diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/lombok/ConfigurationKeys.java | 3 | ||||
-rw-r--r-- | src/core/lombok/core/configuration/BubblingConfigurationResolver.java | 12 | ||||
-rw-r--r-- | src/core/lombok/core/configuration/NullAnnotationLibrary.java | 3 | ||||
-rw-r--r-- | src/core/lombok/core/handlers/HandlerUtil.java | 4 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/HandleNonNull.java | 54 | ||||
-rw-r--r-- | src/core/lombok/javac/JavacAST.java | 28 | ||||
-rw-r--r-- | src/core/lombok/javac/apt/LombokProcessor.java | 41 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleNonNull.java | 39 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleVal.java | 24 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/JavacHandlerUtil.java | 82 | ||||
-rw-r--r-- | src/delombok/lombok/delombok/PrettyPrinter.java | 13 | ||||
-rwxr-xr-x | src/eclipseAgent/lombok/launch/PatchFixesHider.java | 9 |
12 files changed, 195 insertions, 117 deletions
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index 22d5a4c5..93bcb85f 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2022 The Project Lombok Authors. + * Copyright (C) 2013-2023 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,6 +103,7 @@ public class ConfigurationKeys { * Lombok generally copies relevant nullity annotations from your source code to the right places. However, sometimes lombok generates code where the nullability of some node is not dependent on something in your source code. You can configure lombok to add an appropriate nullity annotation in this case.<ul> * <li>{@code none} (the default) - no annotations are added.</li> * <li>{@code javax} - The annotations {@code javax.annotation.NonNull} and {@code javax.annotation.Nullable} are used.</li> + * <li>{@code jakarta} - The annotations {@code jakarta.annotation.NonNull} and {@code jakarta.annotation.Nullable} are used.</li> * <li>{@code eclipse} - The annotations {@code org.eclipse.jdt.annotation.NonNull} and {@code org.eclipse.jdt.annotation.Nullable} are used.</li> * <li>{@code jetbrains} - The annotations {@code org.jetbrains.annotations.NotNull} and {@code org.jetbrains.annotations.Nullable} are used.</li> * <li>{@code netbeans} - The annotations {@code org.netbeans.api.annotations.common.NonNull} and {@code org.netbeans.api.annotations.common.NullAllowed} are used.</li> diff --git a/src/core/lombok/core/configuration/BubblingConfigurationResolver.java b/src/core/lombok/core/configuration/BubblingConfigurationResolver.java index 45a45fdc..ecd5e397 100644 --- a/src/core/lombok/core/configuration/BubblingConfigurationResolver.java +++ b/src/core/lombok/core/configuration/BubblingConfigurationResolver.java @@ -48,12 +48,12 @@ public class BubblingConfigurationResolver implements ConfigurationResolver { public <T> T resolve(ConfigurationKey<T> key) { boolean isList = key.getType().isList(); List<List<ListModification>> listModificationsList = null; - + boolean stopBubbling = false; ConfigurationFile currentLevel = start; Collection<ConfigurationFile> visited = new HashSet<ConfigurationFile>(); outer: - while (!stopBubbling && currentLevel != null) { + while (currentLevel != null) { Deque<ConfigurationFile> round = new ArrayDeque<ConfigurationFile>(); round.push(currentLevel); @@ -70,18 +70,18 @@ public class BubblingConfigurationResolver implements ConfigurationResolver { stopBubbling = stopBubbling || (stop != null && Boolean.TRUE.equals(stop.getValue())); Result result = source.resolve(key); - if (result == null) { - continue; - } + if (result == null) continue; + if (isList) { if (listModificationsList == null) listModificationsList = new ArrayList<List<ListModification>>(); - listModificationsList.add((List<ListModification>)result.getValue()); + listModificationsList.add((List<ListModification>) result.getValue()); } if (result.isAuthoritative()) { if (isList) break outer; return (T) result.getValue(); } } + if (stopBubbling) break; currentLevel = currentLevel.parent(); } diff --git a/src/core/lombok/core/configuration/NullAnnotationLibrary.java b/src/core/lombok/core/configuration/NullAnnotationLibrary.java index e8a07721..e1d31004 100644 --- a/src/core/lombok/core/configuration/NullAnnotationLibrary.java +++ b/src/core/lombok/core/configuration/NullAnnotationLibrary.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Project Lombok Authors. + * Copyright (C) 2020-2023 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 @@ -63,6 +63,7 @@ public final class NullAnnotationLibrary implements ConfigurationValueType { public static final NullAnnotationLibrary NONE = new NullAnnotationLibrary("none", null, null, false); public static final NullAnnotationLibrary JAVAX = new NullAnnotationLibrary("javax", "javax.annotation.Nonnull", "javax.annotation.Nullable", false); + public static final NullAnnotationLibrary JAKARTA = new NullAnnotationLibrary("jakarta", "jakarta.annotation.Nonnull", "jakarta.annotation.Nullable", false); public static final NullAnnotationLibrary ECLIPSE = new NullAnnotationLibrary("eclipse", "org.eclipse.jdt.annotation.NonNull", "org.eclipse.jdt.annotation.Nullable", true); public static final NullAnnotationLibrary JETBRAINS = new NullAnnotationLibrary("jetbrains", "org.jetbrains.annotations.NotNull", "org.jetbrains.annotations.Nullable", false); public static final NullAnnotationLibrary NETBEANS = new NullAnnotationLibrary("netbeans", "org.netbeans.api.annotations.common.NonNull", "org.netbeans.api.annotations.common.NullAllowed", false); diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index 5e68f619..07704aa8 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -103,6 +103,7 @@ public class HandlerUtil { "io.micrometer.core.lang.NonNull", "io.reactivex.annotations.NonNull", "io.reactivex.rxjava3.annotations.NonNull", + "jakarta.annotation.Nonnull", "javax.annotation.Nonnull", // "javax.validation.constraints.NotNull", // The field might contain a null value until it is persisted. "libcore.util.NonNull", @@ -160,9 +161,10 @@ public class HandlerUtil { "io.reactivex.annotations.Nullable", "io.reactivex.rxjava3.annotations.NonNull", "io.reactivex.rxjava3.annotations.Nullable", + "jakarta.annotation.Nonnull", + "jakarta.annotation.Nullable", "javax.annotation.CheckForNull", "javax.annotation.Nonnull", - "javax.annotation.Nonnull", "javax.annotation.Nullable", // "javax.validation.constraints.NotNull", // - this should definitely not be included; validation is not about language-level nullity, therefore should not be in this core list. "libcore.util.NonNull", diff --git a/src/core/lombok/eclipse/handlers/HandleNonNull.java b/src/core/lombok/eclipse/handlers/HandleNonNull.java index 365eef33..0138c7fb 100644 --- a/src/core/lombok/eclipse/handlers/HandleNonNull.java +++ b/src/core/lombok/eclipse/handlers/HandleNonNull.java @@ -65,7 +65,6 @@ import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.core.HandlerPriority; import lombok.eclipse.EcjAugments; -import lombok.eclipse.EclipseAST; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; import lombok.spi.Provides; @@ -221,9 +220,16 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> { // As we need both for @NonNull we reset the handled flag during diet parse. if (!annotationNode.isCompleteParse()) { - if (annotationNode.up().getKind() == Kind.FIELD) { + final EclipseNode node; + if (annotationNode.up().getKind() == Kind.TYPE_USE) { + node = annotationNode.directUp().directUp(); + } else { + node = annotationNode.up(); + } + + if (node.getKind() == Kind.FIELD) { //Check if this is a record and we need to generate the compact form constructor. - EclipseNode typeNode = annotationNode.up().up(); + EclipseNode typeNode = node.up(); if (typeNode.getKind() == Kind.TYPE) { if (isRecord(typeNode)) { addCompactConstructorIfNeeded(typeNode, annotationNode); @@ -251,16 +257,23 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> { private void handle0(Annotation ast, EclipseNode annotationNode, boolean force) { handleFlagUsage(annotationNode, ConfigurationKeys.NON_NULL_FLAG_USAGE, "@NonNull"); - if (annotationNode.up().getKind() == Kind.FIELD) { + final EclipseNode node; + if (annotationNode.up().getKind() == Kind.TYPE_USE) { + node = annotationNode.directUp().directUp(); + } else { + node = annotationNode.up(); + } + + if (node.getKind() == Kind.FIELD) { // This is meaningless unless the field is used to generate a method (@Setter, @RequiredArgsConstructor, etc), // but in that case those handlers will take care of it. However, we DO check if the annotation is applied to // a primitive, because those handlers trigger on any annotation named @NonNull and we only want the warning // behaviour on _OUR_ 'lombok.NonNull'. - EclipseNode fieldNode = annotationNode.up(); + EclipseNode fieldNode = node; EclipseNode typeNode = fieldNode.up(); try { - if (isPrimitive(((AbstractVariableDeclaration) annotationNode.up().get()).type)) { + if (isPrimitive(((AbstractVariableDeclaration) node.get()).type)) { annotationNode.addWarning("@NonNull is meaningless on a primitive."); return; } @@ -279,33 +292,14 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> { return; } + if (node.getKind() != Kind.ARGUMENT) return; + Argument param; - EclipseNode paramNode; AbstractMethodDeclaration declaration; - switch (annotationNode.up().getKind()) { - case ARGUMENT: - paramNode = annotationNode.up(); - break; - case TYPE_USE: - EclipseNode typeNode = annotationNode.directUp(); - boolean ok = false; - ASTNode astNode = typeNode.get(); - if (astNode instanceof TypeReference) { - Annotation[] anns = EclipseAST.getTopLevelTypeReferenceAnnotations((TypeReference) astNode); - if (anns == null) return; - for (Annotation ann : anns) if (ast == ann) ok = true; - } - if (!ok) return; - paramNode = typeNode.directUp(); - break; - default: - return; - } - try { - param = (Argument) paramNode.get(); - declaration = (AbstractMethodDeclaration) paramNode.up().get(); + param = (Argument) node.get(); + declaration = (AbstractMethodDeclaration) node.up().get(); } catch (Exception e) { return; } @@ -318,7 +312,7 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> { } addNullCheckIfNeeded(declaration, param, annotationNode); - paramNode.up().rebuild(); + node.up().rebuild(); } private void addNullCheckIfNeeded(AbstractMethodDeclaration declaration, AbstractVariableDeclaration param, EclipseNode annotationNode) { diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index 0919c7d4..c09120c1 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -36,7 +36,6 @@ import javax.annotation.processing.Messager; import javax.tools.Diagnostic; import javax.tools.JavaFileObject; -import com.sun.tools.javac.util.JCDiagnostic; import lombok.core.AST; import lombok.core.CleanupRegistry; import lombok.core.CleanupTask; @@ -53,6 +52,7 @@ import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCCatch; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCIdent; @@ -63,6 +63,7 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.JCTree.JCWildcard; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.JCDiagnostic; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Name; @@ -415,6 +416,18 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> { JCANNOTATEDTYPE_FIELDS_INITIALIZED = true; } + + private static Field JCENHANCEDFORLOOP_VARORRECORDPATTERN_FIELD = Permit.permissiveGetField(JCEnhancedForLoop.class, "varOrRecordPattern"); + private static JCTree getVarOrRecordPattern(JCEnhancedForLoop loop) { + if (JCENHANCEDFORLOOP_VARORRECORDPATTERN_FIELD == null) { + return loop.var; + } + try { + return (JCTree) JCENHANCEDFORLOOP_VARORRECORDPATTERN_FIELD.get(loop); + } catch (Exception ignore) {} + return null; + } + private JavacNode buildTry(JCTry tryNode) { if (setAndGetAsHandled(tryNode)) return null; List<JavacNode> childNodes = new ArrayList<JavacNode>(); @@ -471,6 +484,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> { if (statement instanceof JCVariableDecl) return buildLocalVar((JCVariableDecl) statement, Kind.LOCAL); if (statement instanceof JCTry) return buildTry((JCTry) statement); if (statement.getClass().getName().equals("com.sun.tools.javac.tree.JCTree$JCLambda")) return buildLambda(statement); + if (statement instanceof JCEnhancedForLoop) return buildEnhancedForLoop((JCEnhancedForLoop) statement); if (setAndGetAsHandled(statement)) return null; return drill(statement); @@ -500,6 +514,18 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> { return getBodyMethods.get(c); } + private JavacNode buildEnhancedForLoop(JCEnhancedForLoop loop) { + if (setAndGetAsHandled(loop)) return null; + + List<JavacNode> childNodes = new ArrayList<JavacNode>(); + // The order of the child elements is important and must be kept + addIfNotNull(childNodes, buildTree(getVarOrRecordPattern(loop), Kind.STATEMENT)); + addIfNotNull(childNodes, buildTree(loop.expr, Kind.STATEMENT)); + addIfNotNull(childNodes, buildStatement(loop.body)); + + return putInMap(new JavacNode(this, loop, childNodes, Kind.STATEMENT)); + } + private JavacNode drill(JCTree statement) { try { List<JavacNode> childNodes = new ArrayList<JavacNode>(); diff --git a/src/core/lombok/javac/apt/LombokProcessor.java b/src/core/lombok/javac/apt/LombokProcessor.java index ed713b1d..0467d758 100644 --- a/src/core/lombok/javac/apt/LombokProcessor.java +++ b/src/core/lombok/javac/apt/LombokProcessor.java @@ -25,7 +25,6 @@ import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.URL; @@ -305,10 +304,7 @@ public class LombokProcessor extends AbstractProcessor { // Step 1: Take all CUs which aren't already in the map. Give them the first priority level. - String randomModuleName = null; - for (Element element : roundEnv.getRootElements()) { - if (randomModuleName == null) randomModuleName = getModuleNameFor(element); JCCompilationUnit unit = toUnit(element); if (unit == null) continue; if (roots.containsKey(unit)) continue; @@ -353,7 +349,7 @@ public class LombokProcessor extends AbstractProcessor { newLevels.retainAll(priorityLevelsRequiringResolutionReset); if (!newLevels.isEmpty()) { // Force a new round to reset resolution. The next round will cause this method (process) to be called again. - forceNewRound(randomModuleName, javacFiler); + forceNewRound(javacFiler); return false; } // None of the new levels need resolution, so just keep going. @@ -361,7 +357,7 @@ public class LombokProcessor extends AbstractProcessor { } private int dummyCount = 0; - private void forceNewRound(String randomModuleName, JavacFiler filer) { + private void forceNewRound(JavacFiler filer) { if (!filer.newFiles()) { try { filer.getGeneratedSourceNames().add("lombok.dummy.ForceNewRound" + (dummyCount++)); @@ -372,38 +368,7 @@ public class LombokProcessor extends AbstractProcessor { } } } - - private String getModuleNameFor(Element element) { - while (element != null) { - if (element.getKind().name().equals("MODULE")) return getModuleName(element); - Element n = element.getEnclosingElement(); - if (n == element) return null; - element = n; - } - return null; - } - - private static Class<?> qualifiedNamableClass = null; - private static Method qualifiedNamableQualifiedNameMethod = null; - // QualifiedNameable isn't in java 6, so to remain compatible with java6, use reflection. - private static String getModuleName(Element element) { - try { - if (qualifiedNamableClass == null) qualifiedNamableClass = Class.forName("javax.lang.model.element.QualifiedNamable"); - if (!qualifiedNamableClass.isInstance(element)) return null; - if (qualifiedNamableQualifiedNameMethod == null) qualifiedNamableQualifiedNameMethod = Permit.getMethod(qualifiedNamableClass, "getQualifiedName"); - String name = Permit.invoke(qualifiedNamableQualifiedNameMethod, element).toString().trim(); - return name.isEmpty() ? null : name; - } catch (ClassNotFoundException e) { - return null; - } catch (NoSuchMethodException e) { - return null; - } catch (InvocationTargetException e) { - return null; - } catch (IllegalAccessException e) { - return null; - } - } - + private JCCompilationUnit toUnit(Element element) { TreePath path = null; if (trees != null) { diff --git a/src/core/lombok/javac/handlers/HandleNonNull.java b/src/core/lombok/javac/handlers/HandleNonNull.java index 271bedbb..e817916d 100644 --- a/src/core/lombok/javac/handlers/HandleNonNull.java +++ b/src/core/lombok/javac/handlers/HandleNonNull.java @@ -218,48 +218,43 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> { @Override public void handle(AnnotationValues<NonNull> annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.NON_NULL_FLAG_USAGE, "@NonNull"); - if (annotationNode.up().getKind() == Kind.FIELD) { + + final JavacNode node; + if (annotationNode.up().getKind() == Kind.TYPE_USE) { + node = annotationNode.directUp().directUp(); + } else { + node = annotationNode.up(); + } + + if (node.getKind() == Kind.FIELD) { // This is meaningless unless the field is used to generate a method (@Setter, @RequiredArgsConstructor, etc), // but in that case those handlers will take care of it. However, we DO check if the annotation is applied to // a primitive, because those handlers trigger on any annotation named @NonNull and we only want the warning // behaviour on _OUR_ 'lombok.NonNull'. try { - if (isPrimitive(((JCVariableDecl) annotationNode.up().get()).vartype)) { + if (isPrimitive(((JCVariableDecl) node.get()).vartype)) { annotationNode.addWarning("@NonNull is meaningless on a primitive."); } } catch (Exception ignore) {} - JCVariableDecl fDecl = (JCVariableDecl) annotationNode.up().get(); + JCVariableDecl fDecl = (JCVariableDecl) node.get(); if ((fDecl.mods.flags & RECORD) != 0) { // well, these kinda double as parameters (of the compact constructor), so we do some work here. - List<JCMethodDecl> compactConstructors = addCompactConstructorIfNeeded(annotationNode.up().up(), annotationNode); + List<JCMethodDecl> compactConstructors = addCompactConstructorIfNeeded(node.up(), annotationNode); for (JCMethodDecl ctr : compactConstructors) { - addNullCheckIfNeeded(ctr, annotationNode.up(), annotationNode); + addNullCheckIfNeeded(ctr, node, annotationNode); } } return; } - JCMethodDecl declaration; - JavacNode paramNode; + if (node.getKind() != Kind.ARGUMENT) return; - switch (annotationNode.up().getKind()) { - case ARGUMENT: - paramNode = annotationNode.up(); - break; - case TYPE_USE: - JavacNode typeNode = annotationNode.directUp(); - paramNode = typeNode.directUp(); - break; - default: - return; - } - - if (paramNode.getKind() != Kind.ARGUMENT) return; + JCMethodDecl declaration; try { - declaration = (JCMethodDecl) paramNode.up().get(); + declaration = (JCMethodDecl) node.up().get(); } catch (Exception e) { return; } @@ -276,7 +271,7 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> { return; } - addNullCheckIfNeeded(declaration, paramNode, annotationNode); + addNullCheckIfNeeded(declaration, node, annotationNode); } public boolean isNullCheck(JCStatement stat) { diff --git a/src/core/lombok/javac/handlers/HandleVal.java b/src/core/lombok/javac/handlers/HandleVal.java index d4fb1027..8f4b1a86 100644 --- a/src/core/lombok/javac/handlers/HandleVal.java +++ b/src/core/lombok/javac/handlers/HandleVal.java @@ -24,15 +24,19 @@ package lombok.javac.handlers; import static lombok.core.handlers.HandlerUtil.handleFlagUsage; import static lombok.javac.handlers.HandleDelegate.HANDLE_DELEGATE_PRIORITY; import static lombok.javac.handlers.JavacHandlerUtil.*; + +import java.lang.reflect.Field; + import lombok.ConfigurationKeys; import lombok.val; -import lombok.core.HandlerPriority; import lombok.var; +import lombok.core.HandlerPriority; import lombok.javac.JavacASTAdapter; import lombok.javac.JavacASTVisitor; import lombok.javac.JavacNode; import lombok.javac.JavacResolution; import lombok.javac.ResolutionResetNeeded; +import lombok.permit.Permit; import lombok.spi.Provides; import com.sun.tools.javac.code.Flags; @@ -87,7 +91,8 @@ public class HandleVal extends JavacASTAdapter { if (local.init == null) { if (parentRaw instanceof JCEnhancedForLoop) { JCEnhancedForLoop efl = (JCEnhancedForLoop) parentRaw; - if (efl.var == local) rhsOfEnhancedForLoop = efl.expr; + JCTree var = EnhancedForLoopReflect.getVarOrRecordPattern(efl); + if (var == local) rhsOfEnhancedForLoop = efl.expr; } } @@ -191,4 +196,19 @@ public class HandleVal extends JavacASTAdapter { recursiveSetGeneratedBy(local.vartype, typeNode); } } + + private static class EnhancedForLoopReflect { + private static final Field varOrRecordPattern = Permit.permissiveGetField(JCEnhancedForLoop.class, "varOrRecordPattern"); + + private static JCTree getVarOrRecordPattern(JCEnhancedForLoop loop) { + if (varOrRecordPattern == null) { + return loop.var; + } + + try { + return (JCTree) varOrRecordPattern.get(loop); + } catch (Exception ignore) {} + return null; + } + } } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 9d153a72..ac947581 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -313,7 +313,11 @@ public class JavacHandlerUtil { * @param typeNode A type reference to check. */ public static boolean typeMatches(String type, JavacNode node, JCTree typeNode) { - String typeName = typeNode == null ? null : typeNode.toString(); + String typeName = getTypeName(typeNode); + return typeMatches(type, node, typeName); + } + + private static boolean typeMatches(String type, JavacNode node, String typeName) { if (typeName == null || typeName.length() == 0) return false; int lastIndexA = typeName.lastIndexOf('.') + 1; int lastIndexB = Math.max(type.lastIndexOf('.'), type.lastIndexOf('$')) + 1; @@ -323,7 +327,11 @@ public class JavacHandlerUtil { TypeResolver resolver = node.getImportListAsTypeResolver(); return resolver.typeMatches(node, type, typeName); } - + + private static String getTypeName(JCTree typeNode) { + return typeNode == null ? null : typeNode.toString(); + } + /** * Returns if a field is marked deprecated, either by {@code @Deprecated} or in javadoc * @param field the field to check @@ -512,6 +520,13 @@ public class JavacHandlerUtil { case LOCAL: JCVariableDecl variable = (JCVariableDecl) parentNode.get(); variable.mods.annotations = filterList(variable.mods.annotations, annotation.get()); + + if ((variable.mods.flags & GENERATED_MEMBER) != 0) { + JavacNode typeNode = upToTypeNode(annotation); + if (isRecord(typeNode)) { + RecordComponentReflect.deleteAnnotation((JCClassDecl) typeNode.get(), variable, annotation.get()); + } + } break; case METHOD: JCMethodDecl method = (JCMethodDecl) parentNode.get(); @@ -559,6 +574,47 @@ public class JavacHandlerUtil { return newAnnotations.toList(); } + private static List<JCAnnotation> filterListByPos(List<JCAnnotation> annotations, JCTree jcTree) { + ListBuffer<JCAnnotation> newAnnotations = new ListBuffer<JCAnnotation>(); + for (JCAnnotation ann : annotations) { + if (jcTree.pos != ann.pos) newAnnotations.append(ann); + } + return newAnnotations.toList(); + } + + + static class RecordComponentReflect { + + private static final Field astField; + private static final Method findRecordComponentToRemove; + + static { + Field a = null; + Method m = null; + try { + Class<?> forName = Class.forName("com.sun.tools.javac.code.Symbol$RecordComponent"); + a = Permit.permissiveGetField(forName, "ast"); + m = Permit.permissiveGetMethod(ClassSymbol.class, "findRecordComponentToRemove", JCVariableDecl.class); + } catch (Throwable e) { + // Ignore + } + astField = a; + findRecordComponentToRemove = m; + } + + static void deleteAnnotation(JCClassDecl record, JCVariableDecl component, JCTree annotation) { + if (astField == null || findRecordComponentToRemove == null) return; + + try { + Object toRemove = Permit.invokeSneaky(findRecordComponentToRemove, record.sym, component); + JCVariableDecl variable = (JCVariableDecl) Permit.get(astField, toRemove); + variable.mods.annotations = filterListByPos(variable.mods.annotations, annotation); + } catch (Throwable e) { + // Ignore + } + } + } + /** Serves as return value for the methods that check for the existence of fields and methods. */ public enum MemberExistsResult { NOT_EXISTS, EXISTS_BY_LOMBOK, EXISTS_BY_USER; @@ -1617,7 +1673,8 @@ public class JavacHandlerUtil { for (JavacNode child : node.down()) { if (child.getKind() == Kind.ANNOTATION) { JCAnnotation annotation = (JCAnnotation) child.get(); - for (String nn : NONNULL_ANNOTATIONS) if (typeMatches(nn, node, annotation.annotationType)) return true; + String annotationTypeName = getTypeName(annotation.annotationType); + for (String nn : NONNULL_ANNOTATIONS) if (typeMatches(nn, node, annotationTypeName)) return true; } } @@ -1627,7 +1684,8 @@ public class JavacHandlerUtil { public static boolean hasNonNullAnnotations(JavacNode node, List<JCAnnotation> anns) { if (anns == null) return false; for (JCAnnotation ann : anns) { - for (String nn : NONNULL_ANNOTATIONS) if (typeMatches(nn, node, ann)) return true; + String annotationTypeName = getTypeName(ann.annotationType); + for (String nn : NONNULL_ANNOTATIONS) if (typeMatches(nn, node, annotationTypeName)) return true; } return false; @@ -1656,21 +1714,22 @@ public class JavacHandlerUtil { java.util.List<TypeName> configuredCopyable = node.getAst().readConfiguration(ConfigurationKeys.COPYABLE_ANNOTATIONS); if (!annoName.isEmpty()) { - for (TypeName cn : configuredCopyable) if (cn != null && typeMatches(cn.toString(), node, anno.annotationType)) return List.of(anno); - for (String bn : BASE_COPYABLE_ANNOTATIONS) if (typeMatches(bn, node, anno.annotationType)) return List.of(anno); + for (TypeName cn : configuredCopyable) if (cn != null && typeMatches(cn.toString(), node, annoName)) return List.of(anno); + for (String bn : BASE_COPYABLE_ANNOTATIONS) if (typeMatches(bn, node, annoName)) return List.of(anno); } - + ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>(); for (JavacNode child : node.down()) { if (child.getKind() == Kind.ANNOTATION) { JCAnnotation annotation = (JCAnnotation) child.get(); + String annotationTypeName = getTypeName(annotation.annotationType); boolean match = false; - for (TypeName cn : configuredCopyable) if (cn != null && typeMatches(cn.toString(), node, annotation.annotationType)) { + for (TypeName cn : configuredCopyable) if (cn != null && typeMatches(cn.toString(), node, annotationTypeName)) { result.append(annotation); match = true; break; } - if (!match) for (String bn : BASE_COPYABLE_ANNOTATIONS) if (typeMatches(bn, node, annotation.annotationType)) { + if (!match) for (String bn : BASE_COPYABLE_ANNOTATIONS) if (typeMatches(bn, node, annotationTypeName)) { result.append(annotation); break; } @@ -1714,15 +1773,16 @@ public class JavacHandlerUtil { if (annoName == null) return List.nil(); if (!annoName.isEmpty()) { - for (String bn : annotationsToFind) if (typeMatches(bn, node, anno.annotationType)) return List.of(anno); + for (String bn : annotationsToFind) if (typeMatches(bn, node, annoName)) return List.of(anno); } ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>(); for (JavacNode child : node.down()) { if (child.getKind() == Kind.ANNOTATION) { JCAnnotation annotation = (JCAnnotation) child.get(); + String annotationTypeName = getTypeName(annotation.annotationType); boolean match = false; - if (!match) for (String bn : annotationsToFind) if (typeMatches(bn, node, annotation.annotationType)) { + if (!match) for (String bn : annotationsToFind) if (typeMatches(bn, node, annotationTypeName)) { result.append(annotation); break; } diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java index 13836d77..b8b38da9 100644 --- a/src/delombok/lombok/delombok/PrettyPrinter.java +++ b/src/delombok/lombok/delombok/PrettyPrinter.java @@ -1253,7 +1253,14 @@ public class PrettyPrinter extends JCTree.Visitor { @Override public void visitForeachLoop(JCEnhancedForLoop tree) { aPrint("for ("); - printVarDefInline(tree.var); + JCTree varOrRecordPattern = readObject(tree, "varOrRecordPattern", null); + if (varOrRecordPattern instanceof JCVariableDecl) { + printVarDefInline((JCVariableDecl) varOrRecordPattern); + } else if (varOrRecordPattern != null) { + print(varOrRecordPattern); + } else { + printVarDefInline(tree.var); + } print(" : "); print(tree.expr); print(") "); @@ -1427,9 +1434,7 @@ public class PrettyPrinter extends JCTree.Visitor { void printBindingPattern(JCTree tree) { JCTree var = readObject(tree, "var", tree); - print((JCExpression) readObject(var, "vartype", null)); - print(" "); - print((Name) readObject(var, "name", null)); + printVarDef0((JCVariableDecl) var); } void printDefaultCase(JCTree tree) { diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index c7bdbc31..5404ee1d 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -60,6 +60,8 @@ 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.MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment; +import lombok.permit.Permit; + import static lombok.eclipse.EcjAugments.ASTNode_generatedBy; /** These contain a mix of the following: @@ -200,6 +202,13 @@ final class PatchFixesHider { if (TRANSFORM != null) return; Main.prependClassLoader(prepend); + try { + ClassLoader currentClassLoader = Transform.class.getClassLoader(); + Method prependParentMethod = Permit.getMethod(currentClassLoader.getClass(), "prependParent", ClassLoader.class); + Permit.invoke(prependParentMethod, currentClassLoader, prepend); + } catch (Throwable t) { + // Ignore + } Class<?> shadowed = Util.shadowLoadClass("lombok.eclipse.TransformEclipseAST"); TRANSFORM = Util.findMethodAnyArgs(shadowed, "transform"); TRANSFORM_SWAPPED = Util.findMethodAnyArgs(shadowed, "transform_swapped"); |