aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
-rwxr-xr-xsrc/delombok/lombok/delombok/Delombok.java4
-rw-r--r--src/delombok/lombok/delombok/PrettyPrinter.java41
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java101
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java16
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchVal.java106
-rwxr-xr-xsrc/eclipseAgent/lombok/launch/PatchFixesHider.java53
-rw-r--r--src/installer/lombok/installer/IdeLocation.java12
-rw-r--r--src/installer/lombok/installer/eclipse/EclipseProductLocation.java4
-rw-r--r--src/installer/lombok/installer/eclipse/StandardProductDescriptor.java8
-rw-r--r--src/utils/lombok/eclipse/Eclipse.java7
-rw-r--r--src/utils/lombok/javac/Java14Flags.java26
-rw-r--r--src/utils/lombok/javac/Javac.java2
-rw-r--r--src/utils/lombok/javac/JavacTreeMaker.java14
-rw-r--r--src/utils/lombok/javac/TreeMirrorMaker.java17
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java3
48 files changed, 570 insertions, 218 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());
diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java
index 8d39f447..e4f17602 100755
--- a/src/delombok/lombok/delombok/Delombok.java
+++ b/src/delombok/lombok/delombok/Delombok.java
@@ -43,9 +43,9 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
@@ -733,7 +733,7 @@ public class Delombok {
List<JCCompilationUnit> roots = new ArrayList<JCCompilationUnit>();
Map<JCCompilationUnit, File> baseMap = new IdentityHashMap<JCCompilationUnit, File>();
- Set<AbstractProcessor> processors = new HashSet<AbstractProcessor>();
+ Set<AbstractProcessor> processors = new LinkedHashSet<AbstractProcessor>();
processors.add(new lombok.javac.apt.LombokProcessor());
processors.addAll(additionalAnnotationProcessors);
diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java
index bcf3f431..605b9391 100644
--- a/src/delombok/lombok/delombok/PrettyPrinter.java
+++ b/src/delombok/lombok/delombok/PrettyPrinter.java
@@ -545,6 +545,12 @@ public class PrettyPrinter extends JCTree.Visitor {
print(tree.implementing, ", ");
}
+ List<JCExpression> permitting = readObject(tree, "permitting", List.<JCExpression>nil());
+ if (permitting.nonEmpty()) {
+ print(" permits ");
+ print(permitting, ", ");
+ }
+
println(" {");
indent++;
printClassMembers(tree.defs, isEnum, isInterface);
@@ -1016,6 +1022,8 @@ public class PrettyPrinter extends JCTree.Visitor {
if ((v & TRANSIENT) != 0) print("transient ");
if ((v & NATIVE) != 0) print("native ");
if ((v & ABSTRACT) != 0) print("abstract ");
+ if ((v & SEALED) != 0) print("sealed ");
+ if ((v & NON_SEALED) != 0) print("non-sealed ");
if ((v & STRICTFP) != 0) print("strictfp ");
if ((v & DEFAULT) != 0 && (v & INTERFACE) == 0) print("default ");
}
@@ -1324,13 +1332,16 @@ public class PrettyPrinter extends JCTree.Visitor {
@Override public void visitCase(JCCase tree) {
// Starting with JDK12, switches allow multiple expressions per case, and can take the form of an expression (preview feature).
- List<JCExpression> pats = readObject(tree, "pats", null); // JDK 12+
+ List<JCTree> pats = readObject(tree, "labels", null); // JDK 17+
+ if (pats == null) {
+ pats = readObject(tree, "pats", null); // JDK 12-17
+ }
if (pats == null) {
- JCExpression pat = readObject(tree, "pat", null); // JDK -11
- pats = pat == null ? List.<JCExpression>nil() : List.of(pat);
+ JCTree pat = readObject(tree, "pat", null); // JDK -11
+ pats = pat == null ? List.<JCTree>nil() : List.of(pat);
}
- if (pats.isEmpty()) {
+ if (pats.isEmpty() || pats.size() == 1 && pats.head.getClass().getName().endsWith("$JCDefaultCaseLabel")) {
aPrint("default");
} else {
aPrint("case ");
@@ -1421,6 +1432,22 @@ public class PrettyPrinter extends JCTree.Visitor {
print((Name) readObject(var, "name", null));
}
+ void printDefaultCase(JCTree tree) {
+ print("default");
+ }
+
+ void printGuardPattern(JCTree tree) {
+ print((JCTree) readObject(tree, "patt", null));
+ print(" && ");
+ print((JCExpression) readObject(tree, "expr", null));
+ }
+
+ void printParenthesizedPattern(JCTree tree) {
+ print("(");
+ print((JCTree) readObject(tree, "pattern", null));
+ print(")");
+ }
+
@Override public void visitTry(JCTry tree) {
aPrint("try ");
List<?> resources = readObject(tree, "resources", List.nil());
@@ -1639,6 +1666,12 @@ public class PrettyPrinter extends JCTree.Visitor {
printYieldExpression(tree);
} else if (className.endsWith("$JCBindingPattern")) { // Introduced as preview in JDK14
printBindingPattern(tree);
+ } else if (className.endsWith("$JCDefaultCaseLabel")) { // Introduced in JDK17
+ printDefaultCase(tree);
+ } else if (className.endsWith("$JCGuardPattern")) { // Introduced in JDK17
+ printGuardPattern(tree);
+ } else if (className.endsWith("$JCParenthesizedPattern")) { // Introduced in JDK17
+ printParenthesizedPattern(tree);
} else {
throw new AssertionError("Unhandled tree type: " + tree.getClass() + ": " + tree);
}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
index 0a11cd7a..06e10960 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
@@ -87,14 +87,14 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
patchHideGeneratedNodes(sm);
patchPostCompileHookEclipse(sm);
patchFixSourceTypeConverter(sm);
- patchDisableLombokForCodeCleanup(sm);
patchListRewriteHandleGeneratedMethods(sm);
patchSyntaxAndOccurrencesHighlighting(sm);
patchSortMembersOperation(sm);
- patchExtractInterface(sm);
+ patchExtractInterfaceAndPullUp(sm);
patchAboutDialog(sm);
patchEclipseDebugPatches(sm);
patchJavadoc(sm);
+ patchASTConverterLiterals(sm);
patchPostCompileHookEcj(sm);
@@ -134,7 +134,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
.transplant().build());
}
- private static void patchExtractInterface(ScriptManager sm) {
+ private static void patchExtractInterfaceAndPullUp(ScriptManager sm) {
/* Fix sourceEnding for generated nodes to avoid null pointer */
sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.compiler.SourceElementNotifier", "notifySourceElementRequestor", "void", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "org.eclipse.jdt.internal.compiler.ast.ImportReference"))
@@ -156,10 +156,31 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
.requestExtra(StackRequest.THIS, StackRequest.PARAM4)
.transplant().build());
- /* get real generated node in stead of a random one generated by the annotation */
+ /* Get real node source instead of the annotation */
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.structure.HierarchyProcessor", "createPlaceholderForSingleVariableDeclaration", "org.eclipse.jdt.core.dom.SingleVariableDeclaration",
+ "org.eclipse.jdt.core.dom.SingleVariableDeclaration",
+ "org.eclipse.jdt.core.ICompilationUnit",
+ "org.eclipse.jdt.core.dom.rewrite.ASTRewrite"
+ ))
+ .target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.structure.HierarchyProcessor", "createPlaceholderForType", "org.eclipse.jdt.core.dom.Type",
+ "org.eclipse.jdt.core.dom.Type",
+ "org.eclipse.jdt.core.ICompilationUnit",
+ "org.eclipse.jdt.core.dom.rewrite.ASTRewrite"
+ ))
+ .methodToWrap(new Hook("org.eclipse.jdt.core.IBuffer", "getText", "java.lang.String", "int", "int"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "getRealNodeSource", "java.lang.String", "java.lang.String", "org.eclipse.jdt.core.dom.ASTNode"))
+ .requestExtra(StackRequest.PARAM1)
+ .transplant()
+ .build());
+
+ /* Get real generated node instead of a random one generated by the annotation */
sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.replaceMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.structure.ExtractInterfaceProcessor", "createMemberDeclarations"))
.target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.structure.ExtractInterfaceProcessor", "createMethodComments"))
+ .target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.structure.PullUpRefactoringProcessor", "createAbstractMethod"))
+ .target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.structure.PullUpRefactoringProcessor", "addMethodStubForAbstractMethod"))
+ .target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.structure.PullUpRefactoringProcessor", "createChangeManager"))
.methodToReplace(new Hook("org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil", "getMethodDeclarationNode", "org.eclipse.jdt.core.dom.MethodDeclaration", "org.eclipse.jdt.core.IMethod", "org.eclipse.jdt.core.dom.CompilationUnit"))
.replacementMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "getRealMethodDeclarationNode", "org.eclipse.jdt.core.dom.MethodDeclaration", "org.eclipse.jdt.core.IMethod", "org.eclipse.jdt.core.dom.CompilationUnit"))
.transplant().build());
@@ -177,6 +198,29 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
.decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode"))
.request(StackRequest.PARAM2)
.transplant().build());
+
+ /* Do not add a modifier to the generating annotation during pull up
+ *
+ * Example: Pull up a protected method (canEqual()/@EqualsAndHashCode)
+ */
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.exitEarly()
+ .target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor$IncomingMemberVisibilityAdjustment", "rewriteVisibility"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "skipRewriteVisibility", "boolean", "org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor$IncomingMemberVisibilityAdjustment"))
+ .request(StackRequest.THIS)
+ .transplant()
+ .build());
+
+ /*
+ * ImportRemover sometimes removes lombok imports if a generated method/type gets changed. Skipping all generated nodes fixes this behavior.
+ *
+ * Example: Create a class (Use.java) that uses a generated method (Test t; t.toString();) and pull up this generated method.
+ */
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.exitEarly()
+ .target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.structure.ImportRemover", "registerRemovedNode", "void", "org.eclipse.jdt.core.dom.ASTNode"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode"))
+ .request(StackRequest.PARAM1)
+ .transplant()
+ .build());
}
private static void patchAboutDialog(ScriptManager sm) {
@@ -200,20 +244,13 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
.target(new MethodTarget("org.eclipse.jdt.internal.ui.search.OccurrencesFinder", "addUsage"))
.target(new MethodTarget("org.eclipse.jdt.internal.ui.search.OccurrencesFinder", "addWrite"))
.target(new MethodTarget("org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightingReconciler$PositionCollector", "visit", "boolean", "org.eclipse.jdt.core.dom.SimpleName"))
+ .target(new MethodTarget("org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightingReconciler$PositionCollector", "visitLiteral", "boolean", "org.eclipse.jdt.core.dom.Expression"))
.decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode"))
.valueMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "returnFalse", "boolean", "java.lang.Object"))
.request(StackRequest.PARAM1)
.build());
}
- private static void patchDisableLombokForCodeCleanup(ScriptManager sm) {
- sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.exitEarly()
- .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTNode", "accept", "void", "org.eclipse.jdt.core.dom.ASTVisitor"))
- .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "isRefactoringVisitorAndGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.core.dom.ASTVisitor"))
- .request(StackRequest.THIS, StackRequest.PARAM1)
- .build());
- }
-
private static void patchListRewriteHandleGeneratedMethods(ScriptManager sm) {
sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.replaceMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer$ListRewriter", "rewriteList"))
@@ -308,6 +345,12 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
"org.eclipse.jdt.core.dom.SimpleName[]"))
.request(StackRequest.RETURN_VALUE).build());
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.exitEarly()
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTNode", "accept", "void", "org.eclipse.jdt.core.dom.ASTVisitor"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "isBlockedVisitorAndGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.core.dom.ASTVisitor"))
+ .request(StackRequest.THIS, StackRequest.PARAM1)
+ .build());
+
patchRefactorScripts(sm);
patchFormatters(sm);
}
@@ -528,6 +571,13 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
"org.eclipse.jdt.core.dom.Name", "java.lang.Object"))
.transplant().build());
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.ASTNode", "boolean", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration"))
+ .methodToWrap(new Hook("org.eclipse.jdt.core.dom.Block", "<init>", "void", "org.eclipse.jdt.core.dom.AST"))
+ .requestExtra(StackRequest.PARAM2)
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlag", "void",
+ "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.internal.compiler.ast.ASTNode"))
+ .transplant().build());
sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convertType", "org.eclipse.jdt.core.dom.Type", "org.eclipse.jdt.internal.compiler.ast.TypeReference"))
@@ -766,6 +816,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
sm.addScript(ScriptBuilder.replaceMethodCall()
.target(new MethodTarget(LOCALDECLARATION_SIG, "resolve", "void", BLOCKSCOPE_SIG))
+ .target(new MethodTarget(LOCALDECLARATION_SIG, "resolve", "void", BLOCKSCOPE_SIG, "boolean"))
.methodToReplace(new Hook(EXPRESSION_SIG, "resolveType", TYPEBINDING_SIG, BLOCKSCOPE_SIG))
.requestExtra(StackRequest.THIS)
.replacementMethod(new Hook("lombok.launch.PatchFixesHider$Val", "skipResolveInitializerIfAlreadyCalled2", TYPEBINDING_SIG, EXPRESSION_SIG, BLOCKSCOPE_SIG, LOCALDECLARATION_SIG))
@@ -895,6 +946,14 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
.requestExtra(StackRequest.PARAM1)
.build());
+ /* This is a copy for the language server implementation that also supports markdown */
+ sm.addScript(ScriptBuilder.wrapMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.ls.core.internal.javadoc.JavadocContentAccess2", "getHTMLContent", "java.lang.String", "org.eclipse.jdt.core.IJavaElement", "boolean"))
+ .methodToWrap(new Hook("org.eclipse.jdt.ls.core.internal.javadoc.JavadocContentAccess2", "getHTMLContentFromSource", "java.lang.String", "org.eclipse.jdt.core.IJavaElement"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "getHTMLContentFromSource", "java.lang.String", "java.lang.String", "org.eclipse.jdt.core.IJavaElement"))
+ .requestExtra(StackRequest.PARAM1)
+ .build());
+
/* This is an older version that uses IMember instead of IJavaElement */
sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2", "getHTMLContent", "java.lang.String", "org.eclipse.jdt.core.IMember", "boolean"))
@@ -919,4 +978,22 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
.build());
}
+ private static void patchASTConverterLiterals(ScriptManager sm) {
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.Expression", "org.eclipse.jdt.internal.compiler.ast.StringLiteral"))
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.Expression", "org.eclipse.jdt.internal.compiler.ast.TextBlock"))
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.CharacterLiteral", "org.eclipse.jdt.internal.compiler.ast.CharLiteral"))
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.NumberLiteral", "org.eclipse.jdt.internal.compiler.ast.DoubleLiteral"))
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.NumberLiteral", "org.eclipse.jdt.internal.compiler.ast.FloatLiteral"))
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.NumberLiteral", "org.eclipse.jdt.internal.compiler.ast.LongLiteral"))
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.NumberLiteral", "org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue"))
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.NumberLiteral", "org.eclipse.jdt.internal.compiler.ast.IntLiteral"))
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.NumberLiteral", "org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue"))
+ .methodToWrap(new Hook("java.lang.String", "<init>", "void", "char[]", "int", "int"))
+ .requestExtra(StackRequest.PARAM1)
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "getRealNodeSource", "java.lang.String", "java.lang.String", "org.eclipse.jdt.internal.compiler.ast.ASTNode"))
+ .transplant()
+ .build());
+ }
+
}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java
index 5b34917e..673c30fd 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Project Lombok Authors.
+ * Copyright (C) 2020-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
@@ -103,8 +103,9 @@ public class PatchJavadoc {
private static class Reflection {
private static final Method javadoc2HTML;
private static final Method oldJavadoc2HTML;
+ private static final Method lsJavadoc2HTML;
static {
- Method a = null, b = null;
+ Method a = null, b = null, c = null;
try {
a = Permit.getMethod(JavadocContentAccess2.class, "javadoc2HTML", IMember.class, IJavaElement.class, String.class);
@@ -112,9 +113,13 @@ public class PatchJavadoc {
try {
b = Permit.getMethod(JavadocContentAccess2.class, "javadoc2HTML", IMember.class, String.class);
} catch (Throwable t) {}
+ try {
+ c = Permit.getMethod(Class.forName("org.eclipse.jdt.ls.core.internal.javadoc.JavadocContentAccess2"), "javadoc2HTML", IMember.class, IJavaElement.class, String.class);
+ } catch (Throwable t) {}
javadoc2HTML = a;
oldJavadoc2HTML = b;
+ lsJavadoc2HTML = c;
}
private static String javadoc2HTML(IMember member, IJavaElement element, String rawJavadoc) {
@@ -125,6 +130,13 @@ public class PatchJavadoc {
return null;
}
}
+ if (lsJavadoc2HTML != null) {
+ try {
+ return (String) lsJavadoc2HTML.invoke(null, member, element, rawJavadoc);
+ } catch (Throwable t) {
+ return null;
+ }
+ }
if (oldJavadoc2HTML != null) {
try {
return (String) oldJavadoc2HTML.invoke(null, member, rawJavadoc);
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
index 774e5b40..e758979d 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
@@ -35,13 +35,11 @@ import org.eclipse.jdt.internal.compiler.ast.FunctionalExpression;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
@@ -59,8 +57,8 @@ import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import java.lang.reflect.Field;
import static lombok.Lombok.sneakyThrow;
-import static lombok.eclipse.Eclipse.poss;
-import static lombok.eclipse.handlers.EclipseHandlerUtil.makeType;
+import static lombok.eclipse.Eclipse.*;
+import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
import static org.eclipse.jdt.core.compiler.CategorizedProblem.CAT_TYPE;
public class PatchVal {
@@ -237,13 +235,19 @@ public class PatchVal {
TypeReference replacement = null;
+ // Java 10+: Lombok uses the native 'var' support and transforms 'val' to 'final var'.
+ if (hasNativeVarSupport(scope) && val) {
+ replacement = new SingleTypeReference("var".toCharArray(), pos(local.type));
+ local.initialization = init;
+ init = null;
+ }
+
if (init != null) {
if (init.getClass().getName().equals("org.eclipse.jdt.internal.compiler.ast.LambdaExpression")) {
return false;
}
TypeBinding resolved = null;
- Constant oldConstant = init.constant;
try {
resolved = decomponent ? getForEachComponentType(init, scope) : resolveForExpression(init, scope);
} catch (NullPointerException e) {
@@ -253,6 +257,46 @@ public class PatchVal {
// just go with 'Object' and let the IDE print the appropriate errors.
resolved = null;
}
+
+ if (resolved == null) {
+ if (init instanceof ConditionalExpression) {
+ ConditionalExpression cexp = (ConditionalExpression) init;
+ Expression ifTrue = cexp.valueIfTrue;
+ Expression ifFalse = cexp.valueIfFalse;
+ TypeBinding ifTrueResolvedType = ifTrue.resolvedType;
+ CompilationResult compilationResult = scope.referenceCompilationUnit().compilationResult;
+ CategorizedProblem[] problems = compilationResult.problems;
+ CategorizedProblem lastProblem = problems[compilationResult.problemCount - 1];
+ if (ifTrueResolvedType != null && ifFalse.resolvedType == null && lastProblem.getCategoryID() == CAT_TYPE) {
+ int problemCount = compilationResult.problemCount;
+ for (int i = 0; i < problemCount; ++i) {
+ if (problems[i] == lastProblem) {
+ problems[i] = null;
+ if (i + 1 < problemCount) {
+ System.arraycopy(problems, i + 1, problems, i, problemCount - i + 1);
+ }
+ break;
+ }
+ }
+ compilationResult.removeProblem(lastProblem);
+ if (!compilationResult.hasErrors()) {
+ clearIgnoreFurtherInvestigationField(scope.referenceContext());
+ setValue(getField(CompilationResult.class, "hasMandatoryErrors"), compilationResult, false);
+ }
+
+ if (ifFalse instanceof FunctionalExpression) {
+ FunctionalExpression functionalExpression = (FunctionalExpression) ifFalse;
+ functionalExpression.setExpectedType(ifTrueResolvedType);
+ }
+ if (ifFalse.resolvedType == null) {
+ resolveForExpression(ifFalse, scope);
+ }
+
+ resolved = ifTrueResolvedType;
+ }
+ }
+ }
+
if (resolved != null) {
try {
replacement = makeType(resolved, local.type, false);
@@ -260,10 +304,6 @@ public class PatchVal {
} catch (Exception e) {
// Some type thing failed.
}
- } else {
- if (init instanceof MessageSend && ((MessageSend) init).actualReceiverType == null) {
- init.constant = oldConstant;
- }
}
}
@@ -281,6 +321,14 @@ public class PatchVal {
return is(local.type, scope, "lombok.val");
}
+ private static boolean hasNativeVarSupport(Scope scope) {
+ long sl = scope.problemReporter().options.sourceLevel >> 16;
+ long cl = scope.problemReporter().options.complianceLevel >> 16;
+ if (sl == 0) sl = cl;
+ if (cl == 0) cl = sl;
+ return Math.min((int)(sl - 44), (int)(cl - 44)) >= 10;
+ }
+
public static boolean handleValForForEach(ForeachStatement forEach, BlockScope scope) {
if (forEach.elementVariable == null) return false;
@@ -288,6 +336,8 @@ public class PatchVal {
boolean var = isVar(forEach.elementVariable, scope);
if (!(val || var)) return false;
+ if (hasNativeVarSupport(scope)) return false;
+
TypeBinding component = getForEachComponentType(forEach.collection, scope);
if (component == null) return false;
TypeReference replacement = makeType(component, forEach.elementVariable.type, false);
@@ -353,43 +403,7 @@ public class PatchVal {
// Known cause of issues; for example: val e = mth("X"), where mth takes 2 arguments.
return null;
} catch (AbortCompilation e) {
- if (collection instanceof ConditionalExpression) {
- ConditionalExpression cexp = (ConditionalExpression) collection;
- Expression ifTrue = cexp.valueIfTrue;
- Expression ifFalse = cexp.valueIfFalse;
- TypeBinding ifTrueResolvedType = ifTrue.resolvedType;
- CategorizedProblem problem = e.problem;
- if (ifTrueResolvedType != null && ifFalse.resolvedType == null && problem.getCategoryID() == CAT_TYPE) {
- CompilationResult compilationResult = e.compilationResult;
- CategorizedProblem[] problems = compilationResult.problems;
- int problemCount = compilationResult.problemCount;
- for (int i = 0; i < problemCount; ++i) {
- if (problems[i] == problem) {
- problems[i] = null;
- if (i + 1 < problemCount) {
- System.arraycopy(problems, i + 1, problems, i, problemCount - i + 1);
- }
- break;
- }
- }
- compilationResult.removeProblem(problem);
- if (!compilationResult.hasErrors()) {
- clearIgnoreFurtherInvestigationField(scope.referenceContext());
- setValue(getField(CompilationResult.class, "hasMandatoryErrors"), compilationResult, false);
- }
-
- if (ifFalse instanceof FunctionalExpression) {
- FunctionalExpression functionalExpression = (FunctionalExpression) ifFalse;
- functionalExpression.setExpectedType(ifTrueResolvedType);
- }
- if (ifFalse.resolvedType == null) {
- ifFalse.resolve(scope);
- }
-
- return ifTrueResolvedType;
- }
- }
- throw e;
+ return null;
}
}
diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
index bee30922..63bb3747 100755
--- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java
+++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
@@ -57,6 +57,7 @@ import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent;
import org.eclipse.jdt.internal.core.dom.rewrite.TokenScanner;
import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
+import org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment;
import static lombok.eclipse.EcjAugments.ASTNode_generatedBy;
@@ -413,25 +414,27 @@ final class PatchFixesHider {
}
return result;
}
-
- public static boolean isRefactoringVisitorAndGenerated(org.eclipse.jdt.core.dom.ASTNode node, org.eclipse.jdt.core.dom.ASTVisitor visitor) {
- if (visitor == null) return false;
-
- String className = visitor.getClass().getName();
- if (!(className.startsWith("org.eclipse.jdt.internal.corext.fix") || className.startsWith("org.eclipse.jdt.internal.ui.fix"))) return false;
-
+
+ public static boolean isGenerated(org.eclipse.jdt.core.IMember member) {
boolean result = false;
try {
- result = ((Boolean)node.getClass().getField("$isGenerated").get(node)).booleanValue();
- if (!result && node.getParent() != null && node.getParent() instanceof org.eclipse.jdt.core.dom.QualifiedName) {
- result = isGenerated(node.getParent());
- }
- } catch (Exception e) {
+ result = member.getNameRange().getLength() <= 0 || member.getNameRange().equals(member.getSourceRange());
+ } catch (JavaModelException e) {
// better to assume it isn't generated
}
return result;
}
+ public static boolean isBlockedVisitorAndGenerated(org.eclipse.jdt.core.dom.ASTNode node, org.eclipse.jdt.core.dom.ASTVisitor visitor) {
+ if (visitor == null) return false;
+
+ String className = visitor.getClass().getName();
+ if (!(className.startsWith("org.eclipse.jdt.internal.corext.fix") || className.startsWith("org.eclipse.jdt.internal.ui.fix") || className.startsWith("org.eclipse.jdt.ls.core.internal.semantictokens.SemanticTokensVisitor"))) return false;
+ if (className.equals("org.eclipse.jdt.internal.corext.fix.VariableDeclarationFixCore$WrittenNamesFinder")) return false;
+
+ return isGenerated(node);
+ }
+
public static boolean isListRewriteOnGeneratedNode(org.eclipse.jdt.core.dom.rewrite.ListRewrite rewrite) {
return isGenerated(rewrite.getParent());
}
@@ -473,8 +476,10 @@ final class PatchFixesHider {
StringBuilder signature = new StringBuilder();
addAnnotations(annotations, signature);
- if ((Boolean)processor.getClass().getDeclaredField("fPublic").get(processor)) signature.append("public ");
- if ((Boolean)processor.getClass().getDeclaredField("fAbstract").get(processor)) signature.append("abstract ");
+ try {
+ if ((Boolean)processor.getClass().getDeclaredField("fPublic").get(processor)) signature.append("public ");
+ if ((Boolean)processor.getClass().getDeclaredField("fAbstract").get(processor)) signature.append("abstract ");
+ } catch (Throwable t) { }
signature
.append(declaration.getReturnType2().toString())
@@ -520,7 +525,7 @@ final class PatchFixesHider {
for (Object value : normalAnn.values()) values.add(value.toString());
}
- signature.append("@").append(annotation.resolveTypeBinding().getQualifiedName());
+ signature.append("@").append(annotation.getTypeName().getFullyQualifiedName());
if (!values.isEmpty()) {
signature.append("(");
boolean first = true;
@@ -696,7 +701,7 @@ final class PatchFixesHider {
public static IMethod[] removeGeneratedMethods(IMethod[] methods) throws Exception {
List<IMethod> result = new ArrayList<IMethod>();
for (IMethod m : methods) {
- if (m.getNameRange().getLength() > 0 && !m.getNameRange().equals(m.getSourceRange())) result.add(m);
+ if (!isGenerated(m)) result.add(m);
}
return result.size() == methods.length ? methods : result.toArray(new IMethod[0]);
}
@@ -799,5 +804,21 @@ final class PatchFixesHider {
return replace;
}
+
+ public static String getRealNodeSource(String original, org.eclipse.jdt.internal.compiler.ast.ASTNode node) {
+ if (!isGenerated(node)) return original;
+
+ return node.toString();
+ }
+
+ public static java.lang.String getRealNodeSource(java.lang.String original, org.eclipse.jdt.core.dom.ASTNode node) throws Exception {
+ if (!isGenerated(node)) return original;
+
+ return node.toString();
+ }
+
+ public static boolean skipRewriteVisibility(IncomingMemberVisibilityAdjustment adjustment) {
+ return isGenerated(adjustment.getMember());
+ }
}
}
diff --git a/src/installer/lombok/installer/IdeLocation.java b/src/installer/lombok/installer/IdeLocation.java
index 6b9a94c6..7cba1e2a 100644
--- a/src/installer/lombok/installer/IdeLocation.java
+++ b/src/installer/lombok/installer/IdeLocation.java
@@ -64,16 +64,4 @@ public abstract class IdeLocation {
return x == null ? p.getPath() : x;
}
}
-
- private static final String LEGAL_PATH_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/";
- private static final String LEGAL_PATH_CHARS_WINDOWS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,/;'[]{}!@#$^&()-_+= :\\";
- public static String escapePath(String path) {
- StringBuilder out = new StringBuilder();
- String legalChars = OsUtils.getOS() == OsUtils.OS.UNIX ? LEGAL_PATH_CHARS : LEGAL_PATH_CHARS_WINDOWS;
- for (char c : path.toCharArray()) {
- if (legalChars.indexOf(c) == -1) out.append('\\');
- out.append(c);
- }
- return out.toString();
- }
}
diff --git a/src/installer/lombok/installer/eclipse/EclipseProductLocation.java b/src/installer/lombok/installer/eclipse/EclipseProductLocation.java
index 73f98a35..4cfd07f5 100644
--- a/src/installer/lombok/installer/eclipse/EclipseProductLocation.java
+++ b/src/installer/lombok/installer/eclipse/EclipseProductLocation.java
@@ -347,8 +347,10 @@ public final class EclipseProductLocation extends IdeLocation {
pathPrefix = pathToLombokJarPrefix;
}
+ // NB: You may be tempted to escape this, but don't; there is no possibility to escape this, but
+ // eclipse/java reads the string following the colon in 'raw' fashion. Spaces, colons - all works fine.
newContents.append(String.format(
- "-javaagent:%s", escapePath(pathPrefix + "lombok.jar"))).append(OS_NEWLINE);
+ "-javaagent:%s", pathPrefix + "lombok.jar")).append(OS_NEWLINE);
FileOutputStream fos = new FileOutputStream(eclipseIniPath);
try {
diff --git a/src/installer/lombok/installer/eclipse/StandardProductDescriptor.java b/src/installer/lombok/installer/eclipse/StandardProductDescriptor.java
index 9bd3ae94..365bf7fb 100644
--- a/src/installer/lombok/installer/eclipse/StandardProductDescriptor.java
+++ b/src/installer/lombok/installer/eclipse/StandardProductDescriptor.java
@@ -35,6 +35,7 @@ import lombok.installer.OsUtils;
public class StandardProductDescriptor implements EclipseProductDescriptor {
private static final String USER_HOME = System.getProperty("user.home", ".");
+ private static final String[] BASE_WINDOWS_ROOTS = {"\\", "\\Program Files", "\\Program Files (x86)", "\\ProgramData\\Chocolatey\\lib"};
private static final String[] WINDOWS_ROOTS = windowsRoots();
private static final String[] MAC_ROOTS = {"/Applications", USER_HOME};
private static final String[] UNIX_ROOTS = {USER_HOME};
@@ -159,8 +160,11 @@ public class StandardProductDescriptor implements EclipseProductDescriptor {
private static String[] windowsRoots() {
String localAppData = windowsLocalAppData();
- if (localAppData == null) return new String[] {"\\", "\\Program Files", "\\Program Files (x86)", USER_HOME};
- return new String[] {"\\", "\\Program Files", "\\Program Files (x86)", USER_HOME, localAppData};
+ String[] out = new String[BASE_WINDOWS_ROOTS.length + (localAppData == null ? 1 : 2)];
+ System.arraycopy(BASE_WINDOWS_ROOTS, 0, out, 0, BASE_WINDOWS_ROOTS.length);
+ out[BASE_WINDOWS_ROOTS.length] = USER_HOME;
+ if (localAppData != null) out[BASE_WINDOWS_ROOTS.length + 1] = localAppData;
+ return out;
}
private static String windowsLocalAppData() {
diff --git a/src/utils/lombok/eclipse/Eclipse.java b/src/utils/lombok/eclipse/Eclipse.java
index 8af481b9..0f42ddc6 100644
--- a/src/utils/lombok/eclipse/Eclipse.java
+++ b/src/utils/lombok/eclipse/Eclipse.java
@@ -224,8 +224,11 @@ public class Eclipse {
int highestVersionSoFar = 0;
for (Field f : ClassFileConstants.class.getDeclaredFields()) {
try {
- if (f.getName().startsWith("JDK1_")) {
- int thisVersion = Integer.parseInt(f.getName().substring("JDK1_".length()));
+ if (f.getName().startsWith("JDK")) {
+ String versionString = f.getName().substring("JDK".length());
+ if (versionString.startsWith("1_")) versionString = versionString.substring("1_".length());
+
+ int thisVersion = Integer.parseInt(versionString);
if (thisVersion > highestVersionSoFar) {
highestVersionSoFar = thisVersion;
latestEcjCompilerVersionConstantCached = (Long) f.get(null);
diff --git a/src/utils/lombok/javac/Java14Flags.java b/src/utils/lombok/javac/Java14Flags.java
deleted file mode 100644
index 0d565dca..00000000
--- a/src/utils/lombok/javac/Java14Flags.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package lombok.javac;
-
-public class Java14Flags {
- private Java14Flags() { }
-
- /**
- * Flag to indicate that a class is a record. The flag is also used to mark fields that are
- * part of the state vector of a record and to mark the canonical constructor
- */
- public static final long RECORD = 1L<<61; // ClassSymbols, MethodSymbols and VarSymbols
-
- /**
- * Flag to mark a record constructor as a compact one
- */
- public static final long COMPACT_RECORD_CONSTRUCTOR = 1L<<51; // MethodSymbols only
-
- /**
- * Flag to mark a record field that was not initialized in the compact constructor
- */
- public static final long UNINITIALIZED_FIELD= 1L<<51; // VarSymbols only
-
- /** Flag is set for compiler-generated record members, it could be appplied to
- * accessors and fields
- */
- public static final int GENERATED_MEMBER = 1<<24; // MethodSymbols and VarSymbols
-}
diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java
index d9fcc4f2..3fa0fbb5 100644
--- a/src/utils/lombok/javac/Javac.java
+++ b/src/utils/lombok/javac/Javac.java
@@ -80,6 +80,8 @@ public class Javac {
public static final long COMPACT_RECORD_CONSTRUCTOR = 1L << 51; // MethodSymbols (the 'implicit' many-args constructor that records have)
public static final long UNINITIALIZED_FIELD = 1L << 51; // VarSymbols (To identify fields that the compact record constructor won't initialize)
public static final long GENERATED_MEMBER = 1L << 24; // MethodSymbols, VarSymbols (marks methods and the constructor generated in records)
+ public static final long SEALED = 1L << 62; // ClassSymbols (Flag to indicate sealed class/interface declaration)
+ public static final long NON_SEALED = 1L << 63; // ClassSymbols (Flag to indicate that the class/interface was declared with the non-sealed modifier)
/**
* Returns the version of this java compiler, i.e. the JDK that it shipped in. For example, for javac v1.7, this returns {@code 7}.
diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java
index 30d71606..d369b4e4 100644
--- a/src/utils/lombok/javac/JavacTreeMaker.java
+++ b/src/utils/lombok/javac/JavacTreeMaker.java
@@ -607,7 +607,19 @@ public class JavacTreeMaker {
public JCCase Case(JCExpression pat, List<JCStatement> stats) {
if (tryResolve(Case11)) return invoke(Case11, pat, stats);
- return invoke(Case12.Case12, Case12.CASE_KIND_STATEMENT, pat == null ? com.sun.tools.javac.util.List.nil() : com.sun.tools.javac.util.List.of(pat), stats, null);
+ List<JCTree> labels;
+ if (pat == null) {
+ labels = tryResolve(DefaultCaseLabel) ? List.of(DefaultCaseLabel()) : List.<JCTree>nil();
+ } else {
+ labels = List.<JCTree>of(pat);
+ }
+ return invoke(Case12.Case12, Case12.CASE_KIND_STATEMENT, labels, stats, null);
+ }
+
+ //javac versions: 17
+ private static final MethodId<JCTree> DefaultCaseLabel = MethodId("DefaultCaseLabel", JCTree.class);
+ public JCTree DefaultCaseLabel() {
+ return invoke(DefaultCaseLabel);
}
//javac versions: 6-8
diff --git a/src/utils/lombok/javac/TreeMirrorMaker.java b/src/utils/lombok/javac/TreeMirrorMaker.java
index a67a4ec1..44e26ab6 100644
--- a/src/utils/lombok/javac/TreeMirrorMaker.java
+++ b/src/utils/lombok/javac/TreeMirrorMaker.java
@@ -32,8 +32,10 @@ import lombok.javac.JavacTreeMaker.TypeTag;
import com.sun.source.tree.LabeledStatementTree;
import com.sun.source.tree.VariableTree;
import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.TreeCopier;
+import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
@@ -109,6 +111,21 @@ public class TreeMirrorMaker extends TreeCopier<Void> {
if (wipeSymAndType) {
copy.sym = null;
copy.type = null;
+ } else {
+ if (original.vartype != null) {
+ copy.vartype.type = original.vartype.type;
+ original.vartype.accept(new TreeScanner() {
+ @Override public void scan(JCTree tree) {
+ super.scan(tree);
+ originalToCopy.get(tree).type = tree.type;
+ }
+
+ @Override public void visitSelect(JCFieldAccess tree) {
+ super.visitSelect(tree);
+ ((JCFieldAccess) originalToCopy.get(tree)).sym = tree.sym;
+ }
+ });
+ }
}
}
diff --git a/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java b/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java
index f29f501b..e625cd8d 100644
--- a/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java
+++ b/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java
@@ -21,6 +21,7 @@
*/
package lombok.javac.java8;
+import java.nio.Buffer;
import java.nio.CharBuffer;
import com.sun.tools.javac.parser.Scanner;
@@ -79,7 +80,7 @@ public class CommentCollectingScannerFactory extends ScannerFactory {
int limit;
if (input instanceof CharBuffer && ((CharBuffer) input).hasArray()) {
CharBuffer cb = (CharBuffer) input;
- cb.compact().flip();
+ ((Buffer)cb.compact()).flip();
array = cb.array();
limit = cb.limit();
} else {