From 0375f1a9e8f606588d4e136fc718a6876ff0ae4f Mon Sep 17 00:00:00 2001
From: Thomas Klambauer
Date: Tue, 17 Jul 2018 13:35:34 +0200
Subject: lombok config broken: version must be string
otherwise gradle compile will fail.
---
website/templates/setup/gradle.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/website/templates/setup/gradle.html b/website/templates/setup/gradle.html
index 7cb4af0d..41d90dcc 100644
--- a/website/templates/setup/gradle.html
+++ b/website/templates/setup/gradle.html
@@ -15,7 +15,7 @@
Note, to tell the gradle-lombok plugin to use the latest version of lombok, you need to explicitly tell it about the latest version number and the SHA-256. For our current latest version, put this in your build.gradle file:
lombok {
- version = ${version}
+ version = '${version}'
sha256 = ""
}
--
cgit
From a195a47337f592eb117f519f7a1a42f0d8f570d1 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Tue, 17 Jul 2018 22:32:24 +0200
Subject: Attempting to fix issues with integration with mapstruct; issue #1359
---
build.xml | 3 ++-
doc/changelog.markdown | 1 +
src/launch/lombok/launch/ShadowClassLoader.java | 9 +++++++--
3 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/build.xml b/build.xml
index 28c7fd75..c1d13bd7 100644
--- a/build.xml
+++ b/build.xml
@@ -261,7 +261,8 @@ the common tasks and can be called on to run the main aspects of all the sub-scr
-
+
+
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index 8166f3d1..a77dbb3d 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -2,6 +2,7 @@ Lombok Changelog
----------------
### v1.18.1 "Edgy Guinea Pig"
+* BUGFIX: mapstruct + lombok in eclipse should hopefully work again. [Issue #1359](https://github.com/rzwitserloot/lombok/issues/1359) and [mapstruct issue #1159](https://github.com/mapstruct/mapstruct/issues/1159)
* BUGFIX: Equals and hashCode again exclude transient fields by default. [Issue #1724](https://github.com/rzwitserloot/lombok/issues/1724)
* FEATURE: You can now make builders for type hierarchies, using the new (experimental) `@SuperBuilder` annotation. Thanks for the contribution, Jan Rieke. [`@SuperBuilder` documentation](https://projectlombok.org/features/experimental/SuperBuilder)
* FEATURE: `@NoArgsConstructor`, including forcing one with `lombok.config: lombok.noArgsConstructor.extraPrivate=true` now take any defaults set with `@Builder.Default` into account. [Issue #1347](https://github.com/rzwitserloot/lombok/issues/1347)
diff --git a/src/launch/lombok/launch/ShadowClassLoader.java b/src/launch/lombok/launch/ShadowClassLoader.java
index 36dd289c..32363469 100644
--- a/src/launch/lombok/launch/ShadowClassLoader.java
+++ b/src/launch/lombok/launch/ShadowClassLoader.java
@@ -526,9 +526,14 @@ class ShadowClassLoader extends ClassLoader {
String fileNameOfClass = name.replace(".", "/") + ".class";
URL res = getResource_(fileNameOfClass, true);
if (res == null) {
- if (!exclusionListMatch(fileNameOfClass)) return super.loadClass(name, resolve);
- throw new ClassNotFoundException(name);
+ if (!exclusionListMatch(fileNameOfClass)) try {
+ return super.loadClass(name, resolve);
+ } catch (ClassNotFoundException cnfe) {
+ res = getResource_("secondaryLoading.SCL." + sclSuffix + "/" + name.replace(".", "/") + ".SCL." + sclSuffix, true);
+ if (res == null) throw cnfe;
+ }
}
+ if (res == null) throw new ClassNotFoundException(name);
byte[] b;
int p = 0;
--
cgit
From ff739d6d5a6a68f8d87480be7b0c0104e08f77e0 Mon Sep 17 00:00:00 2001
From: Roland Praml
Date: Thu, 19 Jul 2018 21:46:39 +0200
Subject: Add Roland Praml to authors list
---
AUTHORS | 1 +
1 file changed, 1 insertion(+)
diff --git a/AUTHORS b/AUTHORS
index 0e542693..5246fde7 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -23,6 +23,7 @@ Rabea Gransberger
Reinier Zwitserloot
Robbert Jan Grootjans
Roel Spilker
+Roland Praml
Sander Koning
Szymon Pacanowski
Taiki Sugawara
--
cgit
From be1cfd2f59933725726ec5810e0c189a4aca6ad7 Mon Sep 17 00:00:00 2001
From: Roland Praml
Date: Sun, 8 Jul 2018 16:52:14 +0200
Subject: Replaced StringBuilder by simple char array in "hotspot" method
---
src/core/lombok/bytecode/ClassFileMetaData.java | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/core/lombok/bytecode/ClassFileMetaData.java b/src/core/lombok/bytecode/ClassFileMetaData.java
index 0dc6a6c8..826eed83 100644
--- a/src/core/lombok/bytecode/ClassFileMetaData.java
+++ b/src/core/lombok/bytecode/ClassFileMetaData.java
@@ -116,23 +116,24 @@ public class ClassFileMetaData {
int end = pos + size;
// the resulting string might be smaller
- StringBuilder result = new StringBuilder(size);
+ char[] result = new char[size];
+ int length = 0;
while (pos < end) {
int first = (byteCode[pos++] & 0xFF);
if (first < 0x80) {
- result.append((char)first);
+ result[length++] = (char)first;
} else if ((first & 0xE0) == 0xC0) {
int x = (first & 0x1F) << 6;
int y = (byteCode[pos++] & 0x3F);
- result.append((char)(x | y));
+ result[length++] = (char)(x | y);
} else {
int x = (first & 0x0F) << 12;
int y = (byteCode[pos++] & 0x3F) << 6;
int z = (byteCode[pos++] & 0x3F);
- result.append((char)(x | y | z));
+ result[length++] = (char)(x | y | z);
}
}
- return result.toString();
+ return new String(result, 0, length);
}
/**
--
cgit
From 111d0a5f16667824d0a73b733624e6deffe19a0e Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Wed, 25 Jul 2018 21:10:20 +0200
Subject: Fixes issue #1789 - picking another workspace duplicates the ‘lombok
is installed’ text in the eclipse about dialog.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/eclipseAgent/lombok/eclipse/agent/PatchFixesShadowLoaded.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchFixesShadowLoaded.java b/src/eclipseAgent/lombok/eclipse/agent/PatchFixesShadowLoaded.java
index 52f63765..c0a2c6fe 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchFixesShadowLoaded.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchFixesShadowLoaded.java
@@ -32,6 +32,7 @@ import lombok.core.Version;
public class PatchFixesShadowLoaded {
public static String addLombokNotesToEclipseAboutDialog(String origReturnValue, String key) {
if ("aboutText".equals(key)) {
+ if (origReturnValue.contains(" is installed. https://projectlombok.org")) return origReturnValue;
return origReturnValue + "\n\nLombok " + Version.getFullVersion() + " is installed. https://projectlombok.org/";
}
return origReturnValue;
--
cgit
From 5ec61bb62d3dd2d9509ade090e750dd43e36c0f3 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Wed, 25 Jul 2018 21:41:17 +0200
Subject: [fixes issue #1759] We removed the ‘flag usage’ check on builder
instead of replacing it with the non-experimental check about 3 years ago
when builder moved out of experimental. The check has now been restored.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/core/lombok/javac/handlers/HandleBuilder.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index bb495fbc..f04ea8b1 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -99,6 +99,8 @@ public class HandleBuilder extends JavacAnnotationHandler {
}
@Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) {
+ handleFlagUsage(annotationNode, ConfigurationKeys.BUILDER_FLAG_USAGE, "@Builder");
+
Builder builderInstance = annotation.getInstance();
// These exist just to support the 'old' lombok.experimental.Builder, which had these properties. lombok.Builder no longer has them.
--
cgit
From 7c3724c9dc03684b9e4ecb9b33296c894138add6 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Wed, 25 Jul 2018 22:04:52 +0200
Subject: [Fixes issue #1783] lombok.var / lombok.experimental.var import would
be removed by eclipse’s organize imports.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
doc/changelog.markdown | 1 +
.../lombok/eclipse/agent/PatchVal.java | 16 ++---
.../lombok/eclipse/agent/PatchValEclipse.java | 84 ++++++++++++++++------
3 files changed, 70 insertions(+), 31 deletions(-)
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index a77dbb3d..e6392c53 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -4,6 +4,7 @@ Lombok Changelog
### v1.18.1 "Edgy Guinea Pig"
* BUGFIX: mapstruct + lombok in eclipse should hopefully work again. [Issue #1359](https://github.com/rzwitserloot/lombok/issues/1359) and [mapstruct issue #1159](https://github.com/mapstruct/mapstruct/issues/1159)
* BUGFIX: Equals and hashCode again exclude transient fields by default. [Issue #1724](https://github.com/rzwitserloot/lombok/issues/1724)
+* BUGFIX: Eclipse 'organize imports' feature (either explicitly, or if automatically triggered on saving via 'save actions') would remove the import for `lombok.var`. [Issue #1783](https://github.com/rzwitserloot/lombok/issues/1783)
* FEATURE: You can now make builders for type hierarchies, using the new (experimental) `@SuperBuilder` annotation. Thanks for the contribution, Jan Rieke. [`@SuperBuilder` documentation](https://projectlombok.org/features/experimental/SuperBuilder)
* FEATURE: `@NoArgsConstructor`, including forcing one with `lombok.config: lombok.noArgsConstructor.extraPrivate=true` now take any defaults set with `@Builder.Default` into account. [Issue #1347](https://github.com/rzwitserloot/lombok/issues/1347)
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
index c2a362bd..fee104d3 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
@@ -210,16 +210,16 @@ public class PatchVal {
if (local == null || !LocalDeclaration.class.equals(local.getClass())) return false;
boolean decomponent = false;
- boolean val = isVal(local, scope);
- boolean var = isVar(local, scope);
- if (!(val || var)) return false;
+ boolean val = isVal(local, scope);
+ boolean var = isVar(local, scope);
+ if (!(val || var)) return false;
StackTraceElement[] st = new Throwable().getStackTrace();
for (int i = 0; i < st.length - 2 && i < 10; i++) {
if (st[i].getClassName().equals("lombok.launch.PatchFixesHider$Val")) {
boolean valInForStatement = val &&
- st[i + 1].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.LocalDeclaration") &&
- st[i + 2].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.ForStatement");
+ st[i + 1].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.LocalDeclaration") &&
+ st[i + 2].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.ForStatement");
if (valInForStatement) return false;
break;
}
@@ -269,7 +269,7 @@ public class PatchVal {
}
}
- if(val) local.modifiers |= ClassFileConstants.AccFinal;
+ if (val) local.modifiers |= ClassFileConstants.AccFinal;
local.annotations = addValAnnotation(local.annotations, local.type, scope);
local.type = replacement != null ? replacement : new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(local.type, 3));
@@ -298,7 +298,7 @@ public class PatchVal {
if (val) forEach.elementVariable.modifiers |= ClassFileConstants.AccFinal;
forEach.elementVariable.annotations = addValAnnotation(forEach.elementVariable.annotations, forEach.elementVariable.type, scope);
forEach.elementVariable.type = replacement != null ? replacement :
- new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(forEach.elementVariable.type, 3));
+ new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(forEach.elementVariable.type, 3));
return false;
}
@@ -326,7 +326,7 @@ public class PatchVal {
resolved = ((ArrayBinding) resolved).elementsType();
return resolved;
} else if (resolved instanceof ReferenceBinding) {
- ReferenceBinding iterableType = ((ReferenceBinding)resolved).findSuperTypeOriginatingFrom(TypeIds.T_JavaLangIterable, false);
+ ReferenceBinding iterableType = ((ReferenceBinding) resolved).findSuperTypeOriginatingFrom(TypeIds.T_JavaLangIterable, false);
TypeBinding[] arguments = null;
if (iterableType != null) switch (iterableType.kind()) {
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java
index d59b6a2e..99447bae 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java
@@ -47,9 +47,9 @@ import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.parser.Parser;
public class PatchValEclipse {
@@ -103,6 +103,10 @@ public class PatchValEclipse {
}
}
+ private static boolean couldBeVal(ImportReference[] imports, TypeReference type) {
+ return PatchVal.couldBe(imports, "lombok.val", type);
+ }
+
private static boolean couldBeVar(ImportReference[] imports, TypeReference type) {
return PatchVal.couldBe(imports, "lombok.experimental.var", type) || PatchVal.couldBe(imports, "lombok.var", type);
}
@@ -118,17 +122,18 @@ public class PatchValEclipse {
}
public static void addFinalAndValAnnotationToModifierList(Object converter, List modifiers, AST ast, LocalDeclaration in) {
- // First check that 'in' has the final flag on, and a @val / @lombok.val annotation.
- if ((in.modifiers & ClassFileConstants.AccFinal) == 0) return;
+ // First check that 'in' has the final flag on, and a @val / @lombok.val / @var / @lombok.var annotation.
if (in.annotations == null) return;
boolean found = false;
- Annotation valAnnotation = null;
-
+ Annotation valAnnotation = null, varAnnotation = null;
for (Annotation ann : in.annotations) {
if (couldBeVal(null, ann.type)) {
found = true;
valAnnotation = ann;
- break;
+ }
+ if (couldBeVar(null, ann.type)) {
+ found = true;
+ varAnnotation = ann;
}
}
@@ -139,10 +144,11 @@ public class PatchValEclipse {
if (modifiers == null) return; // This is null only if the project is 1.4 or less. Lombok doesn't work in that.
boolean finalIsPresent = false;
boolean valIsPresent = false;
+ boolean varIsPresent = false;
for (Object present : modifiers) {
if (present instanceof Modifier) {
- ModifierKeyword keyword = ((Modifier)present).getKeyword();
+ ModifierKeyword keyword = ((Modifier) present).getKeyword();
if (keyword == null) continue;
if (keyword.toFlagValue() == Modifier.FINAL) finalIsPresent = true;
}
@@ -151,20 +157,18 @@ public class PatchValEclipse {
Name typeName = ((org.eclipse.jdt.core.dom.Annotation) present).getTypeName();
if (typeName != null) {
String fullyQualifiedName = typeName.getFullyQualifiedName();
- if ("val".equals(fullyQualifiedName) || "lombok.val".equals(fullyQualifiedName)) {
- valIsPresent = true;
- }
+ if ("val".equals(fullyQualifiedName) || "lombok.val".equals(fullyQualifiedName)) valIsPresent = true;
+ if ("var".equals(fullyQualifiedName) || "lombok.var".equals(fullyQualifiedName) || "lombok.experimental.var".equals(fullyQualifiedName)) varIsPresent = true;
}
}
}
- if (!finalIsPresent) {
- modifiers.add(
- createModifier(ast, ModifierKeyword.FINAL_KEYWORD, valAnnotation.sourceStart, valAnnotation.sourceEnd));
+ if (!finalIsPresent && valAnnotation != null) {
+ modifiers.add(createModifier(ast, ModifierKeyword.FINAL_KEYWORD, valAnnotation.sourceStart, valAnnotation.sourceEnd));
}
- if (!valIsPresent) {
- MarkerAnnotation newAnnotation = createValAnnotation(ast, valAnnotation, valAnnotation.sourceStart, valAnnotation.sourceEnd);
+ if (!valIsPresent && valAnnotation != null) {
+ MarkerAnnotation newAnnotation = createValVarAnnotation(ast, valAnnotation, valAnnotation.sourceStart, valAnnotation.sourceEnd);
try {
Reflection.astConverterRecordNodes.invoke(converter, newAnnotation, valAnnotation);
Reflection.astConverterRecordNodes.invoke(converter, newAnnotation.getTypeName(), valAnnotation.type);
@@ -175,10 +179,19 @@ public class PatchValEclipse {
}
modifiers.add(newAnnotation);
}
- }
-
- private static boolean couldBeVal(ImportReference[] imports, TypeReference type) {
- return PatchVal.couldBe(imports, "lombok.val", type);
+
+ if (!varIsPresent && varAnnotation != null) {
+ MarkerAnnotation newAnnotation = createValVarAnnotation(ast, varAnnotation, varAnnotation.sourceStart, varAnnotation.sourceEnd);
+ try {
+ Reflection.astConverterRecordNodes.invoke(converter, newAnnotation, varAnnotation);
+ Reflection.astConverterRecordNodes.invoke(converter, newAnnotation.getTypeName(), varAnnotation.type);
+ } catch (IllegalAccessException e) {
+ throw Lombok.sneakyThrow(e);
+ } catch (InvocationTargetException e) {
+ throw Lombok.sneakyThrow(e.getCause());
+ }
+ modifiers.add(newAnnotation);
+ }
}
public static Modifier createModifier(AST ast, ModifierKeyword keyword, int start, int end) {
@@ -200,7 +213,7 @@ public class PatchValEclipse {
return modifier;
}
- public static MarkerAnnotation createValAnnotation(AST ast, Annotation original, int start, int end) {
+ public static MarkerAnnotation createValVarAnnotation(AST ast, Annotation original, int start, int end) {
MarkerAnnotation out = null;
try {
out = Reflection.markerAnnotationConstructor.newInstance(ast);
@@ -212,13 +225,23 @@ public class PatchValEclipse {
throw Lombok.sneakyThrow(e);
}
+ char[][] tokens;
+ if (original.type instanceof SingleTypeReference) {
+ tokens = new char[1][];
+ tokens[0] = ((SingleTypeReference) original.type).token;
+ } else if (original.type instanceof QualifiedTypeReference) {
+ tokens = ((QualifiedTypeReference) original.type).tokens;
+ } else {
+ return null;
+ }
+
if (out != null) {
- SimpleName valName = ast.newSimpleName("val");
+ SimpleName valName = ast.newSimpleName(new String(tokens[tokens.length - 1]));
valName.setSourceRange(start, end - start + 1);
- if (original.type instanceof SingleTypeReference) {
+ if (tokens.length == 1) {
out.setTypeName(valName);
setIndex(valName, 1);
- } else {
+ } else if (tokens.length == 2) {
SimpleName lombokName = ast.newSimpleName("lombok");
lombokName.setSourceRange(start, end - start + 1);
setIndex(lombokName, 1);
@@ -227,6 +250,21 @@ public class PatchValEclipse {
setIndex(fullName, 1);
fullName.setSourceRange(start, end - start + 1);
out.setTypeName(fullName);
+ } else {
+ SimpleName lombokName = ast.newSimpleName("lombok");
+ lombokName.setSourceRange(start, end - start + 1);
+ SimpleName experimentalName = ast.newSimpleName("experimental");
+ lombokName.setSourceRange(start, end - start + 1);
+ setIndex(lombokName, 1);
+ setIndex(experimentalName, 2);
+ setIndex(valName, 3);
+ QualifiedName lombokExperimentalName = ast.newQualifiedName(lombokName, experimentalName);
+ lombokExperimentalName.setSourceRange(start, end - start + 1);
+ setIndex(lombokExperimentalName, 1);
+ QualifiedName fullName = ast.newQualifiedName(lombokExperimentalName, valName);
+ setIndex(fullName, 1);
+ fullName.setSourceRange(start, end - start + 1);
+ out.setTypeName(fullName);
}
out.setSourceRange(start, end - start + 1);
}
--
cgit
From 7e94041dbc177476020969b00d3411020418f903 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Wed, 25 Jul 2018 23:19:00 +0200
Subject: Added key ‘dangerousconfig.lombok.disable’.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/core/lombok/ConfigurationKeys.java | 9 ++++++++-
src/core/lombok/core/LombokConfiguration.java | 15 ++++++++++-----
src/core/lombok/core/configuration/ConfigurationApp.java | 7 ++++---
src/core/lombok/core/configuration/ConfigurationKey.java | 12 +++++++++++-
.../core/configuration/ConfigurationResolverFactory.java | 6 +++---
src/core/lombok/eclipse/EclipseAST.java | 12 ++++++++----
src/core/lombok/eclipse/TransformEclipseAST.java | 6 +++++-
src/core/lombok/javac/JavacAST.java | 7 +++++--
src/core/lombok/javac/JavacTransformer.java | 11 +++++++++--
test/core/src/lombok/AbstractRunTests.java | 6 +++---
10 files changed, 66 insertions(+), 25 deletions(-)
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java
index f5134bbd..1a28c0fa 100644
--- a/src/core/lombok/ConfigurationKeys.java
+++ b/src/core/lombok/ConfigurationKeys.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2017 The Project Lombok Authors.
+ * Copyright (C) 2013-2018 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -38,6 +38,13 @@ public class ConfigurationKeys {
// ----- global -----
+ /**
+ * lombok configuration: {@code dangerousconfig.lombok.disable} = {@code true} | {@code false}.
+ *
+ * If {@code true}, lombok is disabled entirely.
+ */
+ public static final ConfigurationKey LOMBOK_DISABLE = new ConfigurationKey("dangerousconfig.lombok.disable", "Disables lombok transformers. It does not flag any lombok mentions (so, @Cleanup silently does nothing), and does not disable patched operations in eclipse either. Don't use this unless you know what you're doing. (default: false).", true) {};
+
/**
* lombok configuration: {@code lombok.addGeneratedAnnotation} = {@code true} | {@code false}.
*
diff --git a/src/core/lombok/core/LombokConfiguration.java b/src/core/lombok/core/LombokConfiguration.java
index eb7b3d75..4a79c797 100644
--- a/src/core/lombok/core/LombokConfiguration.java
+++ b/src/core/lombok/core/LombokConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 The Project Lombok Authors.
+ * Copyright (C) 2013-2018 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,6 +21,7 @@
*/
package lombok.core;
+import java.net.URI;
import java.util.Collections;
import lombok.core.configuration.BubblingConfigurationResolver;
@@ -44,7 +45,7 @@ public class LombokConfiguration {
static {
if (System.getProperty("lombok.disableConfig") != null) {
configurationResolverFactory = new ConfigurationResolverFactory() {
- @Override public ConfigurationResolver createResolver(AST, ?, ?> ast) {
+ @Override public ConfigurationResolver createResolver(URI sourceLocation) {
return NULL_RESOLVER;
}
};
@@ -63,13 +64,17 @@ public class LombokConfiguration {
}
static T read(ConfigurationKey key, AST, ?, ?> ast) {
- return configurationResolverFactory.createResolver(ast).resolve(key);
+ return configurationResolverFactory.createResolver(ast.getAbsoluteFileLocation()).resolve(key);
+ }
+
+ public static T read(ConfigurationKey key, URI sourceLocation) {
+ return configurationResolverFactory.createResolver(sourceLocation).resolve(key);
}
private static ConfigurationResolverFactory createFileSystemBubblingResolverFactory() {
return new ConfigurationResolverFactory() {
- @Override public ConfigurationResolver createResolver(AST, ?, ?> ast) {
- return new BubblingConfigurationResolver(cache.sourcesForJavaFile(ast.getAbsoluteFileLocation(), ConfigurationProblemReporter.CONSOLE));
+ @Override public ConfigurationResolver createResolver(URI sourceLocation) {
+ return new BubblingConfigurationResolver(cache.sourcesForJavaFile(sourceLocation, ConfigurationProblemReporter.CONSOLE));
}
};
}
diff --git a/src/core/lombok/core/configuration/ConfigurationApp.java b/src/core/lombok/core/configuration/ConfigurationApp.java
index efe57e38..9cfec2e7 100644
--- a/src/core/lombok/core/configuration/ConfigurationApp.java
+++ b/src/core/lombok/core/configuration/ConfigurationApp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Project Lombok Authors.
+ * Copyright (C) 2014-2018 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -118,7 +118,7 @@ public class ConfigurationApp extends LombokApp {
boolean verbose = args.verbose;
if (args.generate) {
- return generate(keys, verbose);
+ return generate(keys, verbose, !args.key.isEmpty());
}
return display(keys, verbose, args.paths, !args.key.isEmpty());
@@ -130,8 +130,9 @@ public class ConfigurationApp extends LombokApp {
return this;
}
- public int generate(Collection> keys, boolean verbose) {
+ public int generate(Collection> keys, boolean verbose, boolean explicit) {
for (ConfigurationKey> key : keys) {
+ if (!explicit && key.isHidden()) continue;
String keyName = key.getKeyName();
ConfigurationDataType type = key.getType();
String description = key.getDescription();
diff --git a/src/core/lombok/core/configuration/ConfigurationKey.java b/src/core/lombok/core/configuration/ConfigurationKey.java
index d46a70b0..18075190 100644
--- a/src/core/lombok/core/configuration/ConfigurationKey.java
+++ b/src/core/lombok/core/configuration/ConfigurationKey.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 The Project Lombok Authors.
+ * Copyright (C) 2013-2018 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -43,13 +43,19 @@ public abstract class ConfigurationKey {
private final String keyName;
private final String description;
private final ConfigurationDataType type;
+ private final boolean hidden;
public ConfigurationKey(String keyName, String description) {
+ this(keyName, description, false);
+ }
+
+ public ConfigurationKey(String keyName, String description, boolean hidden) {
this.keyName = checkName(keyName);
@SuppressWarnings("unchecked")
ConfigurationDataType type = ConfigurationDataType.toDataType((Class extends ConfigurationKey>>)getClass());
this.type = type;
this.description = description;
+ this.hidden = hidden;
registerKey(keyName, this);
}
@@ -65,6 +71,10 @@ public abstract class ConfigurationKey {
return type;
}
+ public final boolean isHidden() {
+ return hidden;
+ }
+
@Override public String toString() {
return keyName + " (" + type + "): " + description;
}
diff --git a/src/core/lombok/core/configuration/ConfigurationResolverFactory.java b/src/core/lombok/core/configuration/ConfigurationResolverFactory.java
index 83b58c2f..b640b271 100644
--- a/src/core/lombok/core/configuration/ConfigurationResolverFactory.java
+++ b/src/core/lombok/core/configuration/ConfigurationResolverFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Project Lombok Authors.
+ * Copyright (C) 2014-2018 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,8 +21,8 @@
*/
package lombok.core.configuration;
-import lombok.core.AST;
+import java.net.URI;
public interface ConfigurationResolverFactory {
- ConfigurationResolver createResolver(AST, ?, ?> ast);
+ ConfigurationResolver createResolver(URI sourceLocation);
}
diff --git a/src/core/lombok/eclipse/EclipseAST.java b/src/core/lombok/eclipse/EclipseAST.java
index dc2c9843..7cd2e400 100644
--- a/src/core/lombok/eclipse/EclipseAST.java
+++ b/src/core/lombok/eclipse/EclipseAST.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2013 The Project Lombok Authors.
+ * Copyright (C) 2009-2018 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -73,16 +73,20 @@ public class EclipseAST extends AST {
private static final URI NOT_CALCULATED_MARKER = URI.create("https://projectlombok.org/not/calculated");
private URI memoizedAbsoluteFileLocation = NOT_CALCULATED_MARKER;
+ public static URI getAbsoluteFileLocation(CompilationUnitDeclaration ast) {
+ return getAbsoluteFileLocation0(ast);
+ }
+
public URI getAbsoluteFileLocation() {
if (memoizedAbsoluteFileLocation != NOT_CALCULATED_MARKER) return memoizedAbsoluteFileLocation;
- memoizedAbsoluteFileLocation = getAbsoluteFileLocation0();
+ memoizedAbsoluteFileLocation = getAbsoluteFileLocation0(this.compilationUnitDeclaration);
return memoizedAbsoluteFileLocation;
}
/** This is the call, but we wrapped it to memoize this. */
- private URI getAbsoluteFileLocation0() {
- String fileName = getFileName();
+ private static URI getAbsoluteFileLocation0(CompilationUnitDeclaration ast) {
+ String fileName = toFileName(ast);
if (fileName != null && (fileName.startsWith("file:") || fileName.startsWith("sourcecontrol:"))) {
// Some exotic build systems get real fancy with filenames. Known culprits:
// The 'jazz' source control system _probably_ (not confirmed yet) uses sourcecontrol://jazz: urls.
diff --git a/src/core/lombok/eclipse/TransformEclipseAST.java b/src/core/lombok/eclipse/TransformEclipseAST.java
index 683465c9..541924ad 100644
--- a/src/core/lombok/eclipse/TransformEclipseAST.java
+++ b/src/core/lombok/eclipse/TransformEclipseAST.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 The Project Lombok Authors.
+ * Copyright (C) 2009-2018 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -25,6 +25,8 @@ import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
import java.lang.reflect.Field;
+import lombok.ConfigurationKeys;
+import lombok.core.LombokConfiguration;
import lombok.core.debug.DebugSnapshotStore;
import lombok.core.debug.HistogramTracker;
import lombok.patcher.Symbols;
@@ -143,6 +145,8 @@ public class TransformEclipseAST {
// Do NOT abort if (ast.bits & ASTNode.HasAllMethodBodies) != 0 - that doesn't work.
+ if (Boolean.TRUE.equals(LombokConfiguration.read(ConfigurationKeys.LOMBOK_DISABLE, EclipseAST.getAbsoluteFileLocation(ast)))) return;
+
try {
DebugSnapshotStore.INSTANCE.snapshot(ast, "transform entry");
long histoToken = lombokTracker == null ? 0L : lombokTracker.start();
diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java
index 4ca2c050..091612cc 100644
--- a/src/core/lombok/javac/JavacAST.java
+++ b/src/core/lombok/javac/JavacAST.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2017 The Project Lombok Authors.
+ * Copyright (C) 2009-2018 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -93,8 +93,11 @@ public class JavacAST extends AST {
}
@Override public URI getAbsoluteFileLocation() {
+ return getAbsoluteFileLocation((JCCompilationUnit) top().get());
+ }
+
+ public static URI getAbsoluteFileLocation(JCCompilationUnit cu) {
try {
- JCCompilationUnit cu = (JCCompilationUnit) top().get();
return cu.sourcefile.toUri();
} catch (Exception e) {
return null;
diff --git a/src/core/lombok/javac/JavacTransformer.java b/src/core/lombok/javac/JavacTransformer.java
index 54977a59..2e37b32b 100644
--- a/src/core/lombok/javac/JavacTransformer.java
+++ b/src/core/lombok/javac/JavacTransformer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2017 The Project Lombok Authors.
+ * Copyright (C) 2009-2018 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -35,6 +35,9 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
+import lombok.ConfigurationKeys;
+import lombok.core.LombokConfiguration;
+
public class JavacTransformer {
private final HandlerLibrary handlers;
private final Messager messager;
@@ -65,7 +68,11 @@ public class JavacTransformer {
java.util.List asts = new ArrayList();
- for (JCCompilationUnit unit : compilationUnits) asts.add(new JavacAST(messager, context, unit));
+ for (JCCompilationUnit unit : compilationUnits) {
+ if (!Boolean.TRUE.equals(LombokConfiguration.read(ConfigurationKeys.LOMBOK_DISABLE, JavacAST.getAbsoluteFileLocation(unit)))) {
+ asts.add(new JavacAST(messager, context, unit));
+ }
+ }
for (JavacAST ast : asts) {
ast.traverse(new AnnotationVisitor(priority));
diff --git a/test/core/src/lombok/AbstractRunTests.java b/test/core/src/lombok/AbstractRunTests.java
index 3d672bc4..f93fbe27 100644
--- a/test/core/src/lombok/AbstractRunTests.java
+++ b/test/core/src/lombok/AbstractRunTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2014 The Project Lombok Authors.
+ * Copyright (C) 2009-2018 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,6 +30,7 @@ import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
+import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@@ -40,7 +41,6 @@ import java.util.Map;
import org.junit.Assert;
import lombok.DirectoryRunner.FileTester;
-import lombok.core.AST;
import lombok.core.LombokConfiguration;
import lombok.core.LombokImmutableList;
import lombok.core.configuration.ConfigurationKeysLoader;
@@ -84,7 +84,7 @@ public abstract class AbstractRunTests {
StringWriter writer = new StringWriter();
LombokConfiguration.overrideConfigurationResolverFactory(new ConfigurationResolverFactory() {
- @Override public ConfigurationResolver createResolver(AST, ?, ?> ast) {
+ @Override public ConfigurationResolver createResolver(URI sourceLocation) {
return sourceDirectives_.getConfiguration();
}
});
--
cgit
From dc715da8b79bff32116ac477d0ac04875bd21167 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Thu, 26 Jul 2018 00:00:24 +0200
Subject: pre-release version bump
---
doc/changelog.markdown | 3 ++-
src/core/lombok/core/Version.java | 6 +++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index e6392c53..29bd1cce 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -1,10 +1,11 @@
Lombok Changelog
----------------
-### v1.18.1 "Edgy Guinea Pig"
+### v1.18.2 (July 26th, 2018)
* BUGFIX: mapstruct + lombok in eclipse should hopefully work again. [Issue #1359](https://github.com/rzwitserloot/lombok/issues/1359) and [mapstruct issue #1159](https://github.com/mapstruct/mapstruct/issues/1159)
* BUGFIX: Equals and hashCode again exclude transient fields by default. [Issue #1724](https://github.com/rzwitserloot/lombok/issues/1724)
* BUGFIX: Eclipse 'organize imports' feature (either explicitly, or if automatically triggered on saving via 'save actions') would remove the import for `lombok.var`. [Issue #1783](https://github.com/rzwitserloot/lombok/issues/1783)
+* BUGFIX: Lombok and gradle v4.9 didn't work together; that's been fixed. [Issue #1716](https://github.com/rzwitserloot/lombok/issues/1716) and [gradle-apt-plugin issue #87](https://github.com/tbroyer/gradle-apt-plugin/issues/87)
* FEATURE: You can now make builders for type hierarchies, using the new (experimental) `@SuperBuilder` annotation. Thanks for the contribution, Jan Rieke. [`@SuperBuilder` documentation](https://projectlombok.org/features/experimental/SuperBuilder)
* FEATURE: `@NoArgsConstructor`, including forcing one with `lombok.config: lombok.noArgsConstructor.extraPrivate=true` now take any defaults set with `@Builder.Default` into account. [Issue #1347](https://github.com/rzwitserloot/lombok/issues/1347)
diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java
index 70af48e0..7b19d00e 100644
--- a/src/core/lombok/core/Version.java
+++ b/src/core/lombok/core/Version.java
@@ -30,9 +30,9 @@ public class Version {
// ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries).
// Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example.
// Official builds always end in an even number. (Since 0.10.2).
- private static final String VERSION = "1.18.1";
- private static final String RELEASE_NAME = "Edgy Guinea Pig";
-// private static final String RELEASE_NAME = "Envious Ferret";
+ private static final String VERSION = "1.18.2";
+// private static final String RELEASE_NAME = "Edgy Guinea Pig";
+ private static final String RELEASE_NAME = "Envious Ferret";
// Named version history:
// Angry Butterfly
--
cgit
From 61fbd4a7f82180871e635a0ca80248e0cec02cf3 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Thu, 26 Jul 2018 00:17:09 +0200
Subject: post-release version bump
---
doc/changelog.markdown | 3 +++
src/core/lombok/core/Version.java | 6 +++---
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index 29bd1cce..0a12cb2d 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -1,6 +1,9 @@
Lombok Changelog
----------------
+### v1.18.3 "Edgy Guinea Pig"
+* No changes yet.
+
### v1.18.2 (July 26th, 2018)
* BUGFIX: mapstruct + lombok in eclipse should hopefully work again. [Issue #1359](https://github.com/rzwitserloot/lombok/issues/1359) and [mapstruct issue #1159](https://github.com/mapstruct/mapstruct/issues/1159)
* BUGFIX: Equals and hashCode again exclude transient fields by default. [Issue #1724](https://github.com/rzwitserloot/lombok/issues/1724)
diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java
index 7b19d00e..4b119873 100644
--- a/src/core/lombok/core/Version.java
+++ b/src/core/lombok/core/Version.java
@@ -30,9 +30,9 @@ public class Version {
// ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries).
// Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example.
// Official builds always end in an even number. (Since 0.10.2).
- private static final String VERSION = "1.18.2";
-// private static final String RELEASE_NAME = "Edgy Guinea Pig";
- private static final String RELEASE_NAME = "Envious Ferret";
+ private static final String VERSION = "1.18.3";
+ private static final String RELEASE_NAME = "Edgy Guinea Pig";
+// private static final String RELEASE_NAME = "Envious Ferret";
// Named version history:
// Angry Butterfly
--
cgit
From 3d432c38d0cfeb36b8e7402eca56faaafcf7bac7 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Sun, 29 Jul 2018 16:37:21 +0200
Subject: code impl of FieldNameConstants rewrite + test updates for it
---
src/core/lombok/ConfigurationKeys.java | 11 +-
.../eclipse/handlers/HandleFieldNameConstants.java | 144 +++++++++++++--------
.../lombok/experimental/FieldNameConstants.java | 28 +++-
.../javac/handlers/HandleFieldNameConstants.java | 129 ++++++++++--------
.../after-delombok/FieldNameConstantsBasic.java | 8 +-
.../FieldNameConstantsConfigKeys.java | 7 +-
.../after-delombok/FieldNameConstantsEnum.java | 10 ++
.../after-delombok/FieldNameConstantsWeird.java | 6 -
.../after-ecj/FieldNameConstantsBasic.java | 18 ++-
.../after-ecj/FieldNameConstantsConfigKeys.java | 13 +-
.../resource/after-ecj/FieldNameConstantsEnum.java | 23 ++++
.../after-ecj/FieldNameConstantsWeird.java | 13 --
.../resource/before/FieldNameConstantsBasic.java | 4 +-
.../before/FieldNameConstantsConfigKeys.java | 3 +-
.../resource/before/FieldNameConstantsEnum.java | 13 ++
.../resource/before/FieldNameConstantsWeird.java | 12 --
.../FieldNameConstantsWeird.java.messages | 1 -
.../FieldNameConstantsWeird.java.messages | 1 -
18 files changed, 270 insertions(+), 174 deletions(-)
create mode 100644 test/transform/resource/after-delombok/FieldNameConstantsEnum.java
delete mode 100644 test/transform/resource/after-delombok/FieldNameConstantsWeird.java
create mode 100644 test/transform/resource/after-ecj/FieldNameConstantsEnum.java
delete mode 100644 test/transform/resource/after-ecj/FieldNameConstantsWeird.java
create mode 100644 test/transform/resource/before/FieldNameConstantsEnum.java
delete mode 100644 test/transform/resource/before/FieldNameConstantsWeird.java
delete mode 100644 test/transform/resource/messages-delombok/FieldNameConstantsWeird.java.messages
delete mode 100644 test/transform/resource/messages-ecj/FieldNameConstantsWeird.java.messages
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java
index 1a28c0fa..184ded27 100644
--- a/src/core/lombok/ConfigurationKeys.java
+++ b/src/core/lombok/ConfigurationKeys.java
@@ -529,18 +529,11 @@ public class ConfigurationKeys {
public static final ConfigurationKey FIELD_NAME_CONSTANTS_FLAG_USAGE = new ConfigurationKey("lombok.fieldNameConstants.flagUsage", "Emit a warning or error if @FieldNameConstants is used.") {};
/**
- * lombok configuration: {@code lombok.fieldNameConstants.prefix} = <String: aJavaIdentifierPrefix> (Default: {@code PREFIX_}).
+ * lombok configuration: {@code lombok.fieldNameConstants.innerTypeName} = <String: AValidJavaTypeName> (Default: {@code Fields}).
*
* The names of the constants generated by {@code @FieldNameConstants} will be prefixed with this value.
*/
- public static final ConfigurationKey FIELD_NAME_CONSTANTS_PREFIX = new ConfigurationKey("lombok.fieldNameConstants.prefix", "names of constants generated by @FieldNameConstants will be prefixed with this value. (default: 'PREFIX_').") {};
-
- /**
- * lombok configuration: {@code lombok.fieldNameConstants.suffix} = <String: aJavaIdentifierPrefix> (Default: nothing).
- *
- * The names of the constants generated by {@code @FieldNameConstants} will be suffixed with this value.
- */
- public static final ConfigurationKey FIELD_NAME_CONSTANTS_SUFFIX = new ConfigurationKey("lombok.fieldNameConstants.suffix", "names of constants generated by @FieldNameConstants will be suffixed with this value. (default: nothing).") {};
+ public static final ConfigurationKey FIELD_NAME_CONSTANTS_INNER_TYPE_NAME = new ConfigurationKey("lombok.fieldNameConstants.innerTypeName", "The default name of the inner type generated by @FieldNameConstants. (default: 'Fields').") {};
// ----- Wither -----
diff --git a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
index c3a28f7f..15650490 100644
--- a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
+++ b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
@@ -24,32 +24,37 @@ package lombok.eclipse.handlers;
import static lombok.core.handlers.HandlerUtil.handleExperimentalFlagUsage;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
+import java.util.ArrayList;
+import java.util.List;
import lombok.AccessLevel;
import lombok.ConfigurationKeys;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
-import lombok.core.handlers.HandlerUtil;
import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
import lombok.experimental.FieldNameConstants;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.Clinit;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.mangosdk.spi.ProviderFor;
@ProviderFor(EclipseAnnotationHandler.class)
public class HandleFieldNameConstants extends EclipseAnnotationHandler {
- public void generateFieldNameConstantsForType(EclipseNode typeNode, EclipseNode errorNode, AccessLevel level, String prefix, String suffix) {
+ public void generateFieldNameConstantsForType(EclipseNode typeNode, EclipseNode errorNode, AccessLevel level, boolean asEnum, String innerTypeName, boolean onlyExplicit) {
TypeDeclaration typeDecl = null;
if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get();
@@ -57,22 +62,29 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler qualified = new ArrayList();
+
for (EclipseNode field : typeNode.down()) {
- if (fieldQualifiesForFieldNameConstantsGeneration(field)) generateFieldNameConstantsForField(field, errorNode.get(), level, prefix, suffix);
+ if (fieldQualifiesForFieldNameConstantsGeneration(field, onlyExplicit)) qualified.add(field);
+ }
+
+ if (qualified.isEmpty()) {
+ errorNode.addWarning("No fields qualify for @FieldNameConstants, therefore this annotation does nothing");
+ } else {
+ createInnerTypeFieldNameConstants(typeNode, errorNode.get(), level, qualified, asEnum, innerTypeName);
}
}
- private void generateFieldNameConstantsForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level, String prefix, String suffix) {
- if (hasAnnotation(FieldNameConstants.class, fieldNode)) return;
- createFieldNameConstantsForField(level, prefix, suffix, fieldNode, fieldNode, pos, false);
- }
-
- private boolean fieldQualifiesForFieldNameConstantsGeneration(EclipseNode field) {
+ private boolean fieldQualifiesForFieldNameConstantsGeneration(EclipseNode field, boolean onlyExplicit) {
if (field.getKind() != Kind.FIELD) return false;
+ if (hasAnnotation(FieldNameConstants.Exclude.class, field)) return false;
+ if (hasAnnotation(FieldNameConstants.Include.class, field)) return true;
+ if (onlyExplicit) return false;
+
FieldDeclaration fieldDecl = (FieldDeclaration) field.get();
return filterField(fieldDecl);
}
@@ -81,55 +93,75 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists) {
- for (EclipseNode fieldNode : fieldNodes) createFieldNameConstantsForField(level, prefix, suffix, fieldNode, errorNode, source, whineIfExists);
- }
-
- private void createFieldNameConstantsForField(AccessLevel level, String prefix, String suffix, EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists) {
- if (fieldNode.getKind() != Kind.FIELD) {
- errorNode.addError("@FieldNameConstants is only supported on a class, an enum, or a field");
+ FieldNameConstants annotationInstance = annotation.getInstance();
+ AccessLevel level = annotationInstance.level();
+ boolean asEnum = annotationInstance.asEnum();
+ boolean usingLombokv1_18_2 = annotation.isExplicit("prefix") || annotation.isExplicit("suffix") || node.getKind() == Kind.FIELD;
+
+ if (usingLombokv1_18_2) {
+ annotationNode.addError("@FieldNameConstants has been redesigned in lombok v1.18.4; please upgrade your project dependency on lombok. See https://projectlombok.org/features/experimental/FieldNameConstants for more information.");
return;
}
- FieldDeclaration field = (FieldDeclaration) fieldNode.get();
- String fieldName = new String(field.name);
- String constantName = prefix + HandlerUtil.camelCaseToConstant(fieldName) + suffix;
- if (constantName.equals(fieldName)) {
- fieldNode.addWarning("Not generating constant for this field: The name of the constant would be equal to the name of this field.");
+ if (level == AccessLevel.NONE) {
+ annotationNode.addWarning("AccessLevel.NONE is not compatible with @FieldNameConstants. If you don't want the inner type, simply remove FieldNameConstants.");
return;
}
- int pS = source.sourceStart, pE = source.sourceEnd;
- long p = (long) pS << 32 | pE;
- FieldDeclaration fieldConstant = new FieldDeclaration(constantName.toCharArray(), pS,pE);
- fieldConstant.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
- fieldConstant.modifiers = toEclipseModifier(level) | Modifier.STATIC | Modifier.FINAL;
- fieldConstant.type = new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING, new long[] {p,p,p});
- fieldConstant.initialization = new StringLiteral(field.name, pS, pE, 0);
- injectField(fieldNode.up(), fieldConstant);
+ String innerTypeName = annotationInstance.innerTypeName();
+ if (innerTypeName.isEmpty()) innerTypeName = annotationNode.getAst().readConfiguration(ConfigurationKeys.FIELD_NAME_CONSTANTS_INNER_TYPE_NAME);
+ if (innerTypeName == null || innerTypeName.isEmpty()) innerTypeName = "Fields";
+
+ generateFieldNameConstantsForType(node, annotationNode, level, asEnum, innerTypeName, annotationInstance.onlyExplicitlyIncluded());
+ }
+
+ private void createInnerTypeFieldNameConstants(EclipseNode typeNode, ASTNode source, AccessLevel level, List fields, boolean asEnum, String innerTypeName) {
+ if (fields.isEmpty()) return;
+
+ TypeDeclaration parent = (TypeDeclaration) typeNode.get();
+ TypeDeclaration innerType = new TypeDeclaration(parent.compilationResult);
+ innerType.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
+ innerType.modifiers = toEclipseModifier(level) | (asEnum ? ClassFileConstants.AccEnum : ClassFileConstants.AccStatic | ClassFileConstants.AccFinal);
+ char[] name = innerTypeName.toCharArray();
+ innerType.name = name;
+ innerType.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
+ EclipseNode innerNode = injectType(typeNode, innerType);
+
+ ConstructorDeclaration constructor = new ConstructorDeclaration(parent.compilationResult);
+ constructor.selector = name;
+ constructor.declarationSourceStart = constructor.sourceStart = source.sourceStart;
+ constructor.declarationSourceEnd = constructor.sourceEnd = source.sourceEnd;
+ constructor.modifiers = ClassFileConstants.AccPrivate;
+ ExplicitConstructorCall superCall = new ExplicitConstructorCall(0);
+ superCall.sourceStart = source.sourceStart;
+ superCall.sourceEnd = source.sourceEnd;
+ superCall.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
+ constructor.constructorCall = superCall;
+ if (!asEnum) constructor.statements = new Statement[0];
+
+ injectMethod(innerNode, constructor);
+
+ if (asEnum) injectMethod(innerNode, new Clinit(parent.compilationResult));
+
+ for (EclipseNode fieldNode : fields) {
+ FieldDeclaration field = (FieldDeclaration) fieldNode.get();
+ char[] fName = field.name;
+ int pS = source.sourceStart, pE = source.sourceEnd;
+ long p = (long) pS << 32 | pE;
+ FieldDeclaration fieldConstant = new FieldDeclaration(fName, pS, pE);
+ fieldConstant.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
+ fieldConstant.modifiers = asEnum ? 0 : ClassFileConstants.AccPublic | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal;
+ fieldConstant.type = asEnum ? null : new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING, new long[] {p, p, p});
+ if (asEnum) {
+ AllocationExpression ac = new AllocationExpression();
+ ac.enumConstant = fieldConstant;
+ ac.sourceStart = source.sourceStart;
+ ac.sourceEnd = source.sourceEnd;
+ fieldConstant.initialization = ac;
+ } else {
+ fieldConstant.initialization = new StringLiteral(field.name, pS, pE, 0);
+ }
+ injectField(innerNode, fieldConstant);
+ }
}
}
diff --git a/src/core/lombok/experimental/FieldNameConstants.java b/src/core/lombok/experimental/FieldNameConstants.java
index 31c2970c..d6886890 100644
--- a/src/core/lombok/experimental/FieldNameConstants.java
+++ b/src/core/lombok/experimental/FieldNameConstants.java
@@ -29,12 +29,32 @@ import java.lang.annotation.Target;
import lombok.AccessLevel;
/**
- * Generates String constants containing the field name for each field.
+ * Generates an inner type, containing String constants containing the field name for each field. Alternatively, generates an inner enum with enum values matching each field name.
*/
-@Target({ElementType.TYPE, ElementType.FIELD})
+@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface FieldNameConstants {
lombok.AccessLevel level() default AccessLevel.PUBLIC;
- String prefix() default " CONFIG DEFAULT ";
- String suffix() default " CONFIG DEFAULT ";
+ boolean asEnum() default false;
+ String innerTypeName() default "";
+
+ /**
+ * Only include fields and methods explicitly marked with {@code @FieldNameConstants.Include}.
+ * Normally, all (non-static) fields are included by default.
+ */
+ boolean onlyExplicitlyIncluded() default false;
+
+ /**
+ * If present, do not include this field in the generated fieldnames inner type.
+ */
+ @Target(ElementType.FIELD)
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Exclude {}
+
+ /**
+ * If present, include this field in the generated fieldnames inner type (default).
+ */
+ @Target(ElementType.FIELD)
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Include {}
}
diff --git a/src/core/lombok/javac/handlers/HandleFieldNameConstants.java b/src/core/lombok/javac/handlers/HandleFieldNameConstants.java
index 8ff136fc..5b120948 100644
--- a/src/core/lombok/javac/handlers/HandleFieldNameConstants.java
+++ b/src/core/lombok/javac/handlers/HandleFieldNameConstants.java
@@ -24,13 +24,11 @@ package lombok.javac.handlers;
import static lombok.core.handlers.HandlerUtil.handleExperimentalFlagUsage;
import static lombok.javac.handlers.JavacHandlerUtil.*;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
+import java.util.ArrayList;
import lombok.AccessLevel;
import lombok.ConfigurationKeys;
import lombok.core.AST.Kind;
-import lombok.core.handlers.HandlerUtil;
import lombok.core.AnnotationValues;
import lombok.experimental.FieldNameConstants;
import lombok.javac.JavacAnnotationHandler;
@@ -40,16 +38,23 @@ import lombok.javac.JavacTreeMaker;
import org.mangosdk.spi.ProviderFor;
import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
+import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCModifiers;
+import com.sun.tools.javac.tree.JCTree.JCStatement;
+import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Name;
@ProviderFor(JavacAnnotationHandler.class)
public class HandleFieldNameConstants extends JavacAnnotationHandler {
- public void generateFieldNameConstantsForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, String prefix, String suffix) {
+ public void generateFieldNameConstantsForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean asEnum, String innerTypeName, boolean onlyExplicit) {
JCClassDecl typeDecl = null;
if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get();
@@ -57,22 +62,31 @@ public class HandleFieldNameConstants extends JavacAnnotationHandler qualified = new ArrayList();
+
for (JavacNode field : typeNode.down()) {
- if (fieldQualifiesForFieldNameConstantsGeneration(field)) generateFieldNameConstantsForField(field, errorNode.get(), level, prefix, suffix);
+ if (fieldQualifiesForFieldNameConstantsGeneration(field, onlyExplicit)) qualified.add(field);
+ }
+
+ if (qualified.isEmpty()) {
+ errorNode.addWarning("No fields qualify for @FieldNameConstants, therefore this annotation does nothing");
+ } else {
+ createInnerTypeFieldNameConstants(typeNode, errorNode.get(), level, qualified, asEnum, innerTypeName);
}
}
- private void generateFieldNameConstantsForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level, String prefix, String suffix) {
- if (hasAnnotation(FieldNameConstants.class, fieldNode)) return;
- createFieldNameConstantsForField(level, prefix, suffix, fieldNode, fieldNode, false);
- }
-
- private boolean fieldQualifiesForFieldNameConstantsGeneration(JavacNode field) {
+ private boolean fieldQualifiesForFieldNameConstantsGeneration(JavacNode field, boolean onlyExplicit) {
if (field.getKind() != Kind.FIELD) return false;
+ boolean exclAnn = JavacHandlerUtil.hasAnnotationAndDeleteIfNeccessary(FieldNameConstants.Exclude.class, field);
+ boolean inclAnn = JavacHandlerUtil.hasAnnotationAndDeleteIfNeccessary(FieldNameConstants.Include.class, field);
+ if (exclAnn) return false;
+ if (inclAnn) return true;
+ if (onlyExplicit) return false;
+
JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
if (fieldDecl.name.toString().startsWith("$")) return false;
if ((fieldDecl.mods.flags & Flags.STATIC) != 0) return false;
@@ -82,56 +96,61 @@ public class HandleFieldNameConstants extends JavacAnnotationHandler annotation, JCAnnotation ast, JavacNode annotationNode) {
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.FIELD_NAME_CONSTANTS_FLAG_USAGE, "@FieldNameConstants");
- Collection fields = annotationNode.upFromAnnotationToFields();
deleteAnnotationIfNeccessary(annotationNode, FieldNameConstants.class);
deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
JavacNode node = annotationNode.up();
- FieldNameConstants annotatationInstance = annotation.getInstance();
- AccessLevel level = annotatationInstance.level();
- String prefix = annotatationInstance.prefix();
- String suffix = annotatationInstance.suffix();
- if (prefix.equals(" CONFIG DEFAULT ")) prefix = annotationNode.getAst().readConfiguration(ConfigurationKeys.FIELD_NAME_CONSTANTS_PREFIX);
- if (suffix.equals(" CONFIG DEFAULT ")) suffix = annotationNode.getAst().readConfiguration(ConfigurationKeys.FIELD_NAME_CONSTANTS_SUFFIX);
- if (prefix == null) prefix = "FIELD_";
- if (suffix == null) suffix = "";
- if (node == null) return;
- switch (node.getKind()) {
- case FIELD:
- if (level != AccessLevel.NONE) createFieldNameConstantsForFields(level, prefix, suffix, fields, annotationNode, annotationNode, true);
- break;
- case TYPE:
- if (level == AccessLevel.NONE) {
- annotationNode.addWarning("type-level '@FieldNameConstants' does not work with AccessLevel.NONE.");
- return;
- }
- generateFieldNameConstantsForType(node, annotationNode, level, prefix, suffix);
- break;
- }
- }
-
- private void createFieldNameConstantsForFields(AccessLevel level, String prefix, String suffix, Collection fieldNode