diff options
Diffstat (limited to 'src')
29 files changed, 202 insertions, 193 deletions
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index 05550a06..457246e7 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -291,6 +291,13 @@ public class ConfigurationKeys { */ public static final ConfigurationKey<Boolean> TO_STRING_INCLUDE_FIELD_NAMES = new ConfigurationKey<Boolean>("lombok.toString.includeFieldNames", "Include the field names in the generated toString method (default = true).") {}; + /** + * lombok configuration: {@code lombok.toString.onlyExplicitlyIncluded} = {@code true} | {@code false}. + * + * If {@code true}, require a {@code @ToString.Include} annotation on any fields/no-args methods you want to include in lombok's generated `@ToString` method. Otherwise, every (non-static, non-dollar-named) field is included by default (default = false). + */ + public static final ConfigurationKey<Boolean> TO_STRING_ONLY_EXPLICITLY_INCLUDED = new ConfigurationKey<Boolean>("lombok.toString.onlyExplicitlyIncluded", "Include only fields/methods explicitly marked with @ToString.Include. Otherwise, include all non-static, non-dollar-named fields (default = false).") {}; + // ----- Builder ----- /** diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java index 07d035c5..738241e2 100755 --- a/src/core/lombok/core/AST.java +++ b/src/core/lombok/core/AST.java @@ -454,4 +454,9 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>, if (configTracker != null) configTracker.end(start); } } + + public boolean getBooleanAnnotationValue(AnnotationValues<?> annotation, String annoMethod, ConfigurationKey<Boolean> confKey) { + Boolean conf = readConfiguration(confKey); + return annotation.isExplicit(annoMethod) || conf == null ? annotation.getAsBoolean(annoMethod) : conf; + } } diff --git a/src/core/lombok/core/AnnotationValues.java b/src/core/lombok/core/AnnotationValues.java index 78bb1fb5..f5db553c 100644 --- a/src/core/lombok/core/AnnotationValues.java +++ b/src/core/lombok/core/AnnotationValues.java @@ -165,7 +165,7 @@ public class AnnotationValues<A extends Annotation> { AnnotationValue v = values.get(methodName); if (v == null) { - String[] s = getDefaultIf(methodName, String[].class, new String[0]); + String[] s = getDefaultIf(methodName, new String[0]); return Collections.unmodifiableList(Arrays.asList(s)); } @@ -175,7 +175,7 @@ public class AnnotationValues<A extends Annotation> { Object result = guess == null ? null : guessToType(guess, String.class, v, idx); if (result == null) { if (v.valueGuesses.size() == 1) { - String[] s = getDefaultIf(methodName, String[].class, new String[0]); + String[] s = getDefaultIf(methodName, new String[0]); return Collections.unmodifiableList(Arrays.asList(s)); } throw new AnnotationValueDecodeFail(v, @@ -190,28 +190,29 @@ public class AnnotationValues<A extends Annotation> { public String getAsString(String methodName) { AnnotationValue v = values.get(methodName); if (v == null || v.valueGuesses.size() != 1) { - return getDefaultIf(methodName, String.class, ""); + return getDefaultIf(methodName, ""); } Object guess = guessToType(v.valueGuesses.get(0), String.class, v, 0); if (guess instanceof String) return (String) guess; - return getDefaultIf(methodName, String.class, ""); + return getDefaultIf(methodName, ""); } public boolean getAsBoolean(String methodName) { AnnotationValue v = values.get(methodName); if (v == null || v.valueGuesses.size() != 1) { - return getDefaultIf(methodName, boolean.class, false); + return getDefaultIf(methodName, false); } Object guess = guessToType(v.valueGuesses.get(0), boolean.class, v, 0); if (guess instanceof Boolean) return ((Boolean) guess).booleanValue(); - return getDefaultIf(methodName, boolean.class, false); + return getDefaultIf(methodName, false); } - public <T> T getDefaultIf(String methodName, Class<T> type, T defaultValue) { + @SuppressWarnings("unchecked") + public <T> T getDefaultIf(String methodName, T defaultValue) { try { - return type.cast(Permit.getMethod(type, methodName).getDefaultValue()); + return (T) Permit.getMethod(type, methodName).getDefaultValue(); } catch (Exception e) { return defaultValue; } diff --git a/src/core/lombok/core/configuration/CheckerFrameworkVersion.java b/src/core/lombok/core/configuration/CheckerFrameworkVersion.java index c37ba91d..e69476ac 100644 --- a/src/core/lombok/core/configuration/CheckerFrameworkVersion.java +++ b/src/core/lombok/core/configuration/CheckerFrameworkVersion.java @@ -33,7 +33,6 @@ public final class CheckerFrameworkVersion implements ConfigurationValueType { public static final String NAME__PURE = "org.checkerframework.dataflow.qual.Pure"; public static final String NAME__UNIQUE = "org.checkerframework.common.aliasing.qual.Unique"; public static final String NAME__RETURNS_RECEIVER = "org.checkerframework.common.returnsreceiver.qual.This"; - public static final String NAME__NOT_CALLED = "org.checkerframework.checker.calledmethods.qual.NotCalledMethods"; public static final String NAME__CALLED = "org.checkerframework.checker.calledmethods.qual.CalledMethods"; public static final CheckerFrameworkVersion NONE = new CheckerFrameworkVersion(0); @@ -57,11 +56,11 @@ public final class CheckerFrameworkVersion implements ConfigurationValueType { } public boolean generateReturnsReceiver() { - return version > 3999; + return version >= 3100; } public boolean generateCalledMethods() { - return version > 3999; + return version >= 3100; } public static CheckerFrameworkVersion valueOf(String versionString) { diff --git a/src/core/lombok/core/configuration/ConfigurationApp.java b/src/core/lombok/core/configuration/ConfigurationApp.java index 8d794c8a..268e83b5 100644 --- a/src/core/lombok/core/configuration/ConfigurationApp.java +++ b/src/core/lombok/core/configuration/ConfigurationApp.java @@ -232,6 +232,7 @@ public class ConfigurationApp extends LombokApp { if (!problems.isEmpty()) { err.printf("Problems in the configuration files:%n"); for (String problem : problems) err.printf("- %s%n", problem); + return 2; } return 0; diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index f90a7caf..2415b750 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -902,7 +902,7 @@ public class HandlerUtil { public static String stripLinesWithTagFromJavadoc(String javadoc, JavadocTag tag) { if (javadoc == null || javadoc.isEmpty()) return javadoc; - return tag.pattern.matcher(javadoc).replaceAll(""); + return tag.pattern.matcher(javadoc).replaceAll("").trim(); } public static String stripSectionsFromJavadoc(String javadoc) { diff --git a/src/core/lombok/core/handlers/InclusionExclusionUtils.java b/src/core/lombok/core/handlers/InclusionExclusionUtils.java index 0aa6c47b..2a519b82 100644 --- a/src/core/lombok/core/handlers/InclusionExclusionUtils.java +++ b/src/core/lombok/core/handlers/InclusionExclusionUtils.java @@ -113,10 +113,14 @@ public class InclusionExclusionUtils { } private static <A extends AST<A, L, N>, L extends LombokNode<A, L, N>, N, I extends Annotation> List<Included<L, I>> handleIncludeExcludeMarking(Class<I> inclType, String replaceName, Class<? extends Annotation> exclType, LombokNode<A, L, N> typeNode, AnnotationValues<?> annotation, LombokNode<A, L, N> annotationNode, boolean includeTransient) { + boolean onlyExplicitlyIncluded = annotation != null ? annotation.getAsBoolean("onlyExplicitlyIncluded") : false; + return handleIncludeExcludeMarking(inclType, onlyExplicitlyIncluded, replaceName, exclType, typeNode, annotation, annotationNode, includeTransient); + } + + private static <A extends AST<A, L, N>, L extends LombokNode<A, L, N>, N, I extends Annotation> List<Included<L, I>> handleIncludeExcludeMarking(Class<I> inclType, boolean onlyExplicitlyIncluded, String replaceName, Class<? extends Annotation> exclType, LombokNode<A, L, N> typeNode, AnnotationValues<?> annotation, LombokNode<A, L, N> annotationNode, boolean includeTransient) { List<String> oldExcludes = (annotation != null && annotation.isExplicit("exclude")) ? annotation.getAsStringList("exclude") : null; List<String> oldIncludes = (annotation != null && annotation.isExplicit("of")) ? annotation.getAsStringList("of") : null; - boolean onlyExplicitlyIncluded = annotation != null ? annotation.getAsBoolean("onlyExplicitlyIncluded") : false; boolean memberAnnotationMode = onlyExplicitlyIncluded; List<Included<L, I>> members = new ArrayList<Included<L, I>>(); List<String> namesToAutoExclude = new ArrayList<String>(); @@ -203,14 +207,14 @@ public class InclusionExclusionUtils { return members; } - public static <A extends AST<A, L, N>, L extends LombokNode<A, L, N>, N> List<Included<L, ToString.Include>> handleToStringMarking(LombokNode<A, L, N> typeNode, AnnotationValues<ToString> annotation, LombokNode<A, L, N> annotationNode) { - List<Included<L, ToString.Include>> members = handleIncludeExcludeMarking(ToString.Include.class, "name", ToString.Exclude.class, typeNode, annotation, annotationNode, true); + public static <A extends AST<A, L, N>, L extends LombokNode<A, L, N>, N> List<Included<L, ToString.Include>> handleToStringMarking(LombokNode<A, L, N> typeNode, boolean onlyExplicitlyIncluded, AnnotationValues<ToString> annotation, LombokNode<A, L, N> annotationNode) { + List<Included<L, ToString.Include>> members = handleIncludeExcludeMarking(ToString.Include.class, onlyExplicitlyIncluded, "name", ToString.Exclude.class, typeNode, annotation, annotationNode, true); Collections.sort(members, new Comparator<Included<L, ToString.Include>>() { @Override public int compare(Included<L, ToString.Include> a, Included<L, ToString.Include> b) { int ra = a.getInc() == null ? 0 : a.getInc().rank(); int rb = b.getInc() == null ? 0 : b.getInc().rank(); - + return compareRankOrPosition(ra, rb, a.getNode(), b.getNode()); } }); @@ -219,28 +223,28 @@ public class InclusionExclusionUtils { public static <A extends AST<A, L, N>, L extends LombokNode<A, L, N>, N> List<Included<L, EqualsAndHashCode.Include>> handleEqualsAndHashCodeMarking(LombokNode<A, L, N> typeNode, AnnotationValues<EqualsAndHashCode> annotation, LombokNode<A, L, N> annotationNode) { List<Included<L, EqualsAndHashCode.Include>> members = handleIncludeExcludeMarking(EqualsAndHashCode.Include.class, "replaces", EqualsAndHashCode.Exclude.class, typeNode, annotation, annotationNode, false); - + Collections.sort(members, new Comparator<Included<L, EqualsAndHashCode.Include>>() { @Override public int compare(Included<L, EqualsAndHashCode.Include> a, Included<L, EqualsAndHashCode.Include> b) { int ra = a.hasExplicitRank() ? a.getInc().rank() : HandlerUtil.defaultEqualsAndHashcodeIncludeRank(a.node.fieldOrMethodBaseType()); int rb = b.hasExplicitRank() ? b.getInc().rank() : HandlerUtil.defaultEqualsAndHashcodeIncludeRank(b.node.fieldOrMethodBaseType()); - + return compareRankOrPosition(ra, rb, a.getNode(), b.getNode()); } }); return members; } - + private static <A extends AST<A, L, N>, L extends LombokNode<A, L, N>, N> int compareRankOrPosition(int ra, int rb, LombokNode<A, L, N> nodeA, LombokNode<A, L, N> nodeB) { if (ra < rb) return +1; if (ra > rb) return -1; - + int pa = nodeA.getStartPos(); int pb = nodeB.getStartPos(); - + if (pa < pb) return -1; if (pa > pb) return +1; - + return 0; } } diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index f8cde6c8..6483a749 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -447,16 +447,18 @@ public class EclipseHandlerUtil { // arrays if (in instanceof ArrayInitializer) { - Expression[] exprs = ((ArrayInitializer) in).expressions; - Expression[] copy = new Expression[exprs.length]; - for (int i = 0; i < exprs.length; i++) copy[i] = copyAnnotationMemberValue(exprs[i]); ArrayInitializer out = new ArrayInitializer(); out.sourceStart = s; out.sourceEnd = e; out.bits = in.bits; out.implicitConversion = in.implicitConversion; out.statementEnd = e; - out.expressions = copy; + Expression[] exprs = ((ArrayInitializer) in).expressions; + if (exprs != null) { + Expression[] copy = new Expression[exprs.length]; + for (int i = 0; i < exprs.length; i++) copy[i] = copyAnnotationMemberValue(exprs[i]); + out.expressions = copy; + } return out; } @@ -2094,6 +2096,15 @@ public class EclipseHandlerUtil { return newAnnotationArray; } + public static void addCheckerFrameworkReturnsReceiver(TypeReference returnType, ASTNode source, CheckerFrameworkVersion cfv) { + if (cfv.generateReturnsReceiver()) { + Annotation rrAnn = generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER); + int levels = returnType.getAnnotatableLevels(); + returnType.annotations = new Annotation[levels][]; + returnType.annotations[levels-1] = new Annotation[] {rrAnn}; + } + } + private static boolean arrayHasOnlyElementsOfType(Object[] array, Class<?> clazz) { for (Object element : array) { if (!clazz.isInstance(element)) diff --git a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java index d099cab2..998c1274 100755 --- a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java +++ b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java @@ -300,13 +300,10 @@ public class EclipseSingularsRecipes { // -- Utility methods -- - protected Annotation[] generateSelfReturnAnnotations(boolean deprecate, CheckerFrameworkVersion cfv, ASTNode source) { + protected Annotation[] generateSelfReturnAnnotations(boolean deprecate, ASTNode source) { Annotation deprecated = deprecate ? generateDeprecatedAnnotation(source) : null; - Annotation returnsReceiver = cfv.generateReturnsReceiver() ? generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER) : null; - if (deprecated == null && returnsReceiver == null) return null; - if (deprecated == null) return new Annotation[] {returnsReceiver}; - if (returnsReceiver == null) return new Annotation[] {deprecated}; - return new Annotation[] {deprecated, returnsReceiver}; + if (deprecated == null) return null; + return new Annotation[] {deprecated}; } /** diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index 2bfe1e8b..a2dd5057 100755 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -767,18 +767,6 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> { return decl; } - static Receiver generateNotCalledReceiver(BuilderJob job, String setterName) { - char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED); - SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(job.source, nameNotCalled.length)), job.source.sourceStart); - ann.memberValue = new StringLiteral(setterName.toCharArray(), 0, 0, 0); - - TypeReference typeReference = job.createBuilderTypeReference(); - int trLen = typeReference.getTypeName().length; - typeReference.annotations = new Annotation[trLen][]; - typeReference.annotations[trLen - 1] = new Annotation[] {ann}; - return new Receiver(new char[] { 't', 'h', 'i', 's' }, 0, typeReference, null, 0); - } - static Receiver generateBuildReceiver(BuilderJob job) { if (!job.checkerFramework.generateCalledMethods()) return null; @@ -1050,7 +1038,6 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> { ASTNode source = job.sourceNode.get(); MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, bfd.name, bfd.nameOfSetFlag, job.oldChain, toEclipseModifier(job.accessInners), job.sourceNode, methodAnnsList, bfd.annotations != null ? Arrays.asList(copyAnnotations(source, bfd.annotations)) : Collections.<Annotation>emptyList()); - if (job.checkerFramework.generateCalledMethods()) setter.receiver = generateNotCalledReceiver(job, setterName); if (job.sourceNode.up().getKind() == Kind.METHOD) { copyJavadocFromParam(bfd.originalFieldNode.up(), setter, td, bfd.name.toString()); } else { diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java index ddae21fb..0fdd058f 100644 --- a/src/core/lombok/eclipse/handlers/HandleSetter.java +++ b/src/core/lombok/eclipse/handlers/HandleSetter.java @@ -34,7 +34,6 @@ import lombok.AccessLevel; import lombok.ConfigurationKeys; import lombok.Setter; import lombok.core.AST.Kind; -import lombok.core.configuration.CheckerFrameworkVersion; import lombok.core.AnnotationValues; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; @@ -191,14 +190,12 @@ public class HandleSetter extends EclipseAnnotationHandler<Setter> { ReturnStatement returnThis = null; if (shouldReturnThis) { returnType = cloneSelfType(fieldNode, source); + addCheckerFrameworkReturnsReceiver(returnType, source, getCheckerFrameworkVersion(sourceNode)); ThisReference thisRef = new ThisReference(pS, pE); returnThis = new ReturnStatement(thisRef, pS, pE); } MethodDeclaration d = createSetter(parent, deprecate, fieldNode, name, paramName, booleanFieldToSet, returnType, returnThis, modifier, sourceNode, onMethod, onParam); - if (shouldReturnThis && getCheckerFrameworkVersion(sourceNode).generateReturnsReceiver()) { - d.annotations = copyAnnotations(source, d.annotations, new Annotation[] { generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER) }); - } return d; } diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index 26b62cbf..558c6ec2 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -51,6 +51,7 @@ import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.FieldReference; import org.eclipse.jdt.internal.compiler.ast.IfStatement; import org.eclipse.jdt.internal.compiler.ast.Initializer; +import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.NullLiteral; @@ -838,16 +839,12 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; out.modifiers = ClassFileConstants.AccAbstract | ClassFileConstants.AccProtected | ExtraCompilerModifiers.AccSemicolonBody; Annotation overrideAnn = override ? makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, job.parentType.get()) : null; - Annotation rrAnn = job.checkerFramework.generateReturnsReceiver() ? generateNamedAnnotation(job.parentType.get(), CheckerFrameworkVersion.NAME__RETURNS_RECEIVER): null; Annotation sefAnn = job.checkerFramework.generatePure() ? generateNamedAnnotation(job.parentType.get(), CheckerFrameworkVersion.NAME__PURE): null; - if (overrideAnn != null && rrAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn, sefAnn}; - else if (overrideAnn != null && rrAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn}; - else if (overrideAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn}; + if (overrideAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn}; else if (overrideAnn != null) out.annotations = new Annotation[] {overrideAnn}; - else if (rrAnn != null && sefAnn != null) out.annotations = new Annotation[] {rrAnn, sefAnn}; - else if (rrAnn != null) out.annotations = new Annotation[] {rrAnn}; else if (sefAnn != null) out.annotations = new Annotation[] {sefAnn}; out.returnType = new SingleTypeReference(builderGenericName.toCharArray(), 0); + addCheckerFrameworkReturnsReceiver(out.returnType, job.parentType.get(), job.checkerFramework); return out; } @@ -857,13 +854,11 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; out.modifiers = ClassFileConstants.AccProtected; Annotation overrideAnn = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, job.builderType.get()); - Annotation rrAnn = job.checkerFramework.generateReturnsReceiver() ? generateNamedAnnotation(job.builderType.get(), CheckerFrameworkVersion.NAME__RETURNS_RECEIVER) : null; Annotation sefAnn = job.checkerFramework.generatePure() ? generateNamedAnnotation(job.builderType.get(), CheckerFrameworkVersion.NAME__PURE) : null; - if (rrAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn, sefAnn}; - else if (rrAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn}; - else if (sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn}; + if (sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn}; else out.annotations = new Annotation[] {overrideAnn}; out.returnType = namePlusTypeParamsToTypeReference(job.builderType, job.typeParams, job.getPos()); + addCheckerFrameworkReturnsReceiver(out.returnType, job.parentType.get(), job.checkerFramework); out.statements = new Statement[] {new ReturnStatement(new ThisReference(0, 0), 0, 0)}; return out; } @@ -1013,13 +1008,9 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { } List<Annotation> methodAnnsList = Arrays.asList(EclipseHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode)); - if (job.checkerFramework.generateReturnsReceiver()) { - methodAnnsList = new ArrayList<Annotation>(methodAnnsList); - methodAnnsList.add(generateNamedAnnotation(job.source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER)); - } + addCheckerFrameworkReturnsReceiver(returnType, job.source, job.checkerFramework); MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, paramName, nameOfSetFlag, returnType, returnStatement, ClassFileConstants.AccPublic, job.sourceNode, methodAnnsList, annosOnParam != null ? Arrays.asList(copyAnnotations(job.source, annosOnParam)) : Collections.<Annotation>emptyList()); - if (job.checkerFramework.generateCalledMethods()) setter.receiver = generateNotCalledReceiver(job, setterName); injectMethod(job.builderType, setter); } diff --git a/src/core/lombok/eclipse/handlers/HandleToString.java b/src/core/lombok/eclipse/handlers/HandleToString.java index 05b0e069..b22d162f 100644 --- a/src/core/lombok/eclipse/handlers/HandleToString.java +++ b/src/core/lombok/eclipse/handlers/HandleToString.java @@ -76,7 +76,8 @@ public class HandleToString extends EclipseAnnotationHandler<ToString> { handleFlagUsage(annotationNode, ConfigurationKeys.TO_STRING_FLAG_USAGE, "@ToString"); ToString ann = annotation.getInstance(); - List<Included<EclipseNode, ToString.Include>> members = InclusionExclusionUtils.handleToStringMarking(annotationNode.up(), annotation, annotationNode); + boolean onlyExplicitlyIncluded = annotationNode.getAst().getBooleanAnnotationValue(annotation, "onlyExplicitlyIncluded", ConfigurationKeys.TO_STRING_ONLY_EXPLICITLY_INCLUDED); + List<Included<EclipseNode, ToString.Include>> members = InclusionExclusionUtils.handleToStringMarking(annotationNode.up(), onlyExplicitlyIncluded, annotation, annotationNode); if (members == null) return; Boolean callSuper = ann.callSuper(); @@ -99,16 +100,14 @@ public class HandleToString extends EclipseAnnotationHandler<ToString> { return; } - boolean includeFieldNames = true; - try { - Boolean configuration = typeNode.getAst().readConfiguration(ConfigurationKeys.TO_STRING_INCLUDE_FIELD_NAMES); - includeFieldNames = configuration != null ? configuration : ((Boolean)ToString.class.getMethod("includeFieldNames").getDefaultValue()).booleanValue(); - } catch (Exception ignore) {} + AnnotationValues<ToString> anno = AnnotationValues.of(ToString.class); + boolean includeFieldNames = typeNode.getAst().getBooleanAnnotationValue(anno, "includeFieldNames", ConfigurationKeys.TO_STRING_INCLUDE_FIELD_NAMES); + boolean onlyExplicitlyIncluded = typeNode.getAst().getBooleanAnnotationValue(anno, "onlyExplicitlyIncluded", ConfigurationKeys.TO_STRING_ONLY_EXPLICITLY_INCLUDED); Boolean doNotUseGettersConfiguration = typeNode.getAst().readConfiguration(ConfigurationKeys.TO_STRING_DO_NOT_USE_GETTERS); FieldAccess access = doNotUseGettersConfiguration == null || !doNotUseGettersConfiguration ? FieldAccess.GETTER : FieldAccess.PREFER_FIELD; - List<Included<EclipseNode, ToString.Include>> members = InclusionExclusionUtils.handleToStringMarking(typeNode, null, null); + List<Included<EclipseNode, ToString.Include>> members = InclusionExclusionUtils.handleToStringMarking(typeNode, onlyExplicitlyIncluded, null, null); generateToString(typeNode, errorNode, members, includeFieldNames, null, false, access); } @@ -204,7 +203,7 @@ public class HandleToString extends EclipseAnnotationHandler<ToString> { if (!prefix.isEmpty()) { StringLiteral px = new StringLiteral(prefix.toCharArray(), pS, pE, 0); - setGeneratedBy(px, source); + setGeneratedBy(px, source); current = new BinaryExpression(current, px, PLUS); current.sourceStart = pS; current.sourceEnd = pE; setGeneratedBy(current, source); diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java index 9b464a25..47822ff3 100755 --- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java +++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java @@ -93,7 +93,7 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer { } @Override protected char[][] getEmptyMakerReceiver(String targetFqn) { - return CGCC; + return makeGuavaTypeName(GuavaTypeMap.getGuavaTypeName(targetFqn), false); } @Override public List<EclipseNode> generateFields(SingularData data, EclipseNode builderType) { @@ -129,13 +129,14 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer { 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()); + addCheckerFrameworkReturnsReceiver(md.returnType, data.getSource(), cfv); + md.annotations = generateSelfReturnAnnotations(deprecate, data.getSource()); data.setGeneratedByRecursive(md); if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); injectMethod(builderType, md); } - + void generateSingularMethod(CheckerFrameworkVersion cfv, boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) { LombokImmutableList<String> suffixes = getArgumentSuffixes(); char[][] names = new char[suffixes.size()][]; @@ -173,9 +174,10 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer { md.arguments[i].annotations = typeUseAnns; } md.returnType = returnType; + addCheckerFrameworkReturnsReceiver(md.returnType, data.getSource(), cfv); 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[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, data.getSource()); Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up())); md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); @@ -213,9 +215,10 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer { md.arguments = new Argument[] {param}; md.returnType = returnType; + addCheckerFrameworkReturnsReceiver(md.returnType, data.getSource(), cfv); 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[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, 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 6f5e9add..fbde3021 100755 --- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java +++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java @@ -119,7 +119,8 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula Statement clearStatement = new IfStatement(new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.NOT_EQUAL), clearMsg, 0, 0); md.statements = returnStatement != null ? new Statement[] {clearStatement, returnStatement} : new Statement[] {clearStatement}; md.returnType = returnType; - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + addCheckerFrameworkReturnsReceiver(md.returnType, data.getSource(), cfv); + md.annotations = generateSelfReturnAnnotations(deprecate, data.getSource()); data.setGeneratedByRecursive(md); if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); @@ -151,9 +152,10 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula param.annotations = typeUseAnns; md.arguments = new Argument[] {param}; md.returnType = returnType; + addCheckerFrameworkReturnsReceiver(md.returnType, data.getSource(), cfv); 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[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, data.getSource()); Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up())); md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); @@ -189,9 +191,10 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula md.arguments = new Argument[] {param}; md.returnType = returnType; + addCheckerFrameworkReturnsReceiver(md.returnType, data.getSource(), cfv); 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[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, 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 c28ba59d..859cce94 100755 --- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java +++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java @@ -189,7 +189,8 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer Statement clearStatement = new IfStatement(new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.NOT_EQUAL), clearMsgs, 0, 0); md.statements = returnStatement != null ? new Statement[] {clearStatement, returnStatement} : new Statement[] {clearStatement}; md.returnType = returnType; - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + addCheckerFrameworkReturnsReceiver(md.returnType, data.getSource(), cfv); + md.annotations = generateSelfReturnAnnotations(deprecate, data.getSource()); if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); @@ -246,13 +247,14 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer valueParam.annotations = typeUseAnnsValue; md.arguments = new Argument[] {keyParam, valueParam}; md.returnType = returnType; + addCheckerFrameworkReturnsReceiver(md.returnType, data.getSource(), cfv); String name = new String(data.getSingularName()); String setterPrefix = data.getSetterPrefix().length > 0 ? new String(data.getSetterPrefix()) : fluent ? "" : "put"; String setterName = HandlerUtil.buildAccessorName(builderType, setterPrefix, name); md.selector = setterName.toCharArray(); - Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, data.getSource()); Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up())); md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); @@ -322,13 +324,14 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer md.arguments = new Argument[] {param}; md.returnType = returnType; + addCheckerFrameworkReturnsReceiver(md.returnType, data.getSource(), cfv); String name = new String(data.getPluralName()); String setterPrefix = data.getSetterPrefix().length > 0 ? new String(data.getSetterPrefix()) : fluent ? "" : "put"; String setterName = HandlerUtil.buildAccessorName(builderType, setterPrefix, name); md.selector = setterName.toCharArray(); - Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, data.getSource()); Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up())); md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); diff --git a/src/core/lombok/javac/HandlerLibrary.java b/src/core/lombok/javac/HandlerLibrary.java index c2bf8512..d401f59d 100644 --- a/src/core/lombok/javac/HandlerLibrary.java +++ b/src/core/lombok/javac/HandlerLibrary.java @@ -104,13 +104,13 @@ public class HandlerLibrary { this.handler = handler; this.annotationClass = annotationClass; HandlerPriority hp = handler.getClass().getAnnotation(HandlerPriority.class); - this.priority = hp == null ? 0L : (((long)hp.value()) << 32) + hp.subValue(); + this.priority = hp == null ? 0L : (((long) hp.value()) << 32) + hp.subValue(); this.resolutionResetNeeded = handler.getClass().isAnnotationPresent(ResolutionResetNeeded.class); this.evenIfAlreadyHandled = handler.getClass().isAnnotationPresent(AlreadyHandledAnnotations.class); } public void handle(final JavacNode node) { - handler.handle(JavacHandlerUtil.createAnnotation(annotationClass, node), (JCAnnotation)node.get(), node); + handler.handle(JavacHandlerUtil.createAnnotation(annotationClass, node), (JCAnnotation) node.get(), node); } public long getPriority() { diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index d8fdfb1b..854c8524 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -47,6 +47,7 @@ import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; import com.sun.tools.javac.tree.JCTree.JCModifiers; import com.sun.tools.javac.tree.JCTree.JCNewClass; import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree; +import com.sun.tools.javac.tree.JCTree.JCReturn; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCTypeApply; import com.sun.tools.javac.tree.JCTree.JCTypeParameter; @@ -286,8 +287,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { bfd.nameOfDefaultProvider = parent.toName(DEFAULT_PREFIX + bfd.name); bfd.nameOfSetFlag = parent.toName(bfd.name + SET_PREFIX); bfd.builderFieldName = parent.toName(bfd.name + VALUE_PREFIX); - JCMethodDecl md = generateDefaultProvider(bfd.nameOfDefaultProvider, fieldNode, td.typarams); - recursiveSetGeneratedBy(md, annotationNode); + JCMethodDecl md = generateDefaultProvider(bfd.nameOfDefaultProvider, fieldNode, td.typarams, job); if (md != null) injectMethod(parent, md); } addObtainVia(bfd, fieldNode); @@ -804,16 +804,24 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { return methodDef; } - public static JCMethodDecl generateDefaultProvider(Name methodName, JavacNode fieldNode, List<JCTypeParameter> params) { + public static JCMethodDecl generateDefaultProvider(Name methodName, JavacNode fieldNode, List<JCTypeParameter> params, BuilderJob job) { JavacTreeMaker maker = fieldNode.getTreeMaker(); JCVariableDecl field = (JCVariableDecl) fieldNode.get(); - JCStatement statement = maker.Return(field.init); + // Lombok tries to keep the position of the original initializer. First we save the expression ... + JCExpression init = field.init; field.init = null; + // ... then we generate an empty return statement ... + JCReturn statement = maker.Return(null); JCBlock body = maker.Block(0, List.<JCStatement>of(statement)); int modifiers = Flags.PRIVATE | Flags.STATIC; - return maker.MethodDef(maker.Modifiers(modifiers), methodName, cloneType(maker, field.vartype, fieldNode), copyTypeParams(fieldNode, params), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null); + JCMethodDecl defaultProvider = maker.MethodDef(maker.Modifiers(modifiers), methodName, cloneType(maker, field.vartype, fieldNode), copyTypeParams(fieldNode, params), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null); + // ... then we set positions for everything else ... + recursiveSetGeneratedBy(defaultProvider, job.sourceNode); + // ... and finally add back the original expression + statement.expr = init; + return defaultProvider; } public JCMethodDecl generateBuilderMethod(BuilderJob job) { @@ -914,15 +922,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { JavacTreeMaker maker = fieldNode.getTreeMaker(); List<JCAnnotation> methodAnns = JavacHandlerUtil.findCopyableToSetterAnnotations(bfd.originalFieldNode); - JCMethodDecl newMethod = null; - if (job.checkerFramework.generateCalledMethods() && maker.hasMethodDefWithRecvParam()) { - JCAnnotation ncAnno = maker.Annotation(genTypeRef(job.sourceNode, CheckerFrameworkVersion.NAME__NOT_CALLED), List.<JCExpression>of(maker.Literal(setterName.toString()))); - JCClassDecl builderTypeNode = (JCClassDecl) job.builderType.get(); - JCExpression selfType = namePlusTypeParamsToTypeReference(maker, job.builderType, builderTypeNode.typarams, List.<JCAnnotation>of(ncAnno)); - JCVariableDecl recv = maker.VarDef(maker.Modifiers(Flags.PARAMETER, List.<JCAnnotation>nil()), job.builderType.toName("this"), selfType, null); - newMethod = HandleSetter.createSetterWithRecv(toJavacModifier(job.accessInners), deprecate, fieldNode, maker, setterName, bfd.name, bfd.nameOfSetFlag, job.oldChain, job.sourceNode, methodAnns, bfd.annotations, recv); - } - if (newMethod == null) newMethod = HandleSetter.createSetter(toJavacModifier(job.accessInners), deprecate, fieldNode, maker, setterName, bfd.name, bfd.nameOfSetFlag, job.oldChain, job.sourceNode, methodAnns, bfd.annotations); + JCMethodDecl newMethod = HandleSetter.createSetter(toJavacModifier(job.accessInners), deprecate, fieldNode, maker, setterName, bfd.name, bfd.nameOfSetFlag, job.oldChain, job.sourceNode, methodAnns, bfd.annotations); recursiveSetGeneratedBy(newMethod, job.sourceNode); if (job.sourceNode.up().getKind() == Kind.METHOD) { copyJavadocFromParam(bfd.originalFieldNode.up(), newMethod, bfd.name.toString()); diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index e5b2c062..1b675e8c 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -32,7 +32,6 @@ import lombok.ConfigurationKeys; import lombok.Setter; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; -import lombok.core.configuration.CheckerFrameworkVersion; import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; @@ -195,17 +194,11 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { JCReturn returnStatement = null; if (shouldReturnThis) { returnType = cloneSelfType(field); + returnType = addCheckerFrameworkReturnsReceiver(returnType, treeMaker, field, getCheckerFrameworkVersion(source)); returnStatement = treeMaker.Return(treeMaker.Ident(field.toName("this"))); } JCMethodDecl d = createSetter(access, deprecate, field, treeMaker, setterName, paramName, booleanFieldToSet, returnType, returnStatement, source, onMethod, onParam); - if (shouldReturnThis && getCheckerFrameworkVersion(source).generateReturnsReceiver()) { - List<JCAnnotation> annotations = d.mods.annotations; - if (annotations == null) annotations = List.nil(); - JCAnnotation anno = treeMaker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil()); - recursiveSetGeneratedBy(anno, source); - d.mods.annotations = annotations.prepend(anno); - } return d; } @@ -214,17 +207,11 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { JCReturn returnStatement = null; if (shouldReturnThis) { returnType = cloneSelfType(field); + returnType = addCheckerFrameworkReturnsReceiver(returnType, treeMaker, field, getCheckerFrameworkVersion(source)); returnStatement = treeMaker.Return(treeMaker.Ident(field.toName("this"))); } JCMethodDecl d = createSetterWithRecv(access, deprecate, field, treeMaker, setterName, paramName, booleanFieldToSet, returnType, returnStatement, source, onMethod, onParam, recv); - if (shouldReturnThis && getCheckerFrameworkVersion(source).generateReturnsReceiver()) { - List<JCAnnotation> annotations = d.mods.annotations; - if (annotations == null) annotations = List.nil(); - JCAnnotation anno = treeMaker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil()); - recursiveSetGeneratedBy(anno, source); - d.mods.annotations = annotations.prepend(anno); - } return d; } diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index b5bc73fb..adf3f584 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -208,8 +208,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { bfd.nameOfDefaultProvider = parent.toName(DEFAULT_PREFIX + bfd.name); bfd.nameOfSetFlag = parent.toName(bfd.name + SET_PREFIX); bfd.builderFieldName = parent.toName(bfd.name + VALUE_PREFIX); - JCMethodDecl md = HandleBuilder.generateDefaultProvider(bfd.nameOfDefaultProvider, fieldNode, td.typarams); - recursiveSetGeneratedBy(md, annotationNode); + JCMethodDecl md = HandleBuilder.generateDefaultProvider(bfd.nameOfDefaultProvider, fieldNode, td.typarams, job); if (md != null) injectMethod(parent, md); } addObtainVia(bfd, fieldNode); @@ -787,15 +786,14 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { JavacTreeMaker maker = job.getTreeMaker(); List<JCAnnotation> annotations = List.nil(); JCAnnotation overrideAnnotation = override ? maker.Annotation(genJavaLangTypeRef(job.builderType, "Override"), List.<JCExpression>nil()) : null; - JCAnnotation rrAnnotation = job.checkerFramework.generateReturnsReceiver() ? maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil()) : null; JCAnnotation sefAnnotation = job.checkerFramework.generatePure() ? maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__PURE), List.<JCExpression>nil()) : null; if (sefAnnotation != null) annotations = annotations.prepend(sefAnnotation); - if (rrAnnotation != null) annotations = annotations.prepend(rrAnnotation); if (overrideAnnotation != null) annotations = annotations.prepend(overrideAnnotation); JCModifiers modifiers = maker.Modifiers(Flags.PROTECTED | Flags.ABSTRACT, annotations); Name name = job.toName(SELF_METHOD); JCExpression returnType = maker.Ident(job.toName(builderGenericName)); - + returnType = addCheckerFrameworkReturnsReceiver(returnType, maker, job.builderType, job.checkerFramework); + return maker.MethodDef(modifiers, name, returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null); } @@ -803,17 +801,16 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { JavacTreeMaker maker = job.getTreeMaker(); JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(job.builderType, "Override"), List.<JCExpression>nil()); - JCAnnotation rrAnnotation = job.checkerFramework.generateReturnsReceiver() ? maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil()) : null; JCAnnotation sefAnnotation = job.checkerFramework.generatePure() ? maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__PURE), List.<JCExpression>nil()) : null; List<JCAnnotation> annsOnMethod = List.nil(); if (sefAnnotation != null) annsOnMethod = annsOnMethod.prepend(sefAnnotation); - if (rrAnnotation != null) annsOnMethod = annsOnMethod.prepend(rrAnnotation); annsOnMethod = annsOnMethod.prepend(overrideAnnotation); JCModifiers modifiers = maker.Modifiers(Flags.PROTECTED, annsOnMethod); Name name = job.toName(SELF_METHOD); JCExpression returnType = namePlusTypeParamsToTypeReference(maker, job.builderType.up(), job.getBuilderClassName(), false, job.typeParams); + returnType = addCheckerFrameworkReturnsReceiver(returnType, maker, job.builderType, job.checkerFramework); JCStatement statement = maker.Return(maker.Ident(job.toName("this"))); JCBlock body = maker.Block(0, List.<JCStatement>of(statement)); @@ -962,23 +959,9 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { JavacTreeMaker maker = fieldNode.getTreeMaker(); List<JCAnnotation> methodAnns = JavacHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode); - JCMethodDecl newMethod = null; - if (job.checkerFramework.generateCalledMethods() && maker.hasMethodDefWithRecvParam()) { - JCAnnotation ncAnno = maker.Annotation(genTypeRef(job.sourceNode, CheckerFrameworkVersion.NAME__NOT_CALLED), List.<JCExpression>of(maker.Literal(setterName.toString()))); - JCClassDecl builderTypeNode = (JCClassDecl) job.builderType.get(); - JCExpression selfType = namePlusTypeParamsToTypeReference(maker, job.builderType, builderTypeNode.typarams, List.<JCAnnotation>of(ncAnno)); - JCVariableDecl recv = maker.VarDef(maker.Modifiers(0L, List.<JCAnnotation>nil()), job.toName("this"), selfType, null); - newMethod = HandleSetter.createSetterWithRecv(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, paramName, nameOfSetFlag, returnType, returnStatement, job.sourceNode, methodAnns, annosOnParam, recv); - } - if (newMethod == null) newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, paramName, nameOfSetFlag, returnType, returnStatement, job.sourceNode, methodAnns, annosOnParam); - if (job.checkerFramework.generateReturnsReceiver()) { - List<JCAnnotation> annotations = newMethod.mods.annotations; - if (annotations == null) annotations = List.nil(); - JCAnnotation anno = maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil()); - recursiveSetGeneratedBy(anno, job.sourceNode); - newMethod.mods.annotations = annotations.prepend(anno); - } - + returnType = addCheckerFrameworkReturnsReceiver(returnType, maker, job.builderType, job.checkerFramework); + + JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, paramName, nameOfSetFlag, returnType, returnStatement, job.sourceNode, methodAnns, annosOnParam); injectMethod(job.builderType, newMethod); } diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index 249993ee..8a0bc686 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.java @@ -65,7 +65,8 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { deleteAnnotationIfNeccessary(annotationNode, ToString.class); ToString ann = annotation.getInstance(); - java.util.List<Included<JavacNode, ToString.Include>> members = InclusionExclusionUtils.handleToStringMarking(annotationNode.up(), annotation, annotationNode); + boolean onlyExplicitlyIncluded = annotationNode.getAst().getBooleanAnnotationValue(annotation, "onlyExplicitlyIncluded", ConfigurationKeys.TO_STRING_ONLY_EXPLICITLY_INCLUDED); + java.util.List<Included<JavacNode, ToString.Include>> members = InclusionExclusionUtils.handleToStringMarking(annotationNode.up(), onlyExplicitlyIncluded, annotation, annotationNode); if (members == null) return; Boolean callSuper = ann.callSuper(); @@ -76,10 +77,9 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { boolean doNotUseGetters = annotation.isExplicit("doNotUseGetters") || doNotUseGettersConfiguration == null ? ann.doNotUseGetters() : doNotUseGettersConfiguration; FieldAccess fieldAccess = doNotUseGetters ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER; - Boolean fieldNamesConfiguration = annotationNode.getAst().readConfiguration(ConfigurationKeys.TO_STRING_INCLUDE_FIELD_NAMES); - boolean includeNames = annotation.isExplicit("includeFieldNames") || fieldNamesConfiguration == null ? ann.includeFieldNames() : fieldNamesConfiguration; + boolean includeFieldNames = annotationNode.getAst().getBooleanAnnotationValue(annotation, "includeFieldNames", ConfigurationKeys.TO_STRING_INCLUDE_FIELD_NAMES); - generateToString(annotationNode.up(), annotationNode, members, includeNames, callSuper, true, fieldAccess); + generateToString(annotationNode.up(), annotationNode, members, includeFieldNames, callSuper, true, fieldAccess); } public void generateToStringForType(JavacNode typeNode, JavacNode errorNode) { @@ -88,16 +88,14 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { return; } - boolean includeFieldNames = true; - try { - Boolean configuration = typeNode.getAst().readConfiguration(ConfigurationKeys.TO_STRING_INCLUDE_FIELD_NAMES); - includeFieldNames = configuration != null ? configuration : ((Boolean) ToString.class.getMethod("includeFieldNames").getDefaultValue()).booleanValue(); - } catch (Exception ignore) {} + AnnotationValues<ToString> anno = AnnotationValues.of(ToString.class); + boolean includeFieldNames = typeNode.getAst().getBooleanAnnotationValue(anno, "includeFieldNames", ConfigurationKeys.TO_STRING_INCLUDE_FIELD_NAMES); + boolean onlyExplicitlyIncluded = typeNode.getAst().getBooleanAnnotationValue(anno, "onlyExplicitlyIncluded", ConfigurationKeys.TO_STRING_ONLY_EXPLICITLY_INCLUDED); Boolean doNotUseGettersConfiguration = typeNode.getAst().readConfiguration(ConfigurationKeys.TO_STRING_DO_NOT_USE_GETTERS); FieldAccess access = doNotUseGettersConfiguration == null || !doNotUseGettersConfiguration ? FieldAccess.GETTER : FieldAccess.PREFER_FIELD; - java.util.List<Included<JavacNode, ToString.Include>> members = InclusionExclusionUtils.handleToStringMarking(typeNode, null, null); + java.util.List<Included<JavacNode, ToString.Include>> members = InclusionExclusionUtils.handleToStringMarking(typeNode, onlyExplicitlyIncluded, null, null); generateToString(typeNode, errorNode, members, includeFieldNames, null, false, access); } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index a41264e8..d3532f79 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1407,6 +1407,14 @@ public class JavacHandlerUtil { mods.annotations = mods.annotations.append(annotation); } + static JCExpression addCheckerFrameworkReturnsReceiver(JCExpression returnType, JavacTreeMaker maker, JavacNode typeNode, CheckerFrameworkVersion cfv) { + if (cfv.generateReturnsReceiver()) { + JCAnnotation rrAnnotation = maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil()); + returnType = maker.AnnotatedType(List.of(rrAnnotation), returnType); + } + return returnType; + } + private static List<JCTree> addAllButOne(List<JCTree> defs, int idx) { ListBuffer<JCTree> out = new ListBuffer<JCTree>(); int i = 0; @@ -1820,6 +1828,7 @@ public class JavacHandlerUtil { private static void clearTypes(JCTree tree) { tree.accept(new TreeScanner() { @Override public void scan(JCTree tree) { + if (tree == null) return; tree.type = null; super.scan(tree); } diff --git a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java index 77fcd4ea..4954a610 100644 --- a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java +++ b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java @@ -182,11 +182,10 @@ public class JavacSingularsRecipes { return this; } - protected JCModifiers makeMods(JavacTreeMaker maker, CheckerFrameworkVersion cfv, JavacNode node, boolean deprecate, AccessLevel access, List<JCAnnotation> methodAnnotations) { + protected JCModifiers makeMods(JavacTreeMaker maker, JavacNode node, boolean deprecate, AccessLevel access, List<JCAnnotation> methodAnnotations) { JCAnnotation deprecateAnn = deprecate ? maker.Annotation(genJavaLangTypeRef(node, "Deprecated"), List.<JCExpression>nil()) : null; - JCAnnotation rrAnn = cfv.generateReturnsReceiver() ? maker.Annotation(genTypeRef(node, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil()) : null; - List<JCAnnotation> annsOnMethod = (deprecateAnn != null && rrAnn != null) ? List.of(deprecateAnn, rrAnn) : deprecateAnn != null ? List.of(deprecateAnn) : rrAnn != null ? List.of(rrAnn) : List.<JCAnnotation>nil(); + List<JCAnnotation> annsOnMethod = (deprecateAnn != null) ? List.of(deprecateAnn) : List.<JCAnnotation>nil(); annsOnMethod = mergeAnnotations(annsOnMethod,methodAnnotations); return maker.Modifiers(toJavacModifier(access), annsOnMethod); } @@ -277,7 +276,7 @@ public class JavacSingularsRecipes { private void finishAndInjectMethod(CheckerFrameworkVersion cfv, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JavacNode source, boolean deprecate, ListBuffer<JCStatement> statements, Name methodName, List<JCVariableDecl> jcVariableDecls, List<JCAnnotation> methodAnnotations, AccessLevel access, Boolean ignoreNullCollections) { if (returnStatement != null) statements.append(returnStatement); JCBlock body = maker.Block(0, statements.toList()); - JCModifiers mods = makeMods(maker, cfv, builderType, deprecate, access, methodAnnotations); + JCModifiers mods = makeMods(maker, builderType, deprecate, access, methodAnnotations); List<JCTypeParameter> typeParams = List.nil(); List<JCExpression> thrown = List.nil(); @@ -289,6 +288,7 @@ public class JavacSingularsRecipes { } } + returnType = addCheckerFrameworkReturnsReceiver(returnType, maker, builderType, cfv); JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, jcVariableDecls, thrown, body, null); if (returnStatement != null) createRelevantNonNullAnnotation(builderType, method); recursiveSetGeneratedBy(method, source); diff --git a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java index ce5aad5e..808b794a 100644 --- a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java +++ b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java @@ -52,7 +52,7 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer { } @Override protected String getEmptyMaker(String target) { - return target + ".of"; + return "com.google.common.collect." + GuavaTypeMap.getGuavaTypeName(target) + ".of"; } protected String getBuilderMethodName(SingularData data) { diff --git a/src/delombok/lombok/delombok/DocCommentIntegrator.java b/src/delombok/lombok/delombok/DocCommentIntegrator.java index e61968a5..945f4fa4 100644 --- a/src/delombok/lombok/delombok/DocCommentIntegrator.java +++ b/src/delombok/lombok/delombok/DocCommentIntegrator.java @@ -78,7 +78,7 @@ public class DocCommentIntegrator { @SuppressWarnings("unchecked") private boolean attach(JCCompilationUnit top, final JCTree node, CommentInfo cmt) { String docCommentContent = cmt.content; if (docCommentContent.startsWith("/**")) docCommentContent = docCommentContent.substring(3); - if (docCommentContent.endsWith("*/")) docCommentContent = docCommentContent.substring(0, docCommentContent.length() -2); + if (docCommentContent.endsWith("*/")) docCommentContent = docCommentContent.substring(0, docCommentContent.length() - 2); docCommentContent = CONTENT_STRIPPER.matcher(docCommentContent).replaceAll("$1"); docCommentContent = docCommentContent.trim(); diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index 06e10960..2e35cf57 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -59,7 +59,10 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { sm.registerTransformer(instrumentation); sm.setFilter(new Filter() { @Override public boolean shouldTransform(ClassLoader loader, String className, Class<?> classBeingDefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { - if (loader != null && loader.getClass().getName().startsWith("org.sonar.classloader.")) return false; // Relevant to bug #2351 + if (loader != null) { + if (loader.getClass().getName().startsWith("org.sonar.classloader.")) return false; // Relevant to bug #2351 + if (loader.toString().contains("com.alexnederlof:jasperreports-plugin")) return false; //Relevant to bug #1036 + } if (!(loader instanceof URLClassLoader)) return true; ClassLoader parent = loader.getParent(); if (parent == null) return true; @@ -95,6 +98,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { patchEclipseDebugPatches(sm); patchJavadoc(sm); patchASTConverterLiterals(sm); + patchASTNodeSearchUtil(sm); patchPostCompileHookEcj(sm); @@ -174,17 +178,6 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .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()); - /* Do not add @Override's for generated methods */ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.exitEarly() .target(new MethodTarget("org.eclipse.jdt.core.dom.rewrite.ListRewrite", "insertFirst")) @@ -995,5 +988,18 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .transplant() .build()); } + + private static void patchASTNodeSearchUtil(ScriptManager sm) { + /* + * If an annotation generates more than one method the normal node search returns one of them instead of the right one. + * This patch method also compares method name and method parameter types to identify the right method. + */ + sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapReturnValue() + .target(new MethodTarget("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")) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "getRealMethodDeclarationNode", "org.eclipse.jdt.core.dom.MethodDeclaration", "org.eclipse.jdt.core.dom.MethodDeclaration", "org.eclipse.jdt.core.IMethod", "org.eclipse.jdt.core.dom.CompilationUnit")) + .request(StackRequest.RETURN_VALUE, StackRequest.PARAM1, StackRequest.PARAM2) + .transplant() + .build()); + } } diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java index e758979d..976a71f4 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java @@ -359,7 +359,8 @@ public class PatchVal { newAnn = new Annotation[1]; } - newAnn[newAnn.length - 1] = new org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation(originalRef, originalRef.sourceStart); + TypeReference qualifiedTypeRef = generateQualifiedTypeRef(originalRef, originalRef.getTypeName()); + newAnn[newAnn.length - 1] = new org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation(qualifiedTypeRef, qualifiedTypeRef.sourceStart); return newAnn; } diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index 63bb3747..e0c330a2 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -39,8 +39,8 @@ import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.search.SearchMatch; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; @@ -56,7 +56,6 @@ import org.eclipse.jdt.internal.core.dom.rewrite.NodeRewriteEvent; 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; @@ -540,35 +539,52 @@ final class PatchFixesHider { } } - public static org.eclipse.jdt.core.dom.MethodDeclaration getRealMethodDeclarationNode(org.eclipse.jdt.core.IMethod sourceMethod, org.eclipse.jdt.core.dom.CompilationUnit cuUnit) throws JavaModelException { - MethodDeclaration methodDeclarationNode = ASTNodeSearchUtil.getMethodDeclarationNode(sourceMethod, cuUnit); - if (isGenerated(methodDeclarationNode)) { - IType declaringType = sourceMethod.getDeclaringType(); - Stack<IType> typeStack = new Stack<IType>(); - while (declaringType != null) { - typeStack.push(declaringType); - declaringType = declaringType.getDeclaringType(); - } - - IType rootType = typeStack.pop(); - org.eclipse.jdt.core.dom.AbstractTypeDeclaration typeDeclaration = findTypeDeclaration(rootType, cuUnit.types()); - while (!typeStack.isEmpty() && typeDeclaration != null) { - typeDeclaration = findTypeDeclaration(typeStack.pop(), typeDeclaration.bodyDeclarations()); - } - - if (typeStack.isEmpty() && typeDeclaration != null) { - String methodName = sourceMethod.getElementName(); - for (Object declaration : typeDeclaration.bodyDeclarations()) { - if (declaration instanceof org.eclipse.jdt.core.dom.MethodDeclaration) { - org.eclipse.jdt.core.dom.MethodDeclaration methodDeclaration = (org.eclipse.jdt.core.dom.MethodDeclaration) declaration; - if (methodDeclaration.getName().toString().equals(methodName)) { - return methodDeclaration; + public static org.eclipse.jdt.core.dom.MethodDeclaration getRealMethodDeclarationNode(org.eclipse.jdt.core.dom.MethodDeclaration original, org.eclipse.jdt.core.IMethod sourceMethod, org.eclipse.jdt.core.dom.CompilationUnit cuUnit) throws JavaModelException { + if (!isGenerated(original)) return original; + + IType declaringType = sourceMethod.getDeclaringType(); + Stack<IType> typeStack = new Stack<IType>(); + while (declaringType != null) { + typeStack.push(declaringType); + declaringType = declaringType.getDeclaringType(); + } + + IType rootType = typeStack.pop(); + org.eclipse.jdt.core.dom.AbstractTypeDeclaration typeDeclaration = findTypeDeclaration(rootType, cuUnit.types()); + while (!typeStack.isEmpty() && typeDeclaration != null) { + typeDeclaration = findTypeDeclaration(typeStack.pop(), typeDeclaration.bodyDeclarations()); + } + + String targetMethodName = sourceMethod.getElementName(); + List<String> targetMethodParameterTypes = new ArrayList<String>(); + for (String parameterType : sourceMethod.getParameterTypes()) { + targetMethodParameterTypes.add(org.eclipse.jdt.core.Signature.toString(parameterType)); + } + + if (typeStack.isEmpty() && typeDeclaration != null) { + for (Object declaration : typeDeclaration.bodyDeclarations()) { + if (declaration instanceof org.eclipse.jdt.core.dom.MethodDeclaration) { + org.eclipse.jdt.core.dom.MethodDeclaration methodDeclaration = (org.eclipse.jdt.core.dom.MethodDeclaration) declaration; + + if (!methodDeclaration.getName().toString().equals(targetMethodName)) continue; + if (methodDeclaration.parameters().size() != targetMethodParameterTypes.size()) continue; + if (!isGenerated(methodDeclaration)) continue; + + boolean parameterTypesEquals = true; + for (int i = 0; i < methodDeclaration.parameters().size(); i++) { + SingleVariableDeclaration variableDeclaration = (SingleVariableDeclaration) methodDeclaration.parameters().get(i); + if (!variableDeclaration.getType().toString().equals(targetMethodParameterTypes.get(i))) { + parameterTypesEquals = false; + break; } } + if (parameterTypesEquals) { + return methodDeclaration; + } } } } - return methodDeclarationNode; + return original; } // part of getRealMethodDeclarationNode diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index 3fa0fbb5..5a6165b1 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -392,6 +392,7 @@ public class Javac { public static void storeEnd(JCTree tree, int pos, JCCompilationUnit top) { try { Object endPositions = JCCOMPILATIONUNIT_ENDPOSITIONS.get(top); + if (endPositions == null) return; storeEnd.invoke(endPositions, tree, pos); } catch (IllegalAccessException e) { throw sneakyThrow(e); |