aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorMichael Ernst <mernst@cs.washington.edu>2021-12-07 11:16:11 -0800
committerMichael Ernst <mernst@cs.washington.edu>2021-12-07 11:16:11 -0800
commit3f5e4a2819d2f03d634a06861ff5487af320b719 (patch)
treeba9ab7ba2f582bb179624e2bb3f717bea5d9a421 /src/core
parent0b4cc60c2367845ebc362e4b254f9e96a66d53c3 (diff)
parentd3b763f9dab4a46e88ff10bc2132fb6f12fda639 (diff)
downloadlombok-3f5e4a2819d2f03d634a06861ff5487af320b719.tar.gz
lombok-3f5e4a2819d2f03d634a06861ff5487af320b719.tar.bz2
lombok-3f5e4a2819d2f03d634a06861ff5487af320b719.zip
Merge ../lombok-branch-master into nullness-annotations
Diffstat (limited to 'src/core')
-rw-r--r--src/core/lombok/ConfigurationKeys.java12
-rwxr-xr-xsrc/core/lombok/core/AST.java18
-rw-r--r--src/core/lombok/core/Version.java2
-rw-r--r--src/core/lombok/core/configuration/CapitalizationStrategy.java52
-rw-r--r--src/core/lombok/core/configuration/FlagUsageType.java4
-rw-r--r--src/core/lombok/core/handlers/HandlerUtil.java50
-rw-r--r--src/core/lombok/eclipse/EclipseNode.java9
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java44
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleBuilder.java11
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java9
-rw-r--r--src/core/lombok/eclipse/handlers/HandleFieldDefaults.java2
-rw-r--r--src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java14
-rw-r--r--src/core/lombok/eclipse/handlers/HandleLog.java5
-rw-r--r--src/core/lombok/eclipse/handlers/HandleSuperBuilder.java8
-rw-r--r--src/core/lombok/eclipse/handlers/HandleToString.java4
-rw-r--r--src/core/lombok/eclipse/handlers/HandleVal.java3
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java10
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java10
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java6
-rw-r--r--src/core/lombok/javac/JavacAST.java2
-rw-r--r--src/core/lombok/javac/JavacNode.java8
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java9
-rw-r--r--src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java2
-rw-r--r--src/core/lombok/javac/handlers/HandleFieldDefaults.java2
-rw-r--r--src/core/lombok/javac/handlers/HandleFieldNameConstants.java14
-rw-r--r--src/core/lombok/javac/handlers/HandleLog.java5
-rw-r--r--src/core/lombok/javac/handlers/HandleNonNull.java1
-rw-r--r--src/core/lombok/javac/handlers/HandleSetter.java1
-rw-r--r--src/core/lombok/javac/handlers/HandleSuperBuilder.java8
-rw-r--r--src/core/lombok/javac/handlers/HandleToString.java7
-rw-r--r--src/core/lombok/javac/handlers/HandleVal.java6
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java30
-rw-r--r--src/core/lombok/javac/handlers/JavacSingularsRecipes.java6
33 files changed, 283 insertions, 91 deletions
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java
index b8cd442a..05550a06 100644
--- a/src/core/lombok/ConfigurationKeys.java
+++ b/src/core/lombok/ConfigurationKeys.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2020 The Project Lombok Authors.
+ * Copyright (C) 2013-2021 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
@@ -24,6 +24,7 @@ package lombok;
import java.util.List;
import lombok.core.configuration.CallSuperType;
+import lombok.core.configuration.CapitalizationStrategy;
import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.configuration.ConfigurationKey;
import lombok.core.configuration.FlagUsageType;
@@ -558,6 +559,15 @@ public class ConfigurationKeys {
*/
public static final ConfigurationKey<Boolean> ACCESSORS_FLUENT = new ConfigurationKey<Boolean>("lombok.accessors.fluent", "Generate getters and setters using only the field name (no get/set prefix) (default: false).") {};
+ /**
+ * lombok configuration: {@code lombok.accessors.capitalization} = {@code basic} | {@code beanspec}.
+ *
+ * Which capitalization rule is used to turn field names into getter/setter/with names and vice versa for field names that start with 1 lowercase letter, then 1 uppercase letter.
+ * basic = {@code uShape} becomes {@code getUShape}, beanspec = {@code uShape} becomes {@code getuShape} (default = basic).
+ */
+ public static final ConfigurationKey<CapitalizationStrategy> ACCESSORS_JAVA_BEANS_SPEC_CAPITALIZATION = new ConfigurationKey<CapitalizationStrategy>("lombok.accessors.capitalization", "Which capitalization strategy to use when converting field names to accessor names and vice versa (default: basic).") {};
+
+
// ----- ExtensionMethod -----
/**
diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java
index 9f3a471f..07d035c5 100755
--- a/src/core/lombok/core/AST.java
+++ b/src/core/lombok/core/AST.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2019 The Project Lombok Authors.
+ * Copyright (C) 2009-2021 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
@@ -430,6 +430,9 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
}
}
+ /**
+ * @return The {@code lombok.config} configuration value for the provided {@code key}, or {@code null} if that key is not in the config / there is no config.
+ */
public final <T> T readConfiguration(ConfigurationKey<T> key) {
long start = configTracker == null ? 0L : configTracker.start();
try {
@@ -438,4 +441,17 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
if (configTracker != null) configTracker.end(start);
}
}
+
+ /**
+ * @return The {@code lombok.config} configuration value for the provided {@code key}, or {@code defaultValue} if that key is not in the config / there is no config.
+ */
+ public final <T> T readConfigurationOr(ConfigurationKey<T> key, T defaultValue) {
+ long start = configTracker == null ? 0L : configTracker.start();
+ try {
+ T value = LombokConfiguration.read(key, this);
+ return value != null ? value : defaultValue;
+ } finally {
+ if (configTracker != null) configTracker.end(start);
+ }
+ }
}
diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java
index eb8ed6e7..dafe17ae 100644
--- a/src/core/lombok/core/Version.java
+++ b/src/core/lombok/core/Version.java
@@ -30,7 +30,7 @@ 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.21";
+ private static final String VERSION = "1.18.23";
private static final String RELEASE_NAME = "Edgy Guinea Pig";
// private static final String RELEASE_NAME = "Envious Ferret";
diff --git a/src/core/lombok/core/configuration/CapitalizationStrategy.java b/src/core/lombok/core/configuration/CapitalizationStrategy.java
new file mode 100644
index 00000000..affd3576
--- /dev/null
+++ b/src/core/lombok/core/configuration/CapitalizationStrategy.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 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
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.core.configuration;
+
+/** Used for lombok configuration to determine how to transform field names when turning them into accessor method names and vice versa. */
+public enum CapitalizationStrategy {
+ BASIC {
+ @Override public String capitalize(String in) {
+ if (in.length() == 0) return in;
+ char first = in.charAt(0);
+ if (!Character.isLowerCase(first)) return in;
+ boolean useUpperCase = in.length() > 2 &&
+ (Character.isTitleCase(in.charAt(1)) || Character.isUpperCase(in.charAt(1)));
+ return (useUpperCase ? Character.toUpperCase(first) : Character.toTitleCase(first)) + in.substring(1);
+ }
+ },
+ BEANSPEC {
+ @Override public String capitalize(String in) {
+ if (in.length() == 0) return in;
+ char first = in.charAt(0);
+ if (!Character.isLowerCase(first) || (in.length() > 1 && Character.isUpperCase(in.charAt(1)))) return in;
+ boolean useUpperCase = in.length() > 2 && Character.isTitleCase(in.charAt(1));
+ return (useUpperCase ? Character.toUpperCase(first) : Character.toTitleCase(first)) + in.substring(1);
+ }
+ },
+ ;
+
+ public static CapitalizationStrategy defaultValue() {
+ return BASIC;
+ }
+
+ public abstract String capitalize(String in);
+}
diff --git a/src/core/lombok/core/configuration/FlagUsageType.java b/src/core/lombok/core/configuration/FlagUsageType.java
index 8717c22b..293a2f1d 100644
--- a/src/core/lombok/core/configuration/FlagUsageType.java
+++ b/src/core/lombok/core/configuration/FlagUsageType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Project Lombok Authors.
+ * Copyright (C) 2014-2021 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,7 +21,7 @@
*/
package lombok.core.configuration;
-/** Used for lombok configuration to flag usages of certain lombok feature. */
+/** Used for lombok configuration to flag usages of certain lombok features. */
public enum FlagUsageType {
WARNING, ERROR, ALLOW;
}
diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java
index f57d83c2..f90a7caf 100644
--- a/src/core/lombok/core/handlers/HandlerUtil.java
+++ b/src/core/lombok/core/handlers/HandlerUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2020 The Project Lombok Authors.
+ * Copyright (C) 2013-2021 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
@@ -46,6 +46,7 @@ import lombok.core.AnnotationValues;
import lombok.core.JavaIdentifiers;
import lombok.core.LombokNode;
import lombok.core.configuration.AllowHelper;
+import lombok.core.configuration.CapitalizationStrategy;
import lombok.core.configuration.ConfigurationKey;
import lombok.core.configuration.FlagUsageType;
import lombok.experimental.Accessors;
@@ -431,6 +432,7 @@ public class HandlerUtil {
"com.fasterxml.jackson.annotation.JsonSetter",
"com.fasterxml.jackson.annotation.JsonSubTypes",
"com.fasterxml.jackson.annotation.JsonTypeInfo",
+ "com.fasterxml.jackson.annotation.JsonUnwrapped",
"com.fasterxml.jackson.annotation.JsonView",
"com.fasterxml.jackson.databind.annotation.JsonDeserialize",
"com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper",
@@ -692,11 +694,13 @@ public class HandlerUtil {
if (Boolean.TRUE.equals(ast.readConfiguration(ConfigurationKeys.GETTER_CONSEQUENT_BOOLEAN))) isBoolean = false;
boolean explicitPrefix = accessors != null && accessors.isExplicit("prefix");
boolean explicitFluent = accessors != null && accessors.isExplicit("fluent");
+ boolean explicitJavaBeansSpecCapitalization = accessors != null && accessors.isExplicit("javaBeansSpecCapitalization");
- Accessors ac = (explicitPrefix || explicitFluent) ? accessors.getInstance() : null;
+ Accessors ac = (explicitPrefix || explicitFluent || explicitJavaBeansSpecCapitalization) ? accessors.getInstance() : null;
List<String> prefix = explicitPrefix ? Arrays.asList(ac.prefix()) : ast.readConfiguration(ConfigurationKeys.ACCESSORS_PREFIX);
boolean fluent = explicitFluent ? ac.fluent() : Boolean.TRUE.equals(ast.readConfiguration(ConfigurationKeys.ACCESSORS_FLUENT));
+ CapitalizationStrategy capitalizationStrategy = ast.readConfigurationOr(ConfigurationKeys.ACCESSORS_JAVA_BEANS_SPEC_CAPITALIZATION, CapitalizationStrategy.defaultValue());
fieldName = removePrefix(fieldName, prefix);
if (fieldName == null) return null;
@@ -709,7 +713,7 @@ public class HandlerUtil {
return booleanPrefix + fName.substring(2);
}
- return buildAccessorName(isBoolean ? booleanPrefix : normalPrefix, fName);
+ return buildAccessorName(isBoolean ? booleanPrefix : normalPrefix, fName, capitalizationStrategy);
}
/**
@@ -787,6 +791,7 @@ public class HandlerUtil {
List<String> prefix = explicitPrefix ? Arrays.asList(ac.prefix()) : ast.readConfiguration(ConfigurationKeys.ACCESSORS_PREFIX);
boolean fluent = explicitFluent ? ac.fluent() : Boolean.TRUE.equals(ast.readConfiguration(ConfigurationKeys.ACCESSORS_FLUENT));
+ CapitalizationStrategy capitalizationStrategy = ast.readConfigurationOr(ConfigurationKeys.ACCESSORS_JAVA_BEANS_SPEC_CAPITALIZATION, CapitalizationStrategy.defaultValue());
fieldName = removePrefix(fieldName, prefix);
if (fieldName == null) return Collections.emptyList();
@@ -798,8 +803,8 @@ public class HandlerUtil {
if (adhereToFluent && fluent) {
names.add(baseName);
} else {
- names.add(buildAccessorName(normalPrefix, baseName));
- if (!normalPrefix.equals(booleanPrefix)) names.add(buildAccessorName(booleanPrefix, baseName));
+ names.add(buildAccessorName(normalPrefix, baseName, capitalizationStrategy));
+ if (!normalPrefix.equals(booleanPrefix)) names.add(buildAccessorName(booleanPrefix, baseName, capitalizationStrategy));
}
}
@@ -825,23 +830,36 @@ public class HandlerUtil {
}
/**
+ * @param node Any node (used to fetch config of capitalization strategy).
+ * @param prefix Something like {@code get} or {@code set} or {@code is}.
+ * @param suffix Something like {@code running}.
+ * @return prefix + smartly title-cased suffix. For example, {@code setRunning}.
+ */
+ public static String buildAccessorName(AST<?, ?, ?> ast, String prefix, String suffix) {
+ CapitalizationStrategy capitalizationStrategy = ast.readConfigurationOr(ConfigurationKeys.ACCESSORS_JAVA_BEANS_SPEC_CAPITALIZATION, CapitalizationStrategy.defaultValue());
+ return buildAccessorName(prefix, suffix, capitalizationStrategy);
+ }
+
+ /**
+ * @param node Any node (used to fetch config of capitalization strategy).
* @param prefix Something like {@code get} or {@code set} or {@code is}.
* @param suffix Something like {@code running}.
* @return prefix + smartly title-cased suffix. For example, {@code setRunning}.
*/
- public static String buildAccessorName(String prefix, String suffix) {
+ public static String buildAccessorName(LombokNode<?, ?, ?> node, String prefix, String suffix) {
+ CapitalizationStrategy capitalizationStrategy = node.getAst().readConfigurationOr(ConfigurationKeys.ACCESSORS_JAVA_BEANS_SPEC_CAPITALIZATION, CapitalizationStrategy.defaultValue());
+ return buildAccessorName(prefix, suffix, capitalizationStrategy);
+ }
+
+ /**
+ * @param prefix Something like {@code get} or {@code set} or {@code is}.
+ * @param suffix Something like {@code running}.
+ * @param capitalizationStrategy Which strategy to use to capitalize the name part.
+ */
+ private static String buildAccessorName(String prefix, String suffix, CapitalizationStrategy capitalizationStrategy) {
if (suffix.length() == 0) return prefix;
if (prefix.length() == 0) return suffix;
-
- char first = suffix.charAt(0);
- if (Character.isLowerCase(first)) {
- boolean useUpperCase = suffix.length() > 2 &&
- (Character.isTitleCase(suffix.charAt(1)) || Character.isUpperCase(suffix.charAt(1)));
- suffix = String.format("%s%s",
- useUpperCase ? Character.toUpperCase(first) : Character.toTitleCase(first),
- suffix.subSequence(1, suffix.length()));
- }
- return String.format("%s%s", prefix, suffix);
+ return prefix + capitalizationStrategy.capitalize(suffix);
}
public static String camelCaseToConstant(String fieldName) {
diff --git a/src/core/lombok/eclipse/EclipseNode.java b/src/core/lombok/eclipse/EclipseNode.java
index 4f86f0a5..4950aeef 100644
--- a/src/core/lombok/eclipse/EclipseNode.java
+++ b/src/core/lombok/eclipse/EclipseNode.java
@@ -215,13 +215,16 @@ public class EclipseNode extends lombok.core.LombokNode<EclipseAST, EclipseNode,
@Override public boolean isStatic() {
if (node instanceof TypeDeclaration) {
+ TypeDeclaration t = (TypeDeclaration) node;
+ int f = t.modifiers;
+ if (((ClassFileConstants.AccInterface | ClassFileConstants.AccEnum) & f) != 0) return true;
+
EclipseNode directUp = directUp();
if (directUp == null || directUp.getKind() == Kind.COMPILATION_UNIT) return true;
if (!(directUp.get() instanceof TypeDeclaration)) return false;
TypeDeclaration p = (TypeDeclaration) directUp.get();
- int f = p.modifiers;
- if ((ClassFileConstants.AccInterface & f) != 0) return true;
- if ((ClassFileConstants.AccEnum & f) != 0) return true;
+ f = p.modifiers;
+ if (((ClassFileConstants.AccInterface | ClassFileConstants.AccEnum) & f) != 0) return true;
}
if (node instanceof FieldDeclaration) {
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 5eea980c..f8cde6c8 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -95,6 +95,7 @@ import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
@@ -337,6 +338,8 @@ public class EclipseHandlerUtil {
public static final Class<?> INTERSECTION_BINDING1, INTERSECTION_BINDING2;
public static final Field INTERSECTION_BINDING_TYPES1, INTERSECTION_BINDING_TYPES2;
public static final Field TYPE_DECLARATION_RECORD_COMPONENTS;
+ public static final Class<?> COMPILATION_UNIT;
+ public static final Method COMPILATION_UNIT_ORIGINAL_FROM_CLONE;
static {
STRING_LITERAL__LINE_NUMBER = getField(StringLiteral.class, "lineNumber");
ANNOTATION__MEMBER_VALUE_PAIR_NAME = getField(Annotation.class, "memberValuePairName");
@@ -346,6 +349,8 @@ public class EclipseHandlerUtil {
INTERSECTION_BINDING_TYPES1 = INTERSECTION_BINDING1 == null ? null : getField(INTERSECTION_BINDING1, "intersectingTypes");
INTERSECTION_BINDING_TYPES2 = INTERSECTION_BINDING2 == null ? null : getField(INTERSECTION_BINDING2, "intersectingTypes");
TYPE_DECLARATION_RECORD_COMPONENTS = getField(TypeDeclaration.class, "recordComponents");
+ COMPILATION_UNIT = getClass("org.eclipse.jdt.internal.core.CompilationUnit");
+ COMPILATION_UNIT_ORIGINAL_FROM_CLONE = COMPILATION_UNIT == null ? null : Permit.permissiveGetMethod(COMPILATION_UNIT, "originalFromClone");
}
public static int reflectInt(Field f, Object o) {
@@ -1042,7 +1047,7 @@ public class EclipseHandlerUtil {
res[count] = name;
n = parent;
- while (n != null && n.getKind() == Kind.TYPE && n.get() instanceof TypeDeclaration) {
+ while (count > 0) {
TypeDeclaration td = (TypeDeclaration) n.get();
res[--count] = td.name;
n = n.up();
@@ -2052,11 +2057,7 @@ public class EclipseHandlerUtil {
}
int pS = source.sourceStart, pE = source.sourceEnd;
- long p = (long)pS << 32 | pE;
- long[] poss = new long[annotationTypeFqn.length];
- Arrays.fill(poss, p);
- QualifiedTypeReference qualifiedType = new QualifiedTypeReference(annotationTypeFqn, poss);
- setGeneratedBy(qualifiedType, source);
+ TypeReference qualifiedType = generateQualifiedTypeRef(source, annotationTypeFqn);
Annotation ann;
if (args != null && args.length == 1 && args[0] instanceof Expression) {
SingleMemberAnnotation sma = new SingleMemberAnnotation(qualifiedType, pS);
@@ -2636,6 +2637,13 @@ public class EclipseHandlerUtil {
}
/**
+ * Returns {@code true} if the provided node is an actual class, an enum or a record and not some other type declaration (so, not an annotation definition or interface).
+ */
+ public static boolean isClassEnumOrRecord(EclipseNode typeNode) {
+ return isTypeAndDoesNotHaveFlags(typeNode, ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation);
+ }
+
+ /**
* Returns {@code true} if the provided node is a record declaration (so, not an annotation definition, interface, enum, or plain class).
*/
public static boolean isRecord(EclipseNode typeNode) {
@@ -2662,6 +2670,21 @@ public class EclipseHandlerUtil {
return (modifiers & flags) == 0;
}
+ /**
+ * Returns {@code true} if the provided node supports static methods and types (top level or static class)
+ */
+ public static boolean isStaticAllowed(EclipseNode typeNode) {
+ boolean staticAllowed = true;
+
+ while (typeNode.getKind() != Kind.COMPILATION_UNIT) {
+ if (!staticAllowed) return false;
+
+ staticAllowed = typeNode.isStatic();
+ typeNode = typeNode.up();
+ }
+ return true;
+ }
+
public static AbstractVariableDeclaration[] getRecordComponents(TypeDeclaration typeDeclaration) {
if (typeDeclaration == null || (typeDeclaration.modifiers & AccRecord) == 0) return null;
try {
@@ -2713,7 +2736,14 @@ public class EclipseHandlerUtil {
public static void setDocComment(CompilationUnitDeclaration cud, TypeDeclaration type, ASTNode node, String doc) {
if (doc == null) return;
- Map<String, String> docs = EcjAugments.CompilationUnit_javadoc.setIfAbsent(cud.compilationResult.compilationUnit, new HashMap<String, String>());
+ ICompilationUnit compilationUnit = cud.compilationResult.compilationUnit;
+ if (compilationUnit.getClass().equals(COMPILATION_UNIT)) {
+ try {
+ compilationUnit = (ICompilationUnit) Permit.invoke(COMPILATION_UNIT_ORIGINAL_FROM_CLONE, compilationUnit);
+ } catch (Throwable t) { }
+ }
+
+ Map<String, String> docs = EcjAugments.CompilationUnit_javadoc.setIfAbsent(compilationUnit, new HashMap<String, String>());
if (node instanceof AbstractMethodDeclaration) {
AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) node;
String signature = getSignature(type, methodDeclaration);
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index dab774f3..2bfe1e8b 100755
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -293,6 +293,11 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
List<EclipseNode> nonFinalNonDefaultedFields = null;
+ if (!isStaticAllowed(upToTypeNode(parent))) {
+ annotationNode.addError("@Builder is not supported on non-static nested classes.");
+ return;
+ }
+
if (parent.get() instanceof TypeDeclaration) {
if (!isClass(parent) && !isRecord(parent)) {
annotationNode.addError(BUILDER_NODE_NOT_SUPPORTED_ERR);
@@ -660,7 +665,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
for (BuilderFieldData bfd : job.builderFields) {
String setterName = new String(bfd.name);
String setterPrefix = !prefix.isEmpty() ? prefix : job.oldFluent ? "" : "set";
- if (!setterPrefix.isEmpty()) setterName = HandlerUtil.buildAccessorName(setterPrefix, setterName);
+ if (!setterPrefix.isEmpty()) setterName = HandlerUtil.buildAccessorName(job.sourceNode, setterPrefix, setterName);
MessageSend ms = new MessageSend();
Expression[] tgt = new Expression[bfd.singularData == null ? 1 : 2];
@@ -1028,9 +1033,9 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
String setterPrefix = prefix.isEmpty() ? "set" : prefix;
String setterName;
if (job.oldFluent) {
- setterName = prefix.isEmpty() ? new String(bfd.name) : HandlerUtil.buildAccessorName(setterPrefix, new String(bfd.name));
+ setterName = prefix.isEmpty() ? new String(bfd.name) : HandlerUtil.buildAccessorName(job.sourceNode, setterPrefix, new String(bfd.name));
} else {
- setterName = HandlerUtil.buildAccessorName(setterPrefix, new String(bfd.name));
+ setterName = HandlerUtil.buildAccessorName(job.sourceNode, setterPrefix, new String(bfd.name));
}
for (int i = 0; i < len; i++) {
diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
index 12a3c315..a5e8dfb5 100755
--- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
@@ -538,14 +538,15 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
if (addWildcards) genericsCount.add(arraySizeOf(((TypeDeclaration) type.get()).typeParameters));
boolean staticContext = (((TypeDeclaration) type.get()).modifiers & ClassFileConstants.AccStatic) != 0;
EclipseNode tNode = type.up();
- if (!staticContext && tNode.getKind() == Kind.TYPE && (((TypeDeclaration) tNode.get()).modifiers & ClassFileConstants.AccInterface) != 0) staticContext = true;
while (tNode != null && tNode.getKind() == Kind.TYPE) {
+ TypeDeclaration td = (TypeDeclaration) tNode.get();
+ if (td.name == null || td.name.length == 0) break;
list.add(tNode.getName());
- if (addWildcards) genericsCount.add(staticContext ? 0 : arraySizeOf(((TypeDeclaration) tNode.get()).typeParameters));
- if (!staticContext) staticContext = (((TypeDeclaration) tNode.get()).modifiers & Modifier.STATIC) != 0;
+ if (!staticContext && tNode.getKind() == Kind.TYPE && (td.modifiers & ClassFileConstants.AccInterface) != 0) staticContext = true;
+ if (addWildcards) genericsCount.add(staticContext ? 0 : arraySizeOf(td.typeParameters));
+ if (!staticContext) staticContext = (td.modifiers & Modifier.STATIC) != 0;
tNode = tNode.up();
- if (!staticContext && tNode.getKind() == Kind.TYPE && (((TypeDeclaration) tNode.get()).modifiers & ClassFileConstants.AccInterface) != 0) staticContext = true;
}
Collections.reverse(list);
if (addWildcards) Collections.reverse(genericsCount);
diff --git a/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java b/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java
index 5900e7ed..3297ba06 100644
--- a/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java
+++ b/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java
@@ -160,6 +160,8 @@ public class HandleFieldDefaults extends EclipseASTAdapter {
boolean defaultToFinal = makeFinalIsExplicit ? false : Boolean.TRUE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.FIELD_DEFAULTS_FINAL_EVERYWHERE));
if (!defaultToPrivate && !defaultToFinal && fieldDefaults == null) return;
+ // Do not apply field defaults to records if set using the the config system
+ if (fieldDefaults == null && !isClassOrEnum(typeNode)) return;
AccessLevel fdAccessLevel = (fieldDefaults != null && levelIsExplicit) ? fd.level() : defaultToPrivate ? AccessLevel.PRIVATE : null;
boolean fdToFinal = (fieldDefaults != null && makeFinalIsExplicit) ? fd.makeFinal() : defaultToFinal;
diff --git a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
index cc1a5c3f..071dcdfb 100644
--- a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
+++ b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
@@ -60,14 +60,12 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
private static final IdentifierName FIELDS = IdentifierName.valueOf("Fields");
public void generateFieldNameConstantsForType(EclipseNode typeNode, EclipseNode errorNode, AccessLevel level, boolean asEnum, IdentifierName innerTypeName, boolean onlyExplicit, boolean uppercase) {
- TypeDeclaration typeDecl = null;
- if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get();
-
- int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
- boolean notAClass = (modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0;
-
- if (typeDecl == null || notAClass) {
- errorNode.addError("@FieldNameConstants is only supported on a class or an enum.");
+ if (!isClassEnumOrRecord(typeNode)) {
+ errorNode.addError("@FieldNameConstants is only supported on a class, an enum or a record.");
+ return;
+ }
+ if (!isStaticAllowed(typeNode)) {
+ errorNode.addError("@FieldNameConstants is not supported on non-static nested classes.");
return;
}
diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java
index 1cac2de7..db9104ef 100644
--- a/src/core/lombok/eclipse/handlers/HandleLog.java
+++ b/src/core/lombok/eclipse/handlers/HandleLog.java
@@ -88,6 +88,11 @@ public class HandleLog {
return;
}
+ if (useStatic && !isStaticAllowed(owner)) {
+ annotationNode.addError(framework.getAnnotationAsString() + " is not supported on non-static nested classes.");
+ return;
+ }
+
Object valueGuess = annotation.getValueGuess("topic");
Expression loggerTopic = (Expression) annotation.getActualExpression("topic");
diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
index 4d5d2448..26b62cbf 100644
--- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
@@ -184,6 +184,10 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
annotationNode.addError("@SuperBuilder is only supported on classes.");
return;
}
+ if (!isStaticAllowed(parent)) {
+ annotationNode.addError("@SuperBuilder is not supported on non-static nested classes.");
+ return;
+ }
job.parentType = parent;
TypeDeclaration td = (TypeDeclaration) parent.get();
@@ -794,7 +798,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
}
private MessageSend createSetterCallWithInstanceValue(BuilderFieldData bfd, EclipseNode type, ASTNode source, String setterPrefix) {
- char[] setterName = HandlerUtil.buildAccessorName(setterPrefix, String.valueOf(bfd.name)).toCharArray();
+ char[] setterName = HandlerUtil.buildAccessorName(type, setterPrefix, String.valueOf(bfd.name)).toCharArray();
MessageSend ms = new MessageSend();
Expression[] tgt = new Expression[bfd.singularData == null ? 1 : 2];
@@ -1000,7 +1004,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
if (existing == null) existing = EMPTY_METHODS;
int len = existing.length;
- String setterName = HandlerUtil.buildAccessorName(setterPrefix, new String(paramName));
+ String setterName = HandlerUtil.buildAccessorName(job.sourceNode, setterPrefix, new String(paramName));
for (int i = 0; i < len; i++) {
if (!(existing[i] instanceof MethodDeclaration)) continue;
diff --git a/src/core/lombok/eclipse/handlers/HandleToString.java b/src/core/lombok/eclipse/handlers/HandleToString.java
index 171402b3..05b0e069 100644
--- a/src/core/lombok/eclipse/handlers/HandleToString.java
+++ b/src/core/lombok/eclipse/handlers/HandleToString.java
@@ -315,7 +315,9 @@ public class HandleToString extends EclipseAnnotationHandler<ToString> {
String typeName = getSingleTypeName(type);
EclipseNode upType = type.up();
while (upType.getKind() == Kind.TYPE) {
- typeName = getSingleTypeName(upType) + "." + typeName;
+ String upTypeName = getSingleTypeName(upType);
+ if (upTypeName.isEmpty()) break;
+ typeName = upTypeName + "." + typeName;
upType = upType.up();
}
return typeName;
diff --git a/src/core/lombok/eclipse/handlers/HandleVal.java b/src/core/lombok/eclipse/handlers/HandleVal.java
index ac53e27e..1bea5525 100644
--- a/src/core/lombok/eclipse/handlers/HandleVal.java
+++ b/src/core/lombok/eclipse/handlers/HandleVal.java
@@ -23,6 +23,7 @@ package lombok.eclipse.handlers;
import static lombok.core.handlers.HandlerUtil.handleFlagUsage;
import static lombok.eclipse.handlers.EclipseHandlerUtil.typeMatches;
+
import lombok.ConfigurationKeys;
import lombok.val;
import lombok.var;
@@ -42,7 +43,7 @@ import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
/*
- * This class just handles 3 basic error cases. The real meat of eclipse 'val' support is in {@code PatchVal} and {@code PatchValEclipse}.
+ * This class just handles 3 basic error cases. The real meat of eclipse 'val' support is in {@code PatchVal} and {@code PatchValEclipse}
*/
@Provides(EclipseASTVisitor.class)
@DeferUntilPostDiet
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
index 7dcf18c9..9b464a25 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
@@ -126,7 +126,7 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
thisDotField.receiver = new ThisReference(0, 0);
Assignment a = new Assignment(thisDotField, new NullLiteral(0, 0), 0);
- md.selector = HandlerUtil.buildAccessorName("clear", new String(data.getPluralName())).toCharArray();
+ md.selector = HandlerUtil.buildAccessorName(builderType, "clear", new String(data.getPluralName())).toCharArray();
md.statements = returnStatement != null ? new Statement[] {a, returnStatement} : new Statement[] {a};
md.returnType = returnType;
md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
@@ -173,8 +173,8 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
md.arguments[i].annotations = typeUseAnns;
}
md.returnType = returnType;
- char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray();
- md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray();
+ char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(builderType, new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray();
+ md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName(builderType, "add", new String(data.getSingularName())).toCharArray();
Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up()));
md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
@@ -213,8 +213,8 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
md.arguments = new Argument[] {param};
md.returnType = returnType;
- char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray();
- md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray();
+ char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(builderType, new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray();
+ md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName(builderType, "addAll", new String(data.getPluralName())).toCharArray();
Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up()));
md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
index 882b7adc..6f5e9add 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
@@ -112,7 +112,7 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
thisDotField.receiver = new ThisReference(0, 0);
FieldReference thisDotField2 = new FieldReference(data.getPluralName(), 0L);
thisDotField2.receiver = new ThisReference(0, 0);
- md.selector = HandlerUtil.buildAccessorName("clear", new String(data.getPluralName())).toCharArray();
+ md.selector = HandlerUtil.buildAccessorName(builderType, "clear", new String(data.getPluralName())).toCharArray();
MessageSend clearMsg = new MessageSend();
clearMsg.receiver = thisDotField2;
clearMsg.selector = "clear".toCharArray();
@@ -151,8 +151,8 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
param.annotations = typeUseAnns;
md.arguments = new Argument[] {param};
md.returnType = returnType;
- char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray();
- md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray();
+ char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(builderType, new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray();
+ md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName(builderType, "add", new String(data.getSingularName())).toCharArray();
Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up()));
md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
@@ -189,8 +189,8 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
md.arguments = new Argument[] {param};
md.returnType = returnType;
- char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray();
- md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray();
+ char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(builderType, new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray();
+ md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName(builderType, "addAll", new String(data.getPluralName())).toCharArray();
Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up()));
md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
index a766612f..c28ba59d 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
@@ -177,7 +177,7 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
thisDotField2.receiver = new ThisReference(0, 0);
FieldReference thisDotField3 = new FieldReference(valueFieldName, 0L);
thisDotField3.receiver = new ThisReference(0, 0);
- md.selector = HandlerUtil.buildAccessorName("clear", new String(data.getPluralName())).toCharArray();
+ md.selector = HandlerUtil.buildAccessorName(builderType, "clear", new String(data.getPluralName())).toCharArray();
MessageSend clearMsg1 = new MessageSend();
clearMsg1.receiver = thisDotField2;
clearMsg1.selector = "clear".toCharArray();
@@ -249,7 +249,7 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
String name = new String(data.getSingularName());
String setterPrefix = data.getSetterPrefix().length > 0 ? new String(data.getSetterPrefix()) : fluent ? "" : "put";
- String setterName = HandlerUtil.buildAccessorName(setterPrefix, name);
+ String setterName = HandlerUtil.buildAccessorName(builderType, setterPrefix, name);
md.selector = setterName.toCharArray();
Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
@@ -325,7 +325,7 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
String name = new String(data.getPluralName());
String setterPrefix = data.getSetterPrefix().length > 0 ? new String(data.getSetterPrefix()) : fluent ? "" : "put";
- String setterName = HandlerUtil.buildAccessorName(setterPrefix, name);
+ String setterName = HandlerUtil.buildAccessorName(builderType, setterPrefix, name);
md.selector = setterName.toCharArray();
Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java
index f58de60f..0919c7d4 100644
--- a/src/core/lombok/javac/JavacAST.java
+++ b/src/core/lombok/javac/JavacAST.java
@@ -228,7 +228,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
int underscoreIdx = nm.indexOf('_');
if (underscoreIdx > -1) return Integer.parseInt(nm.substring(underscoreIdx + 1));
// assume java9+
- return Integer.parseInt(nm);
+ return Integer.parseInt(nm.substring(3));
} catch (Exception ignore) {}
return 6;
}
diff --git a/src/core/lombok/javac/JavacNode.java b/src/core/lombok/javac/JavacNode.java
index 035f7c53..fca0d0d1 100644
--- a/src/core/lombok/javac/JavacNode.java
+++ b/src/core/lombok/javac/JavacNode.java
@@ -286,13 +286,15 @@ public class JavacNode extends lombok.core.LombokNode<JavacAST, JavacNode, JCTre
@Override public boolean isStatic() {
if (node instanceof JCClassDecl) {
+ JCClassDecl t = (JCClassDecl) node;
+ long f = t.mods.flags;
+ if (((Flags.INTERFACE | Flags.ENUM) & f) != 0) return true;
JavacNode directUp = directUp();
if (directUp == null || directUp.getKind() == Kind.COMPILATION_UNIT) return true;
if (!(directUp.get() instanceof JCClassDecl)) return false;
JCClassDecl p = (JCClassDecl) directUp.get();
- long f = p.mods.flags;
- if ((Flags.INTERFACE & f) != 0) return true;
- if ((Flags.ENUM & f) != 0) return true;
+ f = p.mods.flags;
+ if (((Flags.INTERFACE | Flags.ENUM) & f) != 0) return true;
}
if (node instanceof JCVariableDecl) {
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index c23dc14c..d8fdfb1b 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -234,6 +234,11 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
ArrayList<JavacNode> nonFinalNonDefaultedFields = null;
+ if (!isStaticAllowed(upToTypeNode(parent))) {
+ annotationNode.addError("@Builder is not supported on non-static nested classes.");
+ return;
+ }
+
if (parent.get() instanceof JCClassDecl) {
if (!isClass(parent) && !isRecord(parent)) {
annotationNode.addError(BUILDER_NODE_NOT_SUPPORTED_ERR);
@@ -631,7 +636,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
for (BuilderFieldData bfd : job.builderFields) {
String setterPrefix = !prefix.isEmpty() ? prefix : job.oldFluent ? "" : "set";
String prefixedSetterName = bfd.name.toString();
- if (!setterPrefix.isEmpty()) prefixedSetterName = HandlerUtil.buildAccessorName(setterPrefix, prefixedSetterName);
+ if (!setterPrefix.isEmpty()) prefixedSetterName = HandlerUtil.buildAccessorName(job.sourceNode, setterPrefix, prefixedSetterName);
Name setterName = job.toName(prefixedSetterName);
JCExpression[] tgt = new JCExpression[bfd.singularData == null ? 1 : 2];
@@ -896,7 +901,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
private void makePrefixedSetterMethodForBuilder(BuilderJob job, BuilderFieldData bfd, boolean deprecate, String prefix) {
JavacNode fieldNode = bfd.createdFields.get(0);
String setterPrefix = !prefix.isEmpty() ? prefix : job.oldFluent ? "" : "set";
- String setterName = HandlerUtil.buildAccessorName(setterPrefix, bfd.name.toString());
+ String setterName = HandlerUtil.buildAccessorName(job.sourceNode, setterPrefix, bfd.name.toString());
Name setterName_ = job.builderType.toName(setterName);
for (JavacNode child : job.builderType.down()) {
diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
index ffe882d8..dace3521 100644
--- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
@@ -385,7 +385,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
boolean staticContext = (((JCClassDecl) type.get()).getModifiers().flags & Flags.STATIC) != 0;
JavacNode tNode = type.up();
- while (tNode != null && tNode.getKind() == Kind.TYPE) {
+ while (tNode != null && tNode.getKind() == Kind.TYPE && !tNode.getName().isEmpty()) {
list.add(tNode.getName());
if (addWildcards) genericsCount.add(staticContext ? 0 : ((JCClassDecl) tNode.get()).typarams.size());
if (!staticContext) staticContext = (((JCClassDecl) tNode.get()).getModifiers().flags & Flags.STATIC) != 0;
diff --git a/src/core/lombok/javac/handlers/HandleFieldDefaults.java b/src/core/lombok/javac/handlers/HandleFieldDefaults.java
index ebab67e3..9a6632dd 100644
--- a/src/core/lombok/javac/handlers/HandleFieldDefaults.java
+++ b/src/core/lombok/javac/handlers/HandleFieldDefaults.java
@@ -140,6 +140,8 @@ public class HandleFieldDefaults extends JavacASTAdapter {
boolean defaultToFinal = makeFinalIsExplicit ? false : Boolean.TRUE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.FIELD_DEFAULTS_FINAL_EVERYWHERE));
if (!defaultToPrivate && !defaultToFinal && fieldDefaults == null) return;
+ // Do not apply field defaults to records if set using the the config system
+ if (fieldDefaults == null && !isClassOrEnum(typeNode)) return;
AccessLevel fdAccessLevel = (fieldDefaults != null && levelIsExplicit) ? fd.level() : defaultToPrivate ? AccessLevel.PRIVATE : null;
boolean fdToFinal = (fieldDefaults != null && makeFinalIsExplicit) ? fd.makeFinal() : defaultToFinal;
diff --git a/src/core/lombok/javac/handlers/HandleFieldNameConstants.java b/src/core/lombok/javac/handlers/HandleFieldNameConstants.java
index f3c879d5..1fc6beb1 100644
--- a/src/core/lombok/javac/handlers/HandleFieldNameConstants.java
+++ b/src/core/lombok/javac/handlers/HandleFieldNameConstants.java
@@ -57,14 +57,12 @@ public class HandleFieldNameConstants extends JavacAnnotationHandler<FieldNameCo
private static final IdentifierName FIELDS = IdentifierName.valueOf("Fields");
public void generateFieldNameConstantsForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean asEnum, IdentifierName innerTypeName, boolean onlyExplicit, boolean uppercase) {
- JCClassDecl typeDecl = null;
- if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get();
-
- long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags;
- boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION)) != 0;
-
- if (typeDecl == null || notAClass) {
- errorNode.addError("@FieldNameConstants is only supported on a class or an enum.");
+ if (!isClassEnumOrRecord(typeNode)) {
+ errorNode.addError("@FieldNameConstants is only supported on a class, an enum or a record.");
+ return;
+ }
+ if (!isStaticAllowed(typeNode)) {
+ errorNode.addError("@FieldNameConstants is not supported on non-static nested classes.");
return;
}
diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java
index 40f7ff08..957f5581 100644
--- a/src/core/lombok/javac/handlers/HandleLog.java
+++ b/src/core/lombok/javac/handlers/HandleLog.java
@@ -80,6 +80,11 @@ public class HandleLog {
return;
}
+ if (useStatic && !isStaticAllowed(typeNode)) {
+ annotationNode.addError(framework.getAnnotationAsString() + " is not supported on non-static nested classes.");
+ return;
+ }
+
Object valueGuess = annotation.getValueGuess("topic");
JCExpression loggerTopic = (JCExpression) annotation.getActualExpression("topic");
diff --git a/src/core/lombok/javac/handlers/HandleNonNull.java b/src/core/lombok/javac/handlers/HandleNonNull.java
index fe66432a..271bedbb 100644
--- a/src/core/lombok/javac/handlers/HandleNonNull.java
+++ b/src/core/lombok/javac/handlers/HandleNonNull.java
@@ -99,7 +99,6 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> {
return recursiveSetGeneratedBy(constr, source);
} else {
existingCtr.mods = mods;
- existingCtr.params = params.toList();
existingCtr.body = body;
existingCtr = recursiveSetGeneratedBy(existingCtr, source);
addSuppressWarningsAll(existingCtr.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(existingCtr)), typeNode.getContext());
diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java
index a0634494..e5b2c062 100644
--- a/src/core/lombok/javac/handlers/HandleSetter.java
+++ b/src/core/lombok/javac/handlers/HandleSetter.java
@@ -43,7 +43,6 @@ import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCAssign;
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.JCReturn;
diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
index 87b18576..b5bc73fb 100644
--- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
@@ -163,6 +163,10 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
annotationNode.addError("@SuperBuilder is only supported on classes.");
return;
}
+ if (!isStaticAllowed(parent)) {
+ annotationNode.addError("@SuperBuilder is not supported on non-static nested classes.");
+ return;
+ }
job.parentType = parent;
JCClassDecl td = (JCClassDecl) parent.get();
@@ -773,7 +777,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
arg = maker.Conditional(eqNull, emptyCollection, tgt[1]);
}
- String setterName = HandlerUtil.buildAccessorName(setterPrefix, bfd.name.toString());
+ String setterName = HandlerUtil.buildAccessorName(job.sourceNode, setterPrefix, bfd.name.toString());
JCMethodInvocation apply = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(job.toName(BUILDER_VARIABLE_NAME)), job.toName(setterName)), List.of(arg));
JCExpressionStatement exec = maker.Exec(apply);
return exec;
@@ -945,7 +949,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
}
private void generateSimpleSetterMethodForBuilder(SuperBuilderJob job, boolean deprecate, JavacNode fieldNode, Name paramName, Name nameOfSetFlag, JCExpression returnType, JCStatement returnStatement, List<JCAnnotation> annosOnParam, JavacNode originalFieldNode, String setterPrefix) {
- String setterName = HandlerUtil.buildAccessorName(setterPrefix, paramName.toString());
+ String setterName = HandlerUtil.buildAccessorName(job.sourceNode, setterPrefix, paramName.toString());
Name setterName_ = job.builderType.toName(setterName);
for (JavacNode child : job.builderType.down()) {
diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java
index 3fc6a4e4..249993ee 100644
--- a/src/core/lombok/javac/handlers/HandleToString.java
+++ b/src/core/lombok/javac/handlers/HandleToString.java
@@ -44,7 +44,6 @@ import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
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.JCMethodInvocation;
@@ -252,10 +251,10 @@ public class HandleToString extends JavacAnnotationHandler<ToString> {
}
public static String getTypeName(JavacNode typeNode) {
- String typeName = ((JCClassDecl) typeNode.get()).name.toString();
+ String typeName = typeNode.getName();
JavacNode upType = typeNode.up();
- while (upType.getKind() == Kind.TYPE) {
- typeName = ((JCClassDecl) upType.get()).name.toString() + "." + typeName;
+ while (upType.getKind() == Kind.TYPE && !upType.getName().isEmpty()) {
+ typeName = upType.getName() + "." + typeName;
upType = upType.up();
}
return typeName;
diff --git a/src/core/lombok/javac/handlers/HandleVal.java b/src/core/lombok/javac/handlers/HandleVal.java
index 0ed831ab..d4fb1027 100644
--- a/src/core/lombok/javac/handlers/HandleVal.java
+++ b/src/core/lombok/javac/handlers/HandleVal.java
@@ -115,6 +115,12 @@ public class HandleVal extends JavacASTAdapter {
local.mods.annotations = local.mods.annotations == null ? List.of(valAnnotation) : local.mods.annotations.append(valAnnotation);
}
+ if (localNode.getSourceVersion() >= 10) {
+ local.vartype = null;
+ localNode.getAst().setChanged();
+ return;
+ }
+
if (JavacResolution.platformHasTargetTyping()) {
local.vartype = localNode.getAst().getTreeMaker().Ident(localNode.getAst().toName("___Lombok_VAL_Attrib__"));
} else {
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 78c20d39..a41264e8 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -106,6 +106,7 @@ import lombok.javac.Javac;
import lombok.javac.JavacAugments;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
+import lombok.javac.JavacTreeMaker.TypeTag;
import lombok.permit.Permit;
/**
@@ -1286,6 +1287,7 @@ public class JavacHandlerUtil {
static Type classEnter(JCTree tree, JavacNode parent) {
Enter enter = Enter.instance(parent.getContext());
Env<AttrContext> classEnv = enter.getEnv((TypeSymbol) parent.getElement());
+ if (classEnv == null) return null;
Type type = (Type) Permit.invokeSneaky(classEnter, enter, tree, classEnv);
if (type == null) return null;
type.complete();
@@ -1902,7 +1904,7 @@ public class JavacHandlerUtil {
public static JCExpression namePlusTypeParamsToTypeReference(JavacTreeMaker maker, JavacNode parentType, Name typeName, boolean instance, List<JCTypeParameter> params, List<JCAnnotation> annotations) {
JCExpression r = null;
- if (parentType != null && parentType.getKind() == Kind.TYPE) {
+ if (parentType != null && parentType.getKind() == Kind.TYPE && !parentType.getName().isEmpty()) {
JCClassDecl td = (JCClassDecl) parentType.get();
boolean outerInstance = instance && ((td.mods.flags & Flags.STATIC) == 0);
List<JCTypeParameter> outerParams = instance ? td.typarams : List.<JCTypeParameter>nil();
@@ -1979,6 +1981,13 @@ public class JavacHandlerUtil {
}
/**
+ * Returns {@code true} if the provided node is an actual class, an enum or a record and not some other type declaration (so, not an annotation definition or interface).
+ */
+ public static boolean isClassEnumOrRecord(JavacNode typeNode) {
+ return isClassAndDoesNotHaveFlags(typeNode, Flags.INTERFACE | Flags.ANNOTATION);
+ }
+
+ /**
* Returns {@code true} if the provided node is a record declaration (so, not an annotation definition, interface, enum, or plain class).
*/
public static boolean isRecord(JavacNode typeNode) {
@@ -1994,6 +2003,21 @@ public class JavacHandlerUtil {
return (typeDeclflags & flags) == 0;
}
+ /**
+ * Returns {@code true} if the provided node supports static methods and types (top level or static class)
+ */
+ public static boolean isStaticAllowed(JavacNode typeNode) {
+ boolean staticAllowed = true;
+
+ while (typeNode.getKind() != Kind.COMPILATION_UNIT) {
+ if (!staticAllowed) return false;
+
+ staticAllowed = typeNode.isStatic();
+ typeNode = typeNode.up();
+ }
+ return true;
+ }
+
public static JavacNode upToTypeNode(JavacNode node) {
if (node == null) throw new NullPointerException("node");
while ((node != null) && !(node.get() instanceof JCClassDecl)) node = node.up();
@@ -2028,7 +2052,9 @@ public class JavacHandlerUtil {
private static JCExpression cloneType0(JavacTreeMaker maker, JCTree in) {
if (in == null) return null;
- if (in instanceof JCPrimitiveTypeTree) return (JCExpression) in;
+ if (in instanceof JCPrimitiveTypeTree) {
+ return maker.TypeIdent(TypeTag.typeTag(in));
+ }
if (in instanceof JCIdent) {
return maker.Ident(((JCIdent) in).name);
diff --git a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
index 4ca09b82..77fcd4ea 100644
--- a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
+++ b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
@@ -300,7 +300,7 @@ public class JavacSingularsRecipes {
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
statements.append(clearStatement);
- Name methodName = builderType.toName(HandlerUtil.buildAccessorName("clear", data.getPluralName().toString()));
+ Name methodName = builderType.toName(HandlerUtil.buildAccessorName(source, "clear", data.getPluralName().toString()));
finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, methodName, List.<JCVariableDecl>nil(), List.<JCAnnotation>nil(), access, null);
}
@@ -312,7 +312,7 @@ public class JavacSingularsRecipes {
Name name = data.getSingularName();
String setterPrefix = data.getSetterPrefix();
if (setterPrefix.isEmpty() && !fluent) setterPrefix = getAddMethodName();
- if (!setterPrefix.isEmpty()) name = builderType.toName(HandlerUtil.buildAccessorName(setterPrefix, name.toString()));
+ if (!setterPrefix.isEmpty()) name = builderType.toName(HandlerUtil.buildAccessorName(source, setterPrefix, name.toString()));
statements.prepend(createConstructBuilderVarIfNeeded(maker, data, builderType, source));
List<JCAnnotation> methodAnnotations = copyAnnotations(findCopyableToBuilderSingularSetterAnnotations(data.annotation.up()));
@@ -344,7 +344,7 @@ public class JavacSingularsRecipes {
Name name = data.getPluralName();
String setterPrefix = data.getSetterPrefix();
if (setterPrefix.isEmpty() && !fluent) setterPrefix = getAddMethodName() + "All";
- if (!setterPrefix.isEmpty()) name = builderType.toName(HandlerUtil.buildAccessorName(setterPrefix, name.toString()));
+ if (!setterPrefix.isEmpty()) name = builderType.toName(HandlerUtil.buildAccessorName(source, setterPrefix, name.toString()));
JCExpression paramType = getPluralMethodParamType(builderType);
paramType = addTypeArgs(getTypeArgumentsCount(), true, builderType, paramType, data.getTypeArgs(), source);
long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());