aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/ConfigurationKeys.java4
-rwxr-xr-x[-rw-r--r--]src/core/lombok/core/AST.java28
-rw-r--r--src/core/lombok/core/handlers/HandlerUtil.java226
-rw-r--r--src/core/lombok/eclipse/EclipseAST.java90
-rw-r--r--src/core/lombok/eclipse/EclipseASTAdapter.java12
-rw-r--r--src/core/lombok/eclipse/EclipseASTVisitor.java24
-rw-r--r--src/core/lombok/eclipse/EclipseNode.java11
-rw-r--r--src/core/lombok/eclipse/TransformEclipseAST.java8
-rwxr-xr-x[-rw-r--r--]src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java2
-rwxr-xr-x[-rw-r--r--]src/core/lombok/eclipse/handlers/HandleBuilder.java19
-rwxr-xr-x[-rw-r--r--]src/core/lombok/eclipse/handlers/HandleConstructor.java8
-rwxr-xr-x[-rw-r--r--]src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java4
-rw-r--r--src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java40
-rwxr-xr-x[-rw-r--r--]src/core/lombok/eclipse/handlers/HandleHelper.java2
-rw-r--r--src/core/lombok/eclipse/handlers/HandleNonNull.java39
-rwxr-xr-x[-rw-r--r--]src/core/lombok/eclipse/handlers/HandleSuperBuilder.java8
-rwxr-xr-x[-rw-r--r--]src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java4
-rwxr-xr-x[-rw-r--r--]src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java4
-rwxr-xr-x[-rw-r--r--]src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java2
-rwxr-xr-x[-rw-r--r--]src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java4
-rwxr-xr-x[-rw-r--r--]src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSingularizer.java2
-rw-r--r--src/core/lombok/javac/JavacAST.java75
-rw-r--r--src/core/lombok/javac/JavacASTAdapter.java11
-rw-r--r--src/core/lombok/javac/JavacASTVisitor.java24
-rw-r--r--src/core/lombok/javac/JavacNode.java10
-rw-r--r--src/core/lombok/javac/JavacTransformer.java6
-rw-r--r--src/core/lombok/javac/apt/EmptyLombokFileObject.java123
-rw-r--r--src/core/lombok/javac/apt/InterceptingJavaFileManager.java7
-rw-r--r--src/core/lombok/javac/apt/LombokFileObjects.java10
-rw-r--r--src/core/lombok/javac/apt/LombokProcessor.java20
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java22
-rwxr-xr-x[-rw-r--r--]src/core/lombok/javac/handlers/HandleHelper.java2
-rw-r--r--src/core/lombok/javac/handlers/HandleNonNull.java24
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java2
-rwxr-xr-x[-rw-r--r--]src/delombok/lombok/delombok/Delombok.java2
-rw-r--r--src/delombok/lombok/delombok/PrettyPrinter.java97
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java6
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchDiagnostics.java11
-rwxr-xr-x[-rw-r--r--]src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java2
-rwxr-xr-x[-rw-r--r--]src/eclipseAgent/lombok/launch/PatchFixesHider.java18
-rw-r--r--src/utils/lombok/permit/Permit.java37
41 files changed, 748 insertions, 302 deletions
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java
index dfcb3e33..2b406dbe 100644
--- a/src/core/lombok/ConfigurationKeys.java
+++ b/src/core/lombok/ConfigurationKeys.java
@@ -83,7 +83,7 @@ public class ConfigurationKeys {
*
* NB: If you enable this option, findbugs must be on the source or classpath, or you'll get errors that the type {@code SuppressFBWarnings} cannot be found.
*/
- public static final ConfigurationKey<Boolean> ADD_FINDBUGS_SUPPRESSWARNINGS_ANNOTATIONS = new ConfigurationKey<Boolean>("lombok.extern.findbugs.addSuppressFBWarnings", "Generate @edu.umd.cs.findbugs.annotations.SuppressFBWArnings on all generated code (default: false).") {};
+ public static final ConfigurationKey<Boolean> ADD_FINDBUGS_SUPPRESSWARNINGS_ANNOTATIONS = new ConfigurationKey<Boolean>("lombok.extern.findbugs.addSuppressFBWarnings", "Generate @edu.umd.cs.findbugs.annotations.SuppressFBWarnings on all generated code (default: false).") {};
// ----- *ArgsConstructor -----
@@ -138,7 +138,7 @@ public class ConfigurationKeys {
*
* If {@code true} (default), @Data and @Value will also generate a private no-args constructor, if there isn't already one, setting all fields to their default values.
*/
- public static final ConfigurationKey<Boolean> NO_ARGS_CONSTRUCTOR_EXTRA_PRIVATE = new ConfigurationKey<Boolean>("lombok.noArgsConstructor.extraPrivate", "Generate a private no-ars constructor for @Data and @Value (default: true).") {};
+ public static final ConfigurationKey<Boolean> NO_ARGS_CONSTRUCTOR_EXTRA_PRIVATE = new ConfigurationKey<Boolean>("lombok.noArgsConstructor.extraPrivate", "Generate a private no-args constructor for @Data and @Value (default: true).") {};
/**
* lombok configuration: {@code lombok.requiredArgsConstructor.flagUsage} = {@code WARNING} | {@code ERROR}.
diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java
index afbba1e8..78761f46 100644..100755
--- a/src/core/lombok/core/AST.java
+++ b/src/core/lombok/core/AST.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2016 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 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
@@ -53,7 +53,7 @@ import lombok.permit.Permit;
public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>, N> {
/** The kind of node represented by a given AST.Node object. */
public enum Kind {
- COMPILATION_UNIT, TYPE, FIELD, INITIALIZER, METHOD, ANNOTATION, ARGUMENT, LOCAL, STATEMENT;
+ COMPILATION_UNIT, TYPE, FIELD, INITIALIZER, METHOD, ANNOTATION, ARGUMENT, LOCAL, STATEMENT, TYPE_USE;
}
private L top;
@@ -229,7 +229,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
List<FieldAccess> fieldList = new ArrayList<FieldAccess>();
getFields(c, fieldList);
- fieldsOfASTClasses.putIfAbsent(c, fieldList.toArray(new FieldAccess[fieldList.size()]));
+ fieldsOfASTClasses.putIfAbsent(c, fieldList.toArray(new FieldAccess[0]));
return fieldsOfASTClasses.get(c);
}
@@ -263,8 +263,8 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
private Class<?> getComponentType(Type type) {
if (type instanceof ParameterizedType) {
- Type component = ((ParameterizedType)type).getActualTypeArguments()[0];
- return component instanceof Class<?> ? (Class<?>)component : Object.class;
+ Type component = ((ParameterizedType) type).getActualTypeArguments()[0];
+ return component instanceof Class<?> ? (Class<?>) component : Object.class;
}
return Object.class;
}
@@ -330,7 +330,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
idx++;
if (o == null) continue;
if (Collection.class.isInstance(o)) {
- Collection<?> newC = (Collection<?>)o;
+ Collection<?> newC = (Collection<?>) o;
List<Collection<?>> newChain = new ArrayList<Collection<?>>(chain);
newChain.add(newC);
if (replaceStatementInCollection(field, fieldRef, newChain, newC, oldN, newN)) return true;
@@ -356,7 +356,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
@SuppressWarnings({"rawtypes", "unchecked"})
protected void setElementInASTCollection(Field field, Object fieldRef, List<Collection<?>> chain, Collection<?> collection, int idx, N newN) throws IllegalAccessException {
if (collection instanceof List<?>) {
- ((List)collection).set(idx, newN);
+ ((List) collection).set(idx, newN);
}
}
@@ -384,7 +384,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
Object o = fa.field.get(child);
if (o == null) return;
if (fa.dim == 0) {
- L node = buildTree((N)o, Kind.STATEMENT);
+ L node = buildTree((N) o, Kind.STATEMENT);
if (node != null) list.add(nodeType.cast(node));
} else if (o.getClass().isArray()) {
buildWithArray(nodeType, o, list, fa.dim);
@@ -399,12 +399,12 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
@SuppressWarnings("unchecked")
private void buildWithArray(Class<L> nodeType, Object array, Collection<L> list, int dim) {
if (dim == 1) {
- for (Object v : (Object[])array) {
+ for (Object v : (Object[]) array) {
if (v == null) continue;
L node = buildTree((N)v, Kind.STATEMENT);
if (node != null) list.add(nodeType.cast(node));
}
- } else for (Object v : (Object[])array) {
+ } else for (Object v : (Object[]) array) {
if (v == null) return;
buildWithArray(nodeType, v, list, dim -1);
}
@@ -413,13 +413,13 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
@SuppressWarnings("unchecked")
private void buildWithCollection(Class<L> nodeType, Object collection, Collection<L> list, int dim) {
if (dim == 1) {
- for (Object v : (Collection<?>)collection) {
+ for (Object v : (Collection<?>) collection) {
if (v == null) continue;
- L node = buildTree((N)v, Kind.STATEMENT);
+ L node = buildTree((N) v, Kind.STATEMENT);
if (node != null) list.add(nodeType.cast(node));
}
- } else for (Object v : (Collection<?>)collection) {
- buildWithCollection(nodeType, v, list, dim-1);
+ } else for (Object v : (Collection<?>) collection) {
+ buildWithCollection(nodeType, v, list, dim - 1);
}
}
diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java
index ac91447d..1a92b5f6 100644
--- a/src/core/lombok/core/handlers/HandlerUtil.java
+++ b/src/core/lombok/core/handlers/HandlerUtil.java
@@ -79,29 +79,225 @@ public class HandlerUtil {
public static final List<String> NONNULL_ANNOTATIONS, BASE_COPYABLE_ANNOTATIONS;
static {
NONNULL_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] {
- "lombok.NonNull",
- "javax.annotation.Nonnull",
- "edu.umd.cs.findbugs.annotations.NonNull",
- "org.jetbrains.annotations.NotNull",
+ "android.annotation.NonNull",
"android.support.annotation.NonNull",
+ "com.sun.istack.internal.NotNull",
+ "edu.umd.cs.findbugs.annotations.NonNull",
+ "javax.annotation.Nonnull",
+ // The field might contain a null value until it is persisted.
+ // "javax.validation.constraints.NotNull",
+ "lombok.NonNull",
+ "org.checkerframework.checker.nullness.qual.NonNull",
"org.eclipse.jdt.annotation.NonNull",
+ "org.eclipse.jgit.annotations.NonNull",
+ "org.jetbrains.annotations.NotNull",
+ "org.jmlspecs.annotation.NonNull",
+ "org.netbeans.api.annotations.common.NonNull",
"org.springframework.lang.NonNull"
}));
BASE_COPYABLE_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] {
- "lombok.NonNull",
- "javax.annotation.Nonnull",
- "edu.umd.cs.findbugs.annotations.NonNull",
- "org.jetbrains.annotations.NotNull",
"android.support.annotation.NonNull",
- "org.eclipse.jdt.annotation.NonNull",
- "org.springframework.lang.NonNull",
- "javax.annotation.Nullable",
- "javax.annotation.CheckForNull",
- "edu.umd.cs.findbugs.annotations.UnknownNullness",
- "edu.umd.cs.findbugs.annotations.Nullable",
- "org.jetbrains.annotations.Nullable",
"android.support.annotation.Nullable",
+ "edu.umd.cs.findbugs.annotations.NonNull",
+ "edu.umd.cs.findbugs.annotations.Nullable",
+ "edu.umd.cs.findbugs.annotations.UnknownNullness",
+ "javax.annotation.CheckForNull",
+ "javax.annotation.Nonnull",
+ "javax.annotation.Nullable",
+ "lombok.NonNull",
+ // To update Checker Framework annotations, run:
+ // grep --recursive --files-with-matches -e '^@Target\b.*TYPE_USE' $CHECKERFRAMEWORK/checker/src/main/java $CHECKERFRAMEWORK/framework/src/main/java | grep '\.java$' | sed 's/.*\/java\//\t\t\t"/' | sed 's/\.java$/",/' | sed 's/\//./g' | sort
+ "org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey",
+ "org.checkerframework.checker.compilermsgs.qual.CompilerMessageKeyBottom",
+ "org.checkerframework.checker.compilermsgs.qual.UnknownCompilerMessageKey",
+ "org.checkerframework.checker.fenum.qual.AwtAlphaCompositingRule",
+ "org.checkerframework.checker.fenum.qual.AwtColorSpace",
+ "org.checkerframework.checker.fenum.qual.AwtCursorType",
+ "org.checkerframework.checker.fenum.qual.AwtFlowLayout",
+ "org.checkerframework.checker.fenum.qual.Fenum",
+ "org.checkerframework.checker.fenum.qual.FenumBottom",
+ "org.checkerframework.checker.fenum.qual.FenumTop",
+ "org.checkerframework.checker.fenum.qual.PolyFenum",
+ "org.checkerframework.checker.fenum.qual.SwingBoxOrientation",
+ "org.checkerframework.checker.fenum.qual.SwingCompassDirection",
+ "org.checkerframework.checker.fenum.qual.SwingElementOrientation",
+ "org.checkerframework.checker.fenum.qual.SwingHorizontalOrientation",
+ "org.checkerframework.checker.fenum.qual.SwingSplitPaneOrientation",
+ "org.checkerframework.checker.fenum.qual.SwingTextOrientation",
+ "org.checkerframework.checker.fenum.qual.SwingTitleJustification",
+ "org.checkerframework.checker.fenum.qual.SwingTitlePosition",
+ "org.checkerframework.checker.fenum.qual.SwingVerticalOrientation",
+ "org.checkerframework.checker.formatter.qual.Format",
+ "org.checkerframework.checker.formatter.qual.FormatBottom",
+ "org.checkerframework.checker.formatter.qual.InvalidFormat",
+ "org.checkerframework.checker.guieffect.qual.AlwaysSafe",
+ "org.checkerframework.checker.guieffect.qual.PolyUI",
+ "org.checkerframework.checker.guieffect.qual.UI",
+ "org.checkerframework.checker.i18nformatter.qual.I18nFormat",
+ "org.checkerframework.checker.i18nformatter.qual.I18nFormatBottom",
+ "org.checkerframework.checker.i18nformatter.qual.I18nFormatFor",
+ "org.checkerframework.checker.i18nformatter.qual.I18nInvalidFormat",
+ "org.checkerframework.checker.i18nformatter.qual.I18nUnknownFormat",
+ "org.checkerframework.checker.i18n.qual.LocalizableKey",
+ "org.checkerframework.checker.i18n.qual.LocalizableKeyBottom",
+ "org.checkerframework.checker.i18n.qual.Localized",
+ "org.checkerframework.checker.i18n.qual.UnknownLocalizableKey",
+ "org.checkerframework.checker.i18n.qual.UnknownLocalized",
+ "org.checkerframework.checker.index.qual.GTENegativeOne",
+ "org.checkerframework.checker.index.qual.IndexFor",
+ "org.checkerframework.checker.index.qual.IndexOrHigh",
+ "org.checkerframework.checker.index.qual.IndexOrLow",
+ "org.checkerframework.checker.index.qual.LengthOf",
+ "org.checkerframework.checker.index.qual.LessThan",
+ "org.checkerframework.checker.index.qual.LessThanBottom",
+ "org.checkerframework.checker.index.qual.LessThanUnknown",
+ "org.checkerframework.checker.index.qual.LowerBoundBottom",
+ "org.checkerframework.checker.index.qual.LowerBoundUnknown",
+ "org.checkerframework.checker.index.qual.LTEqLengthOf",
+ "org.checkerframework.checker.index.qual.LTLengthOf",
+ "org.checkerframework.checker.index.qual.LTOMLengthOf",
+ "org.checkerframework.checker.index.qual.NegativeIndexFor",
+ "org.checkerframework.checker.index.qual.NonNegative",
+ "org.checkerframework.checker.index.qual.PolyIndex",
+ "org.checkerframework.checker.index.qual.PolyLength",
+ "org.checkerframework.checker.index.qual.PolyLowerBound",
+ "org.checkerframework.checker.index.qual.PolySameLen",
+ "org.checkerframework.checker.index.qual.PolyUpperBound",
+ "org.checkerframework.checker.index.qual.Positive",
+ "org.checkerframework.checker.index.qual.SameLen",
+ "org.checkerframework.checker.index.qual.SameLenBottom",
+ "org.checkerframework.checker.index.qual.SameLenUnknown",
+ "org.checkerframework.checker.index.qual.SearchIndexBottom",
+ "org.checkerframework.checker.index.qual.SearchIndexFor",
+ "org.checkerframework.checker.index.qual.SearchIndexUnknown",
+ "org.checkerframework.checker.index.qual.SubstringIndexBottom",
+ "org.checkerframework.checker.index.qual.SubstringIndexFor",
+ "org.checkerframework.checker.index.qual.SubstringIndexUnknown",
+ "org.checkerframework.checker.index.qual.UpperBoundBottom",
+ "org.checkerframework.checker.index.qual.UpperBoundUnknown",
+ "org.checkerframework.checker.initialization.qual.FBCBottom",
+ "org.checkerframework.checker.initialization.qual.Initialized",
+ "org.checkerframework.checker.initialization.qual.UnderInitialization",
+ "org.checkerframework.checker.initialization.qual.UnknownInitialization",
+ "org.checkerframework.checker.interning.qual.Interned",
+ "org.checkerframework.checker.interning.qual.InternedDistinct",
+ "org.checkerframework.checker.interning.qual.PolyInterned",
+ "org.checkerframework.checker.interning.qual.UnknownInterned",
+ "org.checkerframework.checker.lock.qual.GuardedBy",
+ "org.checkerframework.checker.lock.qual.GuardedByBottom",
+ "org.checkerframework.checker.lock.qual.GuardedByUnknown",
+ "org.checkerframework.checker.lock.qual.GuardSatisfied",
+ "org.checkerframework.checker.nullness.qual.KeyFor",
+ "org.checkerframework.checker.nullness.qual.KeyForBottom",
+ "org.checkerframework.checker.nullness.qual.MonotonicNonNull",
+ "org.checkerframework.checker.nullness.qual.NonNull",
+ "org.checkerframework.checker.nullness.qual.NonRaw",
+ "org.checkerframework.checker.nullness.qual.Nullable",
+ "org.checkerframework.checker.nullness.qual.PolyKeyFor",
+ "org.checkerframework.checker.nullness.qual.PolyNull",
+ "org.checkerframework.checker.nullness.qual.PolyRaw",
+ "org.checkerframework.checker.nullness.qual.Raw",
+ "org.checkerframework.checker.nullness.qual.UnknownKeyFor",
+ "org.checkerframework.checker.optional.qual.MaybePresent",
+ "org.checkerframework.checker.optional.qual.PolyPresent",
+ "org.checkerframework.checker.optional.qual.Present",
+ "org.checkerframework.checker.propkey.qual.PropertyKey",
+ "org.checkerframework.checker.propkey.qual.PropertyKeyBottom",
+ "org.checkerframework.checker.propkey.qual.UnknownPropertyKey",
+ "org.checkerframework.checker.regex.qual.PolyRegex",
+ "org.checkerframework.checker.regex.qual.Regex",
+ "org.checkerframework.checker.regex.qual.RegexBottom",
+ "org.checkerframework.checker.regex.qual.UnknownRegex",
+ "org.checkerframework.checker.signature.qual.BinaryName",
+ "org.checkerframework.checker.signature.qual.BinaryNameInUnnamedPackage",
+ "org.checkerframework.checker.signature.qual.ClassGetName",
+ "org.checkerframework.checker.signature.qual.ClassGetSimpleName",
+ "org.checkerframework.checker.signature.qual.DotSeparatedIdentifiers",
+ "org.checkerframework.checker.signature.qual.FieldDescriptor",
+ "org.checkerframework.checker.signature.qual.FieldDescriptorForPrimitive",
+ "org.checkerframework.checker.signature.qual.FieldDescriptorForPrimitiveOrArrayInUnnamedPackage",
+ "org.checkerframework.checker.signature.qual.FullyQualifiedName",
+ "org.checkerframework.checker.signature.qual.Identifier",
+ "org.checkerframework.checker.signature.qual.IdentifierOrArray",
+ "org.checkerframework.checker.signature.qual.InternalForm",
+ "org.checkerframework.checker.signature.qual.MethodDescriptor",
+ "org.checkerframework.checker.signature.qual.PolySignature",
+ "org.checkerframework.checker.signature.qual.SignatureBottom",
+ "org.checkerframework.checker.signedness.qual.Constant",
+ "org.checkerframework.checker.signedness.qual.PolySignedness",
+ "org.checkerframework.checker.signedness.qual.Signed",
+ "org.checkerframework.checker.signedness.qual.SignednessBottom",
+ "org.checkerframework.checker.signedness.qual.UnknownSignedness",
+ "org.checkerframework.checker.signedness.qual.Unsigned",
+ "org.checkerframework.checker.tainting.qual.PolyTainted",
+ "org.checkerframework.checker.tainting.qual.Tainted",
+ "org.checkerframework.checker.tainting.qual.Untainted",
+ "org.checkerframework.checker.units.qual.A",
+ "org.checkerframework.checker.units.qual.Acceleration",
+ "org.checkerframework.checker.units.qual.Angle",
+ "org.checkerframework.checker.units.qual.Area",
+ "org.checkerframework.checker.units.qual.C",
+ "org.checkerframework.checker.units.qual.cd",
+ "org.checkerframework.checker.units.qual.Current",
+ "org.checkerframework.checker.units.qual.degrees",
+ "org.checkerframework.checker.units.qual.g",
+ "org.checkerframework.checker.units.qual.h",
+ "org.checkerframework.checker.units.qual.K",
+ "org.checkerframework.checker.units.qual.kg",
+ "org.checkerframework.checker.units.qual.km",
+ "org.checkerframework.checker.units.qual.km2",
+ "org.checkerframework.checker.units.qual.kmPERh",
+ "org.checkerframework.checker.units.qual.Length",
+ "org.checkerframework.checker.units.qual.Luminance",
+ "org.checkerframework.checker.units.qual.m",
+ "org.checkerframework.checker.units.qual.m2",
+ "org.checkerframework.checker.units.qual.Mass",
+ "org.checkerframework.checker.units.qual.min",
+ "org.checkerframework.checker.units.qual.mm",
+ "org.checkerframework.checker.units.qual.mm2",
+ "org.checkerframework.checker.units.qual.mol",
+ "org.checkerframework.checker.units.qual.mPERs",
+ "org.checkerframework.checker.units.qual.mPERs2",
+ "org.checkerframework.checker.units.qual.PolyUnit",
+ "org.checkerframework.checker.units.qual.radians",
+ "org.checkerframework.checker.units.qual.s",
+ "org.checkerframework.checker.units.qual.Speed",
+ "org.checkerframework.checker.units.qual.Substance",
+ "org.checkerframework.checker.units.qual.Temperature",
+ "org.checkerframework.checker.units.qual.Time",
+ "org.checkerframework.checker.units.qual.UnitsBottom",
+ "org.checkerframework.checker.units.qual.UnknownUnits",
+ "org.checkerframework.common.aliasing.qual.LeakedToResult",
+ "org.checkerframework.common.aliasing.qual.MaybeAliased",
+ "org.checkerframework.common.aliasing.qual.NonLeaked",
+ "org.checkerframework.common.aliasing.qual.Unique",
+ "org.checkerframework.common.reflection.qual.ClassBound",
+ "org.checkerframework.common.reflection.qual.ClassVal",
+ "org.checkerframework.common.reflection.qual.ClassValBottom",
+ "org.checkerframework.common.reflection.qual.MethodVal",
+ "org.checkerframework.common.reflection.qual.MethodValBottom",
+ "org.checkerframework.common.reflection.qual.UnknownClass",
+ "org.checkerframework.common.reflection.qual.UnknownMethod",
+ "org.checkerframework.common.subtyping.qual.Bottom",
+ "org.checkerframework.common.util.report.qual.ReportUnqualified",
+ "org.checkerframework.common.value.qual.ArrayLen",
+ "org.checkerframework.common.value.qual.ArrayLenRange",
+ "org.checkerframework.common.value.qual.BoolVal",
+ "org.checkerframework.common.value.qual.BottomVal",
+ "org.checkerframework.common.value.qual.DoubleVal",
+ "org.checkerframework.common.value.qual.IntRange",
+ "org.checkerframework.common.value.qual.IntVal",
+ "org.checkerframework.common.value.qual.MinLen",
+ "org.checkerframework.common.value.qual.PolyValue",
+ "org.checkerframework.common.value.qual.StringVal",
+ "org.checkerframework.common.value.qual.UnknownVal",
+ "org.checkerframework.framework.qual.PolyAll",
+ "org.checkerframework.framework.util.PurityUnqualified",
+ "org.eclipse.jdt.annotation.NonNull",
"org.eclipse.jdt.annotation.Nullable",
+ "org.jetbrains.annotations.NotNull",
+ "org.jetbrains.annotations.Nullable",
+ "org.springframework.lang.NonNull",
"org.springframework.lang.Nullable"
}));
}
diff --git a/src/core/lombok/eclipse/EclipseAST.java b/src/core/lombok/eclipse/EclipseAST.java
index 1ba26338..e724fb50 100644
--- a/src/core/lombok/eclipse/EclipseAST.java
+++ b/src/core/lombok/eclipse/EclipseAST.java
@@ -22,6 +22,7 @@
package lombok.eclipse;
import java.io.File;
+import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
@@ -49,8 +50,12 @@ import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
import org.eclipse.jdt.internal.compiler.ast.Initializer;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
/**
* Wraps around Eclipse's internal AST view to add useful features as well as the ability to visit parents from children,
@@ -292,7 +297,7 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> {
throw Lombok.sneakyThrow(e);
} catch (NullPointerException e) {
if (!"false".equals(System.getProperty("lombok.debug.reflection", "false"))) {
- e.initCause(EcjReflectionCheck.problem);
+ e.initCause(EcjReflectionCheck.problemAddProblemToCompilationResult);
throw e;
}
//ignore, we don't have access to the correct ECJ classes, so lombok can't possibly
@@ -300,6 +305,25 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> {
}
}
+ public static Annotation[] getTopLevelTypeReferenceAnnotations(TypeReference tr) {
+ Method m = EcjReflectionCheck.typeReferenceGetAnnotationsOnDimensions;
+ if (m == null) return null;
+ Annotation[][] annss = null;
+ try {
+ annss = (Annotation[][]) m.invoke(tr);
+ if (annss != null) return annss[0];
+ } catch (Throwable ignore) {}
+
+ try {
+ Field f = EcjReflectionCheck.typeReferenceAnnotations;
+ if (f == null) return null;
+ annss = (Annotation[][]) f.get(tr);
+ return annss[annss.length - 1];
+ } catch (Throwable t) {
+ return null;
+ }
+ }
+
private final CompilationUnitDeclaration compilationUnitDeclaration;
private boolean completeParse;
@@ -350,6 +374,8 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> {
return buildStatement((Statement) node);
case ANNOTATION:
return buildAnnotation((Annotation) node, false);
+ case TYPE_USE:
+ return buildTypeUse((TypeReference) node);
default:
throw new AssertionError("Did not expect to arrive here: " + kind);
}
@@ -397,6 +423,7 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> {
if (field instanceof Initializer) return buildInitializer((Initializer)field);
if (setAndGetAsHandled(field)) return null;
List<EclipseNode> childNodes = new ArrayList<EclipseNode>();
+ addIfNotNull(childNodes, buildTypeUse(field.type));
addIfNotNull(childNodes, buildStatement(field.initialization));
childNodes.addAll(buildAnnotations(field.annotations, true));
return putInMap(new EclipseNode(this, field, childNodes, Kind.FIELD));
@@ -438,11 +465,40 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> {
private EclipseNode buildLocal(LocalDeclaration local, Kind kind) {
if (setAndGetAsHandled(local)) return null;
List<EclipseNode> childNodes = new ArrayList<EclipseNode>();
+ addIfNotNull(childNodes, buildTypeUse(local.type));
addIfNotNull(childNodes, buildStatement(local.initialization));
childNodes.addAll(buildAnnotations(local.annotations, true));
return putInMap(new EclipseNode(this, local, childNodes, kind));
}
+ private EclipseNode buildTypeUse(TypeReference tr) {
+ if (setAndGetAsHandled(tr)) return null;
+ if (tr == null) return null;
+
+ List<EclipseNode> childNodes = new ArrayList<EclipseNode>();
+ Annotation[] anns = getTopLevelTypeReferenceAnnotations(tr);
+ if (anns != null) for (Annotation ann : anns) addIfNotNull(childNodes, buildAnnotation(ann, false));
+
+ if (tr instanceof ParameterizedQualifiedTypeReference) {
+ ParameterizedQualifiedTypeReference pqtr = (ParameterizedQualifiedTypeReference) tr;
+ int len = pqtr.tokens.length;
+ for (int i = 0; i < len; i++) {
+ TypeReference[] typeArgs = pqtr.typeArguments[i];
+ if (typeArgs != null) for (TypeReference tArg : typeArgs) addIfNotNull(childNodes, buildTypeUse(tArg));
+ }
+ } else if (tr instanceof ParameterizedSingleTypeReference) {
+ ParameterizedSingleTypeReference pstr = (ParameterizedSingleTypeReference) tr;
+ if (pstr.typeArguments != null) for (TypeReference tArg : pstr.typeArguments) {
+ addIfNotNull(childNodes, buildTypeUse(tArg));
+ }
+ } else if (tr instanceof Wildcard) {
+ TypeReference bound = ((Wildcard) tr).bound;
+ if (bound != null) addIfNotNull(childNodes, buildTypeUse(bound));
+ }
+
+ return putInMap(new EclipseNode(this, tr, childNodes, Kind.TYPE_USE));
+ }
+
private Collection<EclipseNode> buildAnnotations(Annotation[] annotations, boolean varDecl) {
List<EclipseNode> elements = new ArrayList<EclipseNode>();
if (annotations != null) for (Annotation an : annotations) addIfNotNull(elements, buildAnnotation(an, varDecl));
@@ -467,9 +523,9 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> {
private EclipseNode buildStatement(Statement child) {
if (child == null) return null;
- if (child instanceof TypeDeclaration) return buildType((TypeDeclaration)child);
+ if (child instanceof TypeDeclaration) return buildType((TypeDeclaration) child);
- if (child instanceof LocalDeclaration) return buildLocal((LocalDeclaration)child, Kind.LOCAL);
+ if (child instanceof LocalDeclaration) return buildLocal((LocalDeclaration) child, Kind.LOCAL);
if (setAndGetAsHandled(child)) return null;
@@ -491,21 +547,35 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> {
private static class EcjReflectionCheck {
private static final String COMPILATIONRESULT_TYPE = "org.eclipse.jdt.internal.compiler.CompilationResult";
- public static Method addProblemToCompilationResult;
- public static final Throwable problem;
-
+ public static final Method addProblemToCompilationResult;
+ public static final Throwable problemAddProblemToCompilationResult;
+ public static final Method typeReferenceGetAnnotationsOnDimensions;
+ public static final Field typeReferenceAnnotations;
static {
Throwable problem_ = null;
- Method m = null;
+ Method m1 = null, m2;
+ Field f;
try {
- m = Permit.getMethod(EclipseAstProblemView.class, "addProblemToCompilationResult", char[].class, Class.forName(COMPILATIONRESULT_TYPE), boolean.class, String.class, int.class, int.class);
+ m1 = Permit.getMethod(EclipseAstProblemView.class, "addProblemToCompilationResult", char[].class, Class.forName(COMPILATIONRESULT_TYPE), boolean.class, String.class, int.class, int.class);
} catch (Throwable t) {
// That's problematic, but as long as no local classes are used we don't actually need it.
// Better fail on local classes than crash altogether.
problem_ = t;
}
- addProblemToCompilationResult = m;
- problem = problem_;
+ try {
+ m2 = Permit.getMethod(TypeReference.class, "getAnnotationsOnDimensions");
+ } catch (Throwable t) {
+ m2 = null;
+ }
+ try {
+ f = Permit.getField(TypeReference.class, "annotations");
+ } catch (Throwable t) {
+ f = null;
+ }
+ addProblemToCompilationResult = m1;
+ problemAddProblemToCompilationResult = problem_;
+ typeReferenceGetAnnotationsOnDimensions = m2;
+ typeReferenceAnnotations = f;
}
}
}
diff --git a/src/core/lombok/eclipse/EclipseASTAdapter.java b/src/core/lombok/eclipse/EclipseASTAdapter.java
index 61807fff..c6ad059d 100644
--- a/src/core/lombok/eclipse/EclipseASTAdapter.java
+++ b/src/core/lombok/eclipse/EclipseASTAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,6 +30,7 @@ import org.eclipse.jdt.internal.compiler.ast.Initializer;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
/**
* Standard adapter for the {@link EclipseASTVisitor} interface. Every method on that interface
@@ -97,6 +98,15 @@ public abstract class EclipseASTAdapter implements EclipseASTVisitor {
public void endVisitLocal(EclipseNode localNode, LocalDeclaration local) {}
/** {@inheritDoc} */
+ @Override public void visitTypeUse(EclipseNode typeUseNode, TypeReference typeUse) {}
+
+ /** {@inheritDoc} */
+ public void visitAnnotationOnTypeUse(TypeReference typeUse, EclipseNode annotationNode, Annotation annotation) {}
+
+ /** {@inheritDoc} */
+ @Override public void endVisitTypeUse(EclipseNode typeUseNode, TypeReference typeUse) {}
+
+ /** {@inheritDoc} */
public void visitStatement(EclipseNode statementNode, Statement statement) {}
/** {@inheritDoc} */
diff --git a/src/core/lombok/eclipse/EclipseASTVisitor.java b/src/core/lombok/eclipse/EclipseASTVisitor.java
index 37bda5e3..0bd668bc 100644
--- a/src/core/lombok/eclipse/EclipseASTVisitor.java
+++ b/src/core/lombok/eclipse/EclipseASTVisitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 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
@@ -107,6 +107,13 @@ public interface EclipseASTVisitor {
void endVisitLocal(EclipseNode localNode, LocalDeclaration local);
/**
+ * Visits a node that represents a type reference. Anything from {@code int} to {@code T} to {@code foo,.pkg.Bar<T>.Baz<?> @Ann []}.
+ */
+ void visitTypeUse(EclipseNode typeUseNode, TypeReference typeUse);
+ void visitAnnotationOnTypeUse(TypeReference typeUse, EclipseNode annotationNode, Annotation annotation);
+ void endVisitTypeUse(EclipseNode typeUseNode, TypeReference typeUse);
+
+ /**
* Visits a statement that isn't any of the other visit methods (e.g. TypeDeclaration).
*/
void visitStatement(EclipseNode statementNode, Statement statement);
@@ -412,6 +419,21 @@ public interface EclipseASTVisitor {
print("</LOCAL %s %s>", str(local.type), str(local.name));
}
+ @Override public void visitTypeUse(EclipseNode typeUseNode, TypeReference typeUse) {
+ print("<TYPE %s>", typeUse.getClass());
+ indent++;
+ print("%s", typeUse);
+ }
+
+ @Override public void visitAnnotationOnTypeUse(TypeReference typeUse, EclipseNode annotationNode, Annotation annotation) {
+ print("<ANNOTATION%s: %s />", isGenerated(annotation) ? " (GENERATED)" : "", annotation);
+ }
+
+ @Override public void endVisitTypeUse(EclipseNode typeUseNode, TypeReference typeUse) {
+ indent--;
+ print("</TYPE %s>", typeUse.getClass());
+ }
+
public void visitStatement(EclipseNode node, Statement statement) {
print("<%s%s%s>", statement.getClass(), isGenerated(statement) ? " (GENERATED)" : "", position(node));
if (statement instanceof AllocationExpression) {
diff --git a/src/core/lombok/eclipse/EclipseNode.java b/src/core/lombok/eclipse/EclipseNode.java
index a0580c51..4c7f4eac 100644
--- a/src/core/lombok/eclipse/EclipseNode.java
+++ b/src/core/lombok/eclipse/EclipseNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2018 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -38,6 +38,7 @@ import org.eclipse.jdt.internal.compiler.ast.Initializer;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
/**
@@ -119,10 +120,18 @@ public class EclipseNode extends lombok.core.LombokNode<EclipseAST, EclipseNode,
case LOCAL:
visitor.visitAnnotationOnLocal((LocalDeclaration) parent.get(), this, (Annotation) get());
break;
+ case TYPE_USE:
+ visitor.visitAnnotationOnTypeUse((TypeReference) parent.get(), this, (Annotation) get());
+ break;
default:
throw new AssertionError("Annotation not expected as child of a " + up().getKind());
}
break;
+ case TYPE_USE:
+ visitor.visitTypeUse(this, (TypeReference) get());
+ ast.traverseChildren(visitor, this);
+ visitor.endVisitTypeUse(this, (TypeReference) get());
+ break;
case STATEMENT:
visitor.visitStatement(this, (Statement) get());
ast.traverseChildren(visitor, this);
diff --git a/src/core/lombok/eclipse/TransformEclipseAST.java b/src/core/lombok/eclipse/TransformEclipseAST.java
index e5edba64..6fcde937 100644
--- a/src/core/lombok/eclipse/TransformEclipseAST.java
+++ b/src/core/lombok/eclipse/TransformEclipseAST.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2018 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 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
@@ -39,6 +39,7 @@ import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.parser.Parser;
/**
@@ -236,5 +237,10 @@ public class TransformEclipseAST {
CompilationUnitDeclaration top = (CompilationUnitDeclaration) annotationNode.top().get();
nextPriority = Math.min(nextPriority, handlers.handleAnnotation(top, annotationNode, annotation, priority));
}
+
+ @Override public void visitAnnotationOnTypeUse(TypeReference typeUse, EclipseNode annotationNode, Annotation annotation) {
+ CompilationUnitDeclaration top = (CompilationUnitDeclaration) annotationNode.top().get();
+ nextPriority = Math.min(nextPriority, handlers.handleAnnotation(top, annotationNode, annotation, priority));
+ }
}
}
diff --git a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
index b9b9e07d..81ddbd0a 100644..100755
--- a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
+++ b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
@@ -341,7 +341,7 @@ public class EclipseSingularsRecipes {
}
if (arguments.isEmpty()) return null;
- return arguments.toArray(new TypeReference[arguments.size()]);
+ return arguments.toArray(new TypeReference[0]);
}
private static final char[] SIZE_TEXT = new char[] {'s', 'i', 'z', 'e'};
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index fc11aff2..3391b99d 100644..100755
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2018 The Project Lombok Authors.
+ * Copyright (C) 2013-2019 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
@@ -87,6 +87,7 @@ import lombok.core.HandlerPriority;
import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
+import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult;
import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData;
import lombok.eclipse.handlers.HandleConstructor.SkipIfConstructorExists;
@@ -460,9 +461,13 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
makeSetterMethodsForBuilder(builderType, bfd, annotationNode, fluent, chain);
}
- if (methodExists(buildMethodName, builderType, -1) == MemberExistsResult.NOT_EXISTS) {
- MethodDeclaration md = generateBuildMethod(tdParent, isStatic, buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, addCleaning, ast);
- if (md != null) injectMethod(builderType, md);
+ {
+ MemberExistsResult methodExists = methodExists(buildMethodName, builderType, -1);
+ if (methodExists == MemberExistsResult.EXISTS_BY_LOMBOK) methodExists = methodExists(buildMethodName, builderType, 0);
+ if (methodExists == MemberExistsResult.NOT_EXISTS) {
+ MethodDeclaration md = generateBuildMethod(tdParent, isStatic, buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, addCleaning, ast);
+ if (md != null) injectMethod(builderType, md);
+ }
}
if (methodExists("toString", builderType, 0) == MemberExistsResult.NOT_EXISTS) {
@@ -663,7 +668,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
if (staticName == null) {
AllocationExpression allocationStatement = new AllocationExpression();
allocationStatement.type = copyType(out.returnType);
- allocationStatement.arguments = args.isEmpty() ? null : args.toArray(new Expression[args.size()]);
+ allocationStatement.arguments = args.isEmpty() ? null : args.toArray(new Expression[0]);
statements.add(new ReturnStatement(allocationStatement, 0, 0));
} else {
MessageSend invoke = new MessageSend();
@@ -674,14 +679,14 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
invoke.receiver = new QualifiedThisReference(new SingleTypeReference(type.up().getName().toCharArray(), 0) , 0, 0);
invoke.typeArguments = typeParameterNames(((TypeDeclaration) type.get()).typeParameters);
- invoke.arguments = args.isEmpty() ? null : args.toArray(new Expression[args.size()]);
+ invoke.arguments = args.isEmpty() ? null : args.toArray(new Expression[0]);
if (returnType instanceof SingleTypeReference && Arrays.equals(TypeConstants.VOID, ((SingleTypeReference) returnType).token)) {
statements.add(invoke);
} else {
statements.add(new ReturnStatement(invoke, 0, 0));
}
}
- out.statements = statements.isEmpty() ? null : statements.toArray(new Statement[statements.size()]);
+ out.statements = statements.isEmpty() ? null : statements.toArray(new Statement[0]);
out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
return out;
}
diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java
index 82859e4b..660b9985 100644..100755
--- a/src/core/lombok/eclipse/handlers/HandleConstructor.java
+++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java
@@ -447,8 +447,8 @@ public class HandleConstructor {
}
nullChecks.addAll(assigns);
- constructor.statements = nullChecks.isEmpty() ? null : nullChecks.toArray(new Statement[nullChecks.size()]);
- constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[params.size()]);
+ constructor.statements = nullChecks.isEmpty() ? null : nullChecks.toArray(new Statement[0]);
+ constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[0]);
/* Generate annotations that must be put on the generated method, and attach them. */ {
Annotation[] constructorProperties = null;
@@ -550,8 +550,8 @@ public class HandleConstructor {
params.add(parameter);
}
- statement.arguments = assigns.isEmpty() ? null : assigns.toArray(new Expression[assigns.size()]);
- constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[params.size()]);
+ statement.arguments = assigns.isEmpty() ? null : assigns.toArray(new Expression[0]);
+ constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[0]);
constructor.statements = new Statement[] { new ReturnStatement(statement, (int) (p >> 32), (int)p) };
constructor.traverse(new SetGeneratedByVisitor(source), typeDecl.scope);
diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
index 84e5185d..046b197f 100644..100755
--- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
@@ -391,7 +391,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
setGeneratedBy(returnStatement, source);
statements.add(returnStatement);
}
- method.statements = statements.toArray(new Statement[statements.size()]);
+ method.statements = statements.toArray(new Statement[0]);
return method;
}
@@ -738,7 +738,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
setGeneratedBy(returnStatement, source);
statements.add(returnStatement);
}
- method.statements = statements.toArray(new Statement[statements.size()]);
+ method.statements = statements.toArray(new Statement[0]);
return method;
}
diff --git a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
index 9e81a068..1caccd59 100644
--- a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
+++ b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2018 The Project Lombok Authors.
+ * Copyright (C) 2014-2019 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
@@ -27,15 +27,7 @@ import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
import java.util.ArrayList;
import java.util.List;
-import lombok.AccessLevel;
-import lombok.ConfigurationKeys;
-import lombok.core.AST.Kind;
-import lombok.core.AnnotationValues;
-import lombok.eclipse.Eclipse;
-import lombok.eclipse.EclipseAnnotationHandler;
-import lombok.eclipse.EclipseNode;
-import lombok.experimental.FieldNameConstants;
-
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
@@ -51,6 +43,16 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.mangosdk.spi.ProviderFor;
+import lombok.AccessLevel;
+import lombok.ConfigurationKeys;
+import lombok.core.AST.Kind;
+import lombok.core.AnnotationValues;
+import lombok.eclipse.Eclipse;
+import lombok.eclipse.EclipseAnnotationHandler;
+import lombok.eclipse.EclipseNode;
+import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult;
+import lombok.experimental.FieldNameConstants;
+
@ProviderFor(EclipseAnnotationHandler.class)
public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldNameConstants> {
public void generateFieldNameConstantsForType(EclipseNode typeNode, EclipseNode errorNode, AccessLevel level, boolean asEnum, String innerTypeName, boolean onlyExplicit) {
@@ -88,7 +90,7 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
return filterField(fieldDecl);
}
- public void handle(AnnotationValues<FieldNameConstants> annotation, Annotation ast, EclipseNode annotationNode) {
+ @Override public void handle(AnnotationValues<FieldNameConstants> annotation, Annotation ast, EclipseNode annotationNode) {
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.FIELD_NAME_CONSTANTS_FLAG_USAGE, "@FieldNameConstants");
EclipseNode node = annotationNode.up();
@@ -117,6 +119,7 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
private void createInnerTypeFieldNameConstants(EclipseNode typeNode, EclipseNode errorNode, ASTNode source, AccessLevel level, List<EclipseNode> fields, boolean asEnum, String innerTypeName) {
if (fields.isEmpty()) return;
+ ASTVisitor generatedByVisitor = new SetGeneratedByVisitor(source);
TypeDeclaration parent = (TypeDeclaration) typeNode.get();
EclipseNode fieldsType = findInnerClass(typeNode, innerTypeName);
boolean genConstr = false, genClinit = false;
@@ -125,11 +128,12 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
if (fieldsType == null) {
generatedInnerType = new TypeDeclaration(parent.compilationResult);
generatedInnerType.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
- generatedInnerType.modifiers = toEclipseModifier(level) | (asEnum ? ClassFileConstants.AccEnum : ClassFileConstants.AccStatic | ClassFileConstants.AccFinal);
+ generatedInnerType.modifiers = toEclipseModifier(level) | (asEnum ? ClassFileConstants.AccEnum : (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal));
generatedInnerType.name = name;
fieldsType = injectType(typeNode, generatedInnerType);
genConstr = true;
genClinit = asEnum;
+ generatedInnerType.traverse(generatedByVisitor, ((TypeDeclaration) typeNode.get()).scope);
} else {
TypeDeclaration builderTypeDeclaration = (TypeDeclaration) fieldsType.get();
if (asEnum && (builderTypeDeclaration.modifiers & ClassFileConstants.AccEnum) == 0) {
@@ -146,8 +150,6 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
if (genConstr) {
ConstructorDeclaration constructor = new ConstructorDeclaration(parent.compilationResult);
constructor.selector = name;
- constructor.declarationSourceStart = constructor.sourceStart = source.sourceStart;
- constructor.declarationSourceEnd = constructor.sourceEnd = source.sourceEnd;
constructor.modifiers = ClassFileConstants.AccPrivate;
ExplicitConstructorCall superCall = new ExplicitConstructorCall(0);
superCall.sourceStart = source.sourceStart;
@@ -157,11 +159,12 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
if (!asEnum) constructor.statements = new Statement[0];
injectMethod(fieldsType, constructor);
}
+
if (genClinit) {
Clinit cli = new Clinit(parent.compilationResult);
injectMethod(fieldsType, cli);
+ cli.traverse(generatedByVisitor, ((TypeDeclaration) fieldsType.get()).scope);
}
-
for (EclipseNode fieldNode : fields) {
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
@@ -171,19 +174,20 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
long p = (long) pS << 32 | pE;
FieldDeclaration constantField = new FieldDeclaration(fName, pS, pE);
constantField.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
- constantField.modifiers = asEnum ? 0 : ClassFileConstants.AccPublic | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal;
- constantField.type = asEnum ? null : new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING, new long[] {p, p, p});
if (asEnum) {
AllocationExpression ac = new AllocationExpression();
ac.enumConstant = constantField;
ac.sourceStart = source.sourceStart;
ac.sourceEnd = source.sourceEnd;
constantField.initialization = ac;
+ constantField.modifiers = 0;
} else {
+ constantField.type = new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING, new long[] {p, p, p});
constantField.initialization = new StringLiteral(field.name, pS, pE, 0);
+ constantField.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal;
}
- constantField.traverse(new SetGeneratedByVisitor(source), null);
injectField(fieldsType, constantField);
+ constantField.traverse(generatedByVisitor, ((TypeDeclaration) fieldsType.get()).initializerScope);
}
}
}
diff --git a/src/core/lombok/eclipse/handlers/HandleHelper.java b/src/core/lombok/eclipse/handlers/HandleHelper.java
index 4f06bdfd..36f53813 100644..100755
--- a/src/core/lombok/eclipse/handlers/HandleHelper.java
+++ b/src/core/lombok/eclipse/handlers/HandleHelper.java
@@ -103,7 +103,7 @@ public class HandleHelper extends EclipseAnnotationHandler<Helper> {
}
Collections.sort(knownMethodNames);
- final String[] knownMethodNames_ = knownMethodNames.toArray(new String[knownMethodNames.size()]);
+ final String[] knownMethodNames_ = knownMethodNames.toArray(new String[0]);
final char[] helperName = new char[annotatedType_.name.length + 1];
final boolean[] helperUsed = new boolean[1];
diff --git a/src/core/lombok/eclipse/handlers/HandleNonNull.java b/src/core/lombok/eclipse/handlers/HandleNonNull.java
index ebc62909..1672618d 100644
--- a/src/core/lombok/eclipse/handlers/HandleNonNull.java
+++ b/src/core/lombok/eclipse/handlers/HandleNonNull.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 The Project Lombok Authors.
+ * Copyright (C) 2013-2019 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
@@ -33,6 +33,7 @@ import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
import lombok.eclipse.DeferUntilPostDiet;
+import lombok.eclipse.EclipseAST;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
@@ -52,6 +53,7 @@ import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement;
import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.mangosdk.spi.ProviderFor;
@DeferUntilPostDiet
@@ -95,14 +97,33 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
return;
}
- if (annotationNode.up().getKind() != Kind.ARGUMENT) return;
-
- Argument arg;
+ 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 {
- arg = (Argument) annotationNode.up().get();
- declaration = (AbstractMethodDeclaration) annotationNode.up().up().get();
+ param = (Argument) paramNode.get();
+ declaration = (AbstractMethodDeclaration) paramNode.up().get();
} catch (Exception e) {
return;
}
@@ -118,7 +139,7 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
// and if they exist, create a new method in the class: 'private static <T> T lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and
// wrap all references to it in the super/this to a call to this method.
- Statement nullCheck = generateNullCheck(arg, annotationNode);
+ Statement nullCheck = generateNullCheck(param, annotationNode);
if (nullCheck == null) {
// @NonNull applied to a primitive. Kinda pointless. Let's generate a warning.
@@ -129,7 +150,7 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
if (declaration.statements == null) {
declaration.statements = new Statement[] {nullCheck};
} else {
- char[] expectedName = arg.name;
+ char[] expectedName = param.name;
/* Abort if the null check is already there, delving into try and synchronized statements */ {
Statement[] stats = declaration.statements;
int idx = 0;
@@ -162,7 +183,7 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
newStatements[skipOver] = nullCheck;
declaration.statements = newStatements;
}
- annotationNode.up().up().rebuild();
+ paramNode.up().rebuild();
}
public boolean isNullCheck(Statement stat) {
diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
index 9a3275c2..7b6a3c28 100644..100755
--- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
@@ -546,7 +546,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
}
}
- constructor.statements = statements.isEmpty() ? null : statements.toArray(new Statement[statements.size()]);
+ constructor.statements = statements.isEmpty() ? null : statements.toArray(new Statement[0]);
constructor.traverse(new SetGeneratedByVisitor(source), typeDeclaration.scope);
@@ -654,7 +654,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
returnCall.selector = SELF_METHOD_NAME;
body.add(new ReturnStatement(returnCall, 0, 0));
- out.statements = body.isEmpty() ? null : body.toArray(new Statement[body.size()]);
+ out.statements = body.isEmpty() ? null : body.toArray(new Statement[0]);
return out;
}
@@ -694,7 +694,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
body.add(exec);
}
- out.statements = body.isEmpty() ? null : body.toArray(new Statement[body.size()]);
+ out.statements = body.isEmpty() ? null : body.toArray(new Statement[0]);
return out;
}
@@ -788,7 +788,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
// Use a constructor that only has this builder as parameter.
allocationStatement.arguments = new Expression[] {new ThisReference(0, 0)};
statements.add(new ReturnStatement(allocationStatement, 0, 0));
- out.statements = statements.isEmpty() ? null : statements.toArray(new Statement[statements.size()]);
+ out.statements = statements.isEmpty() ? null : statements.toArray(new Statement[0]);
out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
return out;
}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
index 4b094a9f..40f01ee4 100644..100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
@@ -149,7 +149,7 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
thisDotFieldDotAdd.selector = getAddMethodName().toCharArray();
statements.add(thisDotFieldDotAdd);
if (returnStatement != null) statements.add(returnStatement);
- md.statements = statements.toArray(new Statement[statements.size()]);
+ md.statements = statements.toArray(new Statement[0]);
md.arguments = new Argument[suffixes.size()];
for (int i = 0; i < suffixes.size(); i++) {
TypeReference tr = cloneParamType(i, data.getTypeArgs(), builderType);
@@ -183,7 +183,7 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
statements.add(thisDotFieldDotAddAll);
if (returnStatement != null) statements.add(returnStatement);
- md.statements = statements.toArray(new Statement[statements.size()]);
+ md.statements = statements.toArray(new Statement[0]);
TypeReference paramType;
paramType = new QualifiedTypeReference(fromQualifiedName(getAddAllTypeName()), NULL_POSS);
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
index 11314bd3..32b1f71f 100644..100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
@@ -140,7 +140,7 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
statements.add(thisDotFieldDotAdd);
if (returnStatement != null) statements.add(returnStatement);
- md.statements = statements.toArray(new Statement[statements.size()]);
+ md.statements = statements.toArray(new Statement[0]);
TypeReference paramType = cloneParamType(0, data.getTypeArgs(), builderType);
Annotation[] typeUseAnns = getTypeUseAnnotations(paramType);
removeTypeUseAnnotations(paramType);
@@ -172,7 +172,7 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
statements.add(thisDotFieldDotAddAll);
if (returnStatement != null) statements.add(returnStatement);
- md.statements = statements.toArray(new Statement[statements.size()]);
+ md.statements = statements.toArray(new Statement[0]);
TypeReference paramType = new QualifiedTypeReference(TypeConstants.JAVA_UTIL_COLLECTION, NULL_POSS);
paramType = addTypeArgs(1, true, builderType, paramType, data.getTypeArgs());
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java
index f512bacf..80d49fe7 100644..100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java
@@ -115,7 +115,7 @@ public class EclipseJavaUtilListSingularizer extends EclipseJavaUtilListSetSingu
}
SwitchStatement switchStat = new SwitchStatement();
- switchStat.statements = switchContents.toArray(new Statement[switchContents.size()]);
+ switchStat.statements = switchContents.toArray(new Statement[0]);
switchStat.expression = getSize(builderType, data.getPluralName(), true, builderVariable);
TypeReference localShadowerType = new QualifiedTypeReference(Eclipse.fromQualifiedName(data.getTargetFqn()), NULL_POSS);
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
index 55f6cadd..b24bf97f 100644..100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
@@ -215,7 +215,7 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
}
if (returnStatement != null) statements.add(returnStatement);
- md.statements = statements.toArray(new Statement[statements.size()]);
+ md.statements = statements.toArray(new Statement[0]);
TypeReference keyParamType = cloneParamType(0, data.getTypeArgs(), builderType);
TypeReference valueParamType = cloneParamType(1, data.getTypeArgs(), builderType);
Annotation[] typeUseAnnsKey = getTypeUseAnnotations(keyParamType);
@@ -286,7 +286,7 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
statements.add(forEach);
if (returnStatement != null) statements.add(returnStatement);
- md.statements = statements.toArray(new Statement[statements.size()]);
+ md.statements = statements.toArray(new Statement[0]);
TypeReference paramType = new QualifiedTypeReference(JAVA_UTIL_MAP, NULL_POSS);
paramType = addTypeArgs(2, true, builderType, paramType, data.getTypeArgs());
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSingularizer.java
index 8bcfa65d..8aeffc48 100644..100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSingularizer.java
@@ -147,7 +147,7 @@ abstract class EclipseJavaUtilSingularizer extends EclipseSingularizer {
}
SwitchStatement switchStat = new SwitchStatement();
- switchStat.statements = switchContents.toArray(new Statement[switchContents.size()]);
+ switchStat.statements = switchContents.toArray(new Statement[0]);
switchStat.expression = getSize(builderType, keyName, true, builderVariable);
TypeReference localShadowerType = new QualifiedTypeReference(fromQualifiedName(data.getTargetFqn()), NULL_POSS);
diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java
index f2901038..f6cd5571 100644
--- a/src/core/lombok/javac/JavacAST.java
+++ b/src/core/lombok/javac/JavacAST.java
@@ -47,15 +47,19 @@ import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.model.JavacTypes;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
+import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCCatch;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
+import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.tree.JCTree.JCTry;
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.DiagnosticPosition;
@@ -192,6 +196,8 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
return buildStatementOrExpression(node);
case ANNOTATION:
return buildAnnotation((JCAnnotation) node, false);
+ case TYPE_USE:
+ return buildTypeUse(node);
default:
throw new AssertionError("Did not expect: " + kind);
}
@@ -233,6 +239,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
if (setAndGetAsHandled(field)) return null;
List<JavacNode> childNodes = new ArrayList<JavacNode>();
for (JCAnnotation annotation : field.mods.annotations) addIfNotNull(childNodes, buildAnnotation(annotation, true));
+ addIfNotNull(childNodes, buildTypeUse(field.vartype));
addIfNotNull(childNodes, buildExpression(field.init));
return putInMap(new JavacNode(this, field, childNodes, Kind.FIELD));
}
@@ -241,23 +248,62 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
if (setAndGetAsHandled(local)) return null;
List<JavacNode> childNodes = new ArrayList<JavacNode>();
for (JCAnnotation annotation : local.mods.annotations) addIfNotNull(childNodes, buildAnnotation(annotation, true));
+ addIfNotNull(childNodes, buildTypeUse(local.vartype));
addIfNotNull(childNodes, buildExpression(local.init));
return putInMap(new JavacNode(this, local, childNodes, kind));
}
- private static boolean JCTRY_RESOURCES_FIELD_INITIALIZED;
+ private JavacNode buildTypeUse(JCTree typeUse) {
+ if (setAndGetAsHandled(typeUse)) return null;
+
+ if (typeUse == null) return null;
+
+ if (typeUse.getClass().getSimpleName().equals("JCAnnotatedType")) {
+ initJcAnnotatedType(typeUse.getClass());
+ Collection<?> anns = Permit.permissiveReadField(Collection.class, JCANNOTATEDTYPE_ANNOTATIONS, typeUse);
+ JCExpression underlying = Permit.permissiveReadField(JCExpression.class, JCANNOTATEDTYPE_UNDERLYINGTYPE, typeUse);
+
+ List<JavacNode> childNodes = new ArrayList<JavacNode>();
+ if (anns != null) for (Object annotation : anns) if (annotation instanceof JCAnnotation) addIfNotNull(childNodes, buildAnnotation((JCAnnotation) annotation, true));
+ addIfNotNull(childNodes, buildTypeUse(underlying));
+ return putInMap(new JavacNode(this, typeUse, childNodes, Kind.TYPE_USE));
+ }
+
+ if (typeUse instanceof JCWildcard) {
+ JCTree inner = ((JCWildcard) typeUse).inner;
+ List<JavacNode> childNodes = inner == null ? Collections.<JavacNode>emptyList() : new ArrayList<JavacNode>();
+ if (inner != null) addIfNotNull(childNodes, buildTypeUse(inner));
+ return putInMap(new JavacNode(this, typeUse, childNodes, Kind.TYPE_USE));
+ }
+
+ if (typeUse instanceof JCArrayTypeTree) {
+ JCTree inner = ((JCArrayTypeTree) typeUse).elemtype;
+ List<JavacNode> childNodes = inner == null ? Collections.<JavacNode>emptyList() : new ArrayList<JavacNode>();
+ if (inner != null) addIfNotNull(childNodes, buildTypeUse(inner));
+ return putInMap(new JavacNode(this, typeUse, childNodes, Kind.TYPE_USE));
+ }
+
+ if (typeUse instanceof JCFieldAccess) {
+ JCTree inner = ((JCFieldAccess) typeUse).selected;
+ List<JavacNode> childNodes = inner == null ? Collections.<JavacNode>emptyList() : new ArrayList<JavacNode>();
+ if (inner != null) addIfNotNull(childNodes, buildTypeUse(inner));
+ return putInMap(new JavacNode(this, typeUse, childNodes, Kind.TYPE_USE));
+ }
+
+ if (typeUse instanceof JCIdent) {
+ return putInMap(new JavacNode(this, typeUse, Collections.<JavacNode>emptyList(), Kind.TYPE_USE));
+ }
+
+ return null;
+ }
+
+ private static boolean JCTRY_RESOURCES_FIELD_INITIALIZED = false;
private static Field JCTRY_RESOURCES_FIELD;
@SuppressWarnings("unchecked")
private static List<JCTree> getResourcesForTryNode(JCTry tryNode) {
if (!JCTRY_RESOURCES_FIELD_INITIALIZED) {
- try {
- JCTRY_RESOURCES_FIELD = Permit.getField(JCTry.class, "resources");
- } catch (NoSuchFieldException ignore) {
- // Java 1.6 or lower won't have this at all.
- } catch (Exception ignore) {
- // Shouldn't happen. Best thing we can do is just carry on and break on try/catch.
- }
+ JCTRY_RESOURCES_FIELD = Permit.permissiveGetField(JCTry.class, "resources");
JCTRY_RESOURCES_FIELD_INITIALIZED = true;
}
@@ -271,6 +317,15 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
return Collections.emptyList();
}
+ private static boolean JCANNOTATEDTYPE_FIELDS_INITIALIZED = false;
+ private static Field JCANNOTATEDTYPE_ANNOTATIONS, JCANNOTATEDTYPE_UNDERLYINGTYPE;
+ private static void initJcAnnotatedType(Class<?> context) {
+ if (JCANNOTATEDTYPE_FIELDS_INITIALIZED) return;
+ JCANNOTATEDTYPE_ANNOTATIONS = Permit.permissiveGetField(context, "annotations");
+ JCANNOTATEDTYPE_UNDERLYINGTYPE = Permit.permissiveGetField(context, "underlyingType");
+ JCANNOTATEDTYPE_FIELDS_INITIALIZED = true;
+ }
+
private JavacNode buildTry(JCTry tryNode) {
if (setAndGetAsHandled(tryNode)) return null;
List<JavacNode> childNodes = new ArrayList<JavacNode>();
@@ -323,8 +378,8 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
private JavacNode buildStatementOrExpression(JCTree statement) {
if (statement == null) return null;
if (statement instanceof JCAnnotation) return null;
- if (statement instanceof JCClassDecl) return buildType((JCClassDecl)statement);
- if (statement instanceof JCVariableDecl) return buildLocalVar((JCVariableDecl)statement, Kind.LOCAL);
+ if (statement instanceof JCClassDecl) return buildType((JCClassDecl) statement);
+ if (statement instanceof JCVariableDecl) return buildLocalVar((JCVariableDecl) statement, Kind.LOCAL);
if (statement instanceof JCTry) return buildTry((JCTry) statement);
if (statement.getClass().getSimpleName().equals("JCLambda")) return buildLambda(statement);
if (setAndGetAsHandled(statement)) return null;
diff --git a/src/core/lombok/javac/JavacASTAdapter.java b/src/core/lombok/javac/JavacASTAdapter.java
index 6af53e3d..4c1912d8 100644
--- a/src/core/lombok/javac/JavacASTAdapter.java
+++ b/src/core/lombok/javac/JavacASTAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 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
@@ -96,6 +96,15 @@ public class JavacASTAdapter implements JavacASTVisitor {
@Override public void endVisitLocal(JavacNode localNode, JCVariableDecl local) {}
/** {@inheritDoc} */
+ @Override public void visitTypeUse(JavacNode typeUseNode, JCTree typeUse) {}
+
+ /** {@inheritDoc} */
+ @Override public void visitAnnotationOnTypeUse(JCTree typeUse, JavacNode annotationNode, JCAnnotation annotation) {}
+
+ /** {@inheritDoc} */
+ @Override public void endVisitTypeUse(JavacNode typeUseNode, JCTree typeUse) {}
+
+ /** {@inheritDoc} */
@Override public void visitStatement(JavacNode statementNode, JCTree statement) {}
/** {@inheritDoc} */
diff --git a/src/core/lombok/javac/JavacASTVisitor.java b/src/core/lombok/javac/JavacASTVisitor.java
index d4f8f731..9b67dda3 100644
--- a/src/core/lombok/javac/JavacASTVisitor.java
+++ b/src/core/lombok/javac/JavacASTVisitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 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
@@ -89,6 +89,13 @@ public interface JavacASTVisitor {
void endVisitLocal(JavacNode localNode, JCVariableDecl local);
/**
+ * Visits a node that represents a type reference. Anything from {@code int} to {@code T} to {@code foo.pkg.Bar<T>.Baz<?> @Ann []}.
+ */
+ void visitTypeUse(JavacNode typeUseNode, JCTree typeUse);
+ void visitAnnotationOnTypeUse(JCTree typeUse, JavacNode annotationNode, JCAnnotation annotation);
+ void endVisitTypeUse(JavacNode typeUseNode, JCTree typeUse);
+
+ /**
* Visits a statement that isn't any of the other visit methods (e.g. JCClassDecl).
* The statement object is guaranteed to be either a JCStatement or a JCExpression.
*/
@@ -261,6 +268,21 @@ public interface JavacASTVisitor {
print("</LOCAL %s %s>", local.vartype, local.name);
}
+ @Override public void visitTypeUse(JavacNode node, JCTree typeUse) {
+ print("<TYPE %s>", typeUse.getClass());
+ indent++;
+ print("%s", typeUse);
+ }
+
+ @Override public void visitAnnotationOnTypeUse(JCTree typeUse, JavacNode node, JCAnnotation annotation) {
+ print("<ANNOTATION: %s />", annotation);
+ }
+
+ @Override public void endVisitTypeUse(JavacNode node, JCTree typeUse) {
+ indent--;
+ print("</TYPE %s>", typeUse.getClass());
+ }
+
@Override public void visitStatement(JavacNode node, JCTree statement) {
print("<%s>", statement.getClass());
indent++;
diff --git a/src/core/lombok/javac/JavacNode.java b/src/core/lombok/javac/JavacNode.java
index f119f1f9..191ab3c0 100644
--- a/src/core/lombok/javac/JavacNode.java
+++ b/src/core/lombok/javac/JavacNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2018 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 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
@@ -145,10 +145,18 @@ public class JavacNode extends lombok.core.LombokNode<JavacAST, JavacNode, JCTre
case LOCAL:
visitor.visitAnnotationOnLocal((JCVariableDecl) up().get(), this, (JCAnnotation) get());
break;
+ case TYPE_USE:
+ visitor.visitAnnotationOnTypeUse(up().get(), this, (JCAnnotation) get());
+ break;
default:
throw new AssertionError("Annotion not expected as child of a " + up().getKind());
}
break;
+ case TYPE_USE:
+ visitor.visitTypeUse(this, get());
+ ast.traverseChildren(visitor, this);
+ visitor.endVisitTypeUse(this, get());
+ break;
default:
throw new AssertionError("Unexpected kind during node traversal: " + getKind());
}
diff --git a/src/core/lombok/javac/JavacTransformer.java b/src/core/lombok/javac/JavacTransformer.java
index 0a4f1f73..625fb283 100644
--- a/src/core/lombok/javac/JavacTransformer.java
+++ b/src/core/lombok/javac/JavacTransformer.java
@@ -27,6 +27,7 @@ import java.util.SortedSet;
import javax.annotation.processing.Messager;
import com.sun.source.util.Trees;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
@@ -114,5 +115,10 @@ public class JavacTransformer {
JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get();
handlers.handleAnnotation(top, annotationNode, annotation, priority);
}
+
+ @Override public void visitAnnotationOnTypeUse(JCTree typeUse, JavacNode annotationNode, JCAnnotation annotation) {
+ JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get();
+ handlers.handleAnnotation(top, annotationNode, annotation, priority);
+ }
}
}
diff --git a/src/core/lombok/javac/apt/EmptyLombokFileObject.java b/src/core/lombok/javac/apt/EmptyLombokFileObject.java
deleted file mode 100644
index d1d00582..00000000
--- a/src/core/lombok/javac/apt/EmptyLombokFileObject.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2010-2018 The Project Lombok Authors.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package lombok.javac.apt;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.Writer;
-import java.net.URI;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CodingErrorAction;
-
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.NestingKind;
-
-// Can't use SimpleJavaFileObject so we copy/paste most of its content here, because javac doesn't follow the interface,
-// and casts to its own BaseFileObject type. D'oh!
-class EmptyLombokFileObject implements LombokFileObject {
- private final String name;
- private final Kind kind;
-
- public EmptyLombokFileObject(String name, Kind kind) {
- this.name = name;
- this.kind = kind;
- }
-
- @Override public boolean isNameCompatible(String simpleName, Kind kind) {
- String baseName = simpleName + kind.extension;
- return kind.equals(getKind())
- && (baseName.equals(toUri().getPath()) || toUri().getPath().endsWith("/" + baseName));
- }
-
- @Override public URI toUri() {
- return URI.create("file:///" + (name.startsWith("/") ? name.substring(1) : name));
- }
-
- @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
- return "";
- }
-
- @Override public InputStream openInputStream() throws IOException {
- return new ByteArrayInputStream(new byte[0]);
- }
-
- @Override public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
- return new StringReader("");
- }
-
- @Override public Writer openWriter() throws IOException {
- return new OutputStreamWriter(openOutputStream());
- }
-
- @Override public OutputStream openOutputStream() throws IOException {
- return new ByteArrayOutputStream();
- }
-
- @Override public long getLastModified() {
- return 0L;
- }
-
- @Override public boolean delete() {
- return false;
- }
-
- @Override public Kind getKind() {
- return kind;
- }
-
- @SuppressWarnings("all")
- @Override public String getName() {
- return toUri().getPath();
- }
-
- @Override public NestingKind getNestingKind() {
- return null;
- }
-
- @Override public Modifier getAccessLevel() {
- return null;
- }
-
- @Override public CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
- CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
- CodingErrorAction action = ignoreEncodingErrors ? CodingErrorAction.REPLACE : CodingErrorAction.REPORT;
- return decoder.onMalformedInput(action).onUnmappableCharacter(action);
- }
-
- @Override public boolean equals(Object obj) {
- if (!(obj instanceof EmptyLombokFileObject)) return false;
- if (obj == this) return true;
- EmptyLombokFileObject other = (EmptyLombokFileObject) obj;
- return name.equals(other.name) && kind.equals(other.kind);
- }
-
- @Override public int hashCode() {
- return name.hashCode() ^ kind.hashCode();
- }
-} \ No newline at end of file
diff --git a/src/core/lombok/javac/apt/InterceptingJavaFileManager.java b/src/core/lombok/javac/apt/InterceptingJavaFileManager.java
index 9b58d111..3f4c6ef1 100644
--- a/src/core/lombok/javac/apt/InterceptingJavaFileManager.java
+++ b/src/core/lombok/javac/apt/InterceptingJavaFileManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2018 The Project Lombok Authors.
+ * Copyright (C) 2010-2019 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
@@ -42,11 +42,6 @@ final class InterceptingJavaFileManager extends ForwardingJavaFileManager<JavaFi
}
@Override public JavaFileObject getJavaFileForOutput(Location location, String className, final Kind kind, FileObject sibling) throws IOException {
- if (className.contains("lombok.dummy.ForceNewRound")) {
- final String name = className.replace(".", "/") + kind.extension;
- return LombokFileObjects.createEmpty(compiler, name, kind);
- }
-
JavaFileObject fileObject = fileManager.getJavaFileForOutput(location, className, kind, sibling);
if (kind != Kind.CLASS) return fileObject;
diff --git a/src/core/lombok/javac/apt/LombokFileObjects.java b/src/core/lombok/javac/apt/LombokFileObjects.java
index d6c96480..f6643db3 100644
--- a/src/core/lombok/javac/apt/LombokFileObjects.java
+++ b/src/core/lombok/javac/apt/LombokFileObjects.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2018 The Project Lombok Authors.
+ * Copyright (C) 2010-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -38,11 +38,11 @@ import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
+import com.sun.tools.javac.file.BaseFileManager;
+
import lombok.core.DiagnosticsReceiver;
import lombok.permit.Permit;
-import com.sun.tools.javac.file.BaseFileManager;
-
//Can't use SimpleJavaFileObject so we copy/paste most of its content here, because javac doesn't follow the interface,
//and casts to its own BaseFileObject type. D'oh!
final class LombokFileObjects {
@@ -152,10 +152,6 @@ final class LombokFileObjects {
throw new IllegalArgumentException(sb.toString());
}
- static JavaFileObject createEmpty(Compiler compiler, String name, Kind kind) {
- return compiler.wrap(new EmptyLombokFileObject(name, kind));
- }
-
static JavaFileObject createIntercepting(Compiler compiler, JavaFileObject delegate, String fileName, DiagnosticsReceiver diagnostics) {
return compiler.wrap(new InterceptingJavaFileObject(delegate, fileName, diagnostics, compiler.getDecoderMethod()));
}
diff --git a/src/core/lombok/javac/apt/LombokProcessor.java b/src/core/lombok/javac/apt/LombokProcessor.java
index d4f3504a..79db5dec 100644
--- a/src/core/lombok/javac/apt/LombokProcessor.java
+++ b/src/core/lombok/javac/apt/LombokProcessor.java
@@ -23,7 +23,6 @@ package lombok.javac.apt;
import java.io.IOException;
import java.io.InputStream;
-import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
@@ -47,13 +46,6 @@ import javax.lang.model.element.QualifiedNameable;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;
import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-
-import lombok.Lombok;
-import lombok.core.CleanupRegistry;
-import lombok.core.DiagnosticsReceiver;
-import lombok.javac.JavacTransformer;
-import lombok.permit.Permit;
import com.sun.source.util.TreePath;
import com.sun.source.util.Trees;
@@ -64,6 +56,12 @@ import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Context;
+import lombok.Lombok;
+import lombok.core.CleanupRegistry;
+import lombok.core.DiagnosticsReceiver;
+import lombok.javac.JavacTransformer;
+import lombok.permit.Permit;
+
/**
* This Annotation Processor is the standard injection mechanism for lombok-enabling the javac compiler.
*
@@ -362,11 +360,7 @@ public class LombokProcessor extends AbstractProcessor {
private void forceNewRound(String randomModuleName, JavacFiler filer) {
if (!filer.newFiles()) {
try {
- String name = "lombok.dummy.ForceNewRound" + (dummyCount++);
- if (randomModuleName != null) name = randomModuleName + "/" + name;
- JavaFileObject dummy = filer.createSourceFile(name);
- Writer w = dummy.openWriter();
- w.close();
+ filer.getGeneratedSourceNames().add("lombok.dummy.ForceNewRound" + (dummyCount++));
} catch (Exception e) {
e.printStackTrace();
processingEnv.getMessager().printMessage(Kind.WARNING,
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index 1038f116..609adbd6 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2018 The Project Lombok Authors.
+ * Copyright (C) 2013-2019 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
@@ -405,11 +405,15 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
makeSetterMethodsForBuilder(builderType, bfd, annotationNode, fluent, chain);
}
- if (methodExists(buildMethodName, builderType, -1) == MemberExistsResult.NOT_EXISTS) {
- JCMethodDecl md = generateBuildMethod(tdParent, isStatic, buildMethodName, nameOfBuilderMethod, returnType, builderFields, builderType, thrownExceptions, ast, addCleaning);
- if (md != null) {
- injectMethod(builderType, md);
- recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
+ {
+ MemberExistsResult methodExists = methodExists(builderMethodName, builderType, -1);
+ if (methodExists == MemberExistsResult.EXISTS_BY_LOMBOK) methodExists = methodExists(buildMethodName, builderType, 0);
+ if (methodExists == MemberExistsResult.NOT_EXISTS) {
+ JCMethodDecl md = generateBuildMethod(tdParent, isStatic, buildMethodName, nameOfBuilderMethod, returnType, builderFields, builderType, thrownExceptions, ast, addCleaning);
+ if (md != null) {
+ injectMethod(builderType, md);
+ recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
+ }
}
}
@@ -701,13 +705,13 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
public void makeSetterMethodsForBuilder(JavacNode builderType, BuilderFieldData fieldNode, JavacNode source, boolean fluent, boolean chain) {
boolean deprecate = isFieldDeprecated(fieldNode.originalFieldNode);
if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) {
- makeSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, fluent, chain, fieldNode.annotations);
+ makeSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, fluent, chain, fieldNode.annotations, fieldNode.originalFieldNode);
} else {
fieldNode.singularData.getSingularizer().generateMethods(fieldNode.singularData, deprecate, builderType, source.get(), fluent, chain);
}
}
- private void makeSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, List<JCAnnotation> annosOnParam) {
+ private void makeSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, List<JCAnnotation> annosOnParam, JavacNode originalFieldNode) {
Name fieldName = ((JCVariableDecl) fieldNode.get()).name;
for (JavacNode child : builderType.down()) {
@@ -723,6 +727,8 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, nameOfSetFlag, chain, source, List.<JCAnnotation>nil(), annosOnParam);
recursiveSetGeneratedBy(newMethod, source.get(), builderType.getContext());
+ copyJavadoc(originalFieldNode, newMethod, CopyJavadoc.SETTER);
+
injectMethod(builderType, newMethod);
}
diff --git a/src/core/lombok/javac/handlers/HandleHelper.java b/src/core/lombok/javac/handlers/HandleHelper.java
index 09ace4d6..6f4361c1 100644..100755
--- a/src/core/lombok/javac/handlers/HandleHelper.java
+++ b/src/core/lombok/javac/handlers/HandleHelper.java
@@ -102,7 +102,7 @@ public class HandleHelper extends JavacAnnotationHandler<Helper> {
}
Collections.sort(knownMethodNames);
- final String[] knownMethodNames_ = knownMethodNames.toArray(new String[knownMethodNames.size()]);
+ final String[] knownMethodNames_ = knownMethodNames.toArray(new String[0]);
final Name helperName = annotationNode.toName("$" + annotatedType_.name);
final boolean[] helperUsed = new boolean[1];
diff --git a/src/core/lombok/javac/handlers/HandleNonNull.java b/src/core/lombok/javac/handlers/HandleNonNull.java
index 81aa1525..9a81ffff 100644
--- a/src/core/lombok/javac/handlers/HandleNonNull.java
+++ b/src/core/lombok/javac/handlers/HandleNonNull.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 The Project Lombok Authors.
+ * Copyright (C) 2013-2019 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
@@ -74,12 +74,24 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> {
return;
}
- if (annotationNode.up().getKind() != Kind.ARGUMENT) return;
-
JCMethodDecl declaration;
+ JavacNode paramNode;
+
+ 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;
try {
- declaration = (JCMethodDecl) annotationNode.up().up().get();
+ declaration = (JCMethodDecl) paramNode.up().get();
} catch (Exception e) {
return;
}
@@ -93,7 +105,7 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> {
// and if they exist, create a new method in the class: 'private static <T> T lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and
// wrap all references to it in the super/this to a call to this method.
- JCStatement nullCheck = recursiveSetGeneratedBy(generateNullCheck(annotationNode.getTreeMaker(), annotationNode.up(), annotationNode), ast, annotationNode.getContext());
+ JCStatement nullCheck = recursiveSetGeneratedBy(generateNullCheck(annotationNode.getTreeMaker(), paramNode, annotationNode), ast, annotationNode.getContext());
if (nullCheck == null) {
// @NonNull applied to a primitive. Kinda pointless. Let's generate a warning.
@@ -103,7 +115,7 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> {
List<JCStatement> statements = declaration.body.stats;
- String expectedName = annotationNode.up().getName();
+ String expectedName = paramNode.getName();
/* Abort if the null check is already there, delving into try and synchronized statements */ {
List<JCStatement> stats = statements;
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 5fd17388..f08098d2 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -1462,7 +1462,7 @@ public class JavacHandlerUtil {
* variable name as message.
*/
public static JCStatement generateNullCheck(JavacTreeMaker maker, JavacNode variable, JavacNode source) {
- return generateNullCheck(maker, variable, (JCVariableDecl)variable.get(), source);
+ return generateNullCheck(maker, variable, (JCVariableDecl) variable.get(), source);
}
/**
diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java
index 69898668..9582c3b8 100644..100755
--- a/src/delombok/lombok/delombok/Delombok.java
+++ b/src/delombok/lombok/delombok/Delombok.java
@@ -426,7 +426,7 @@ public class Delombok {
throw new IOException("Unclosed ' in @ file");
}
- return x.toArray(new String[x.size()]);
+ return x.toArray(new String[0]);
}
public static class InvalidFormatOptionException extends Exception {
diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java
index 3fb1f1b1..84c342f0 100644
--- a/src/delombok/lombok/delombok/PrettyPrinter.java
+++ b/src/delombok/lombok/delombok/PrettyPrinter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Project Lombok Authors.
+ * Copyright (C) 2016-2019 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
@@ -258,6 +258,7 @@ public class PrettyPrinter extends JCTree.Visitor {
JCMethodInvocation inv = (JCMethodInvocation) expr;
if (!inv.typeargs.isEmpty() || !inv.args.isEmpty()) return false;
if (!(inv.meth instanceof JCIdent)) return false;
+ if (tree.pos != expr.pos) return false; // Explicit super call
return ((JCIdent) inv.meth).name.toString().equals("super");
}
}
@@ -377,6 +378,9 @@ public class PrettyPrinter extends JCTree.Visitor {
private int dims(JCExpression vartype) {
if (vartype instanceof JCArrayTypeTree) {
return 1 + dims(((JCArrayTypeTree) vartype).elemtype);
+ } else if (isJcAnnotatedType(vartype)) {
+ JCTree underlyingType = readObject(vartype, "underlyingType", (JCTree) null);
+ if (underlyingType instanceof JCArrayTypeTree) return 1 + dims (((JCArrayTypeTree) underlyingType).elemtype);
}
return 0;
@@ -624,13 +628,29 @@ public class PrettyPrinter extends JCTree.Visitor {
printVarDef0(tree);
}
+ private boolean innermostArrayBracketsAreVarargs = false;
private void printVarDef0(JCVariableDecl tree) {
boolean varargs = (tree.mods.flags & VARARGS) != 0;
- if (varargs && tree.vartype instanceof JCArrayTypeTree) {
- print(((JCArrayTypeTree) tree.vartype).elemtype);
- print("...");
- } else {
+
+ /* story time!
+
+ in 'new int[5][6];', the 5 is the outermost and the 6 is the innermost: That means: 5 int arrays, each capable of containing 6 elements.
+ But that's actually a crazy way to read it; you'd think that in FOO[], you should interpret that as 'an array of FOO', but that's not correct;
+ if FOO is for example 'int[]', it's: "Modify the component type of FOO to be an array of whatever it was before.. unless FOO isn't an array, in which case,
+ this is an array of FOO". Which is weird.
+
+ This is particularly poignant with vargs. In: "int[]... x", the ... are actually the _INNER_ type even though varargs by definition is a modification of
+ how to interpret the outer. The JLS just sort of lets that be: To indicate varargs, replace the lexically last [] with dots even though that's the wrong
+ [] to modify!
+
+ This becomes an utter shambles when annotations-on-arrays become involved. The annotation on the INNER most type is to be placed right before the ...;
+ and because of that, we have to do crazy stuff with this innermostArrayBracketsAreVarargs flag.
+ */
+ try {
+ innermostArrayBracketsAreVarargs = varargs;
print(tree.vartype);
+ } finally {
+ innermostArrayBracketsAreVarargs = false;
}
print(" ");
print(tree.name);
@@ -774,10 +794,7 @@ public class PrettyPrinter extends JCTree.Visitor {
}
@Override public void visitTypeArray(JCArrayTypeTree tree) {
- JCTree elem = tree.elemtype;
- while (elem instanceof JCWildcard) elem = ((JCWildcard) elem).inner;
- print(elem);
- print("[]");
+ printTypeArray0(tree);
}
@Override public void visitNewArray(JCNewArray tree) {
@@ -1456,6 +1473,21 @@ public class PrettyPrinter extends JCTree.Visitor {
}
}
+ private boolean jcAnnotatedTypeInit = false;
+ private Class<?> jcAnnotatedTypeClass = null;
+
+ private boolean isJcAnnotatedType(Object o) {
+ if (o == null) return false;
+ if (jcAnnotatedTypeInit) return jcAnnotatedTypeClass == o.getClass();
+ Class<?> c = o.getClass();
+ if (c.getSimpleName().equals("JCAnnotatedType")) {
+ jcAnnotatedTypeClass = c;
+ jcAnnotatedTypeInit = true;
+ return true;
+ }
+ return false;
+ }
+
private void printMemberReference0(JCTree tree) {
print(readObject(tree, "expr", (JCExpression) null));
print("::");
@@ -1514,10 +1546,57 @@ public class PrettyPrinter extends JCTree.Visitor {
print(readObject(tree, "annotations", List.<JCExpression>nil()), " ");
print(" ");
print(((JCFieldAccess) underlyingType).name);
+ } else if (underlyingType instanceof JCArrayTypeTree) {
+ printTypeArray0(tree);
} else {
print(readObject(tree, "annotations", List.<JCExpression>nil()), " ");
print(" ");
print(underlyingType);
}
}
+
+ private void printTypeArray0(JCTree tree) {
+ JCTree inner = tree;
+ int dimCount = 0;
+
+ while (true) {
+ if (inner instanceof JCArrayTypeTree) {
+ inner = ((JCArrayTypeTree) inner).elemtype;
+ dimCount++;
+ continue;
+ } else if (isJcAnnotatedType(inner)) {
+ JCTree underlyingType = readObject(inner, "underlyingType", (JCTree) null);
+ if (underlyingType instanceof JCArrayTypeTree) {
+ inner = ((JCArrayTypeTree) underlyingType).elemtype;
+ dimCount++;
+ continue;
+ }
+ }
+ break;
+ }
+
+ print(inner);
+
+ inner = tree;
+ while (true) {
+ if (inner instanceof JCArrayTypeTree) {
+ dimCount--;
+ print((dimCount == 0 && innermostArrayBracketsAreVarargs) ? "..." : "[]");
+ inner = ((JCArrayTypeTree) inner).elemtype;
+ continue;
+ } else if (isJcAnnotatedType(inner)) {
+ JCTree underlyingType = readObject(inner, "underlyingType", (JCTree) null);
+ if (underlyingType instanceof JCArrayTypeTree) {
+ dimCount--;
+ print(" ");
+ print(readObject(inner, "annotations", List.<JCExpression>nil()), " ");
+ print(" ");
+ print((dimCount == 0 && innermostArrayBracketsAreVarargs) ? "..." : "[]");
+ inner = ((JCArrayTypeTree) underlyingType).elemtype;
+ continue;
+ }
+ }
+ break;
+ }
+ }
}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
index a6d745b6..0e74dfaf 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2015 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 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
@@ -392,8 +392,8 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
private static void patchIdentifierEndReparse(ScriptManager sm) {
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "retrieveIdentifierEndPosition"))
- .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "fixRetrieveIdentifierEndPosition", "int", "int", "int"))
- .transplant().request(StackRequest.RETURN_VALUE, StackRequest.PARAM2).build());
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "fixRetrieveIdentifierEndPosition", "int", "int", "int", "int"))
+ .transplant().request(StackRequest.RETURN_VALUE, StackRequest.PARAM1, StackRequest.PARAM2).build());
}
private static void patchRetrieveEllipsisStartPosition(ScriptManager sm) {
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchDiagnostics.java b/src/eclipseAgent/lombok/eclipse/agent/PatchDiagnostics.java
index 82c4f522..157d92a3 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchDiagnostics.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchDiagnostics.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Project Lombok Authors.
+ * Copyright (C) 2012-2019 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
@@ -29,14 +29,19 @@ public class PatchDiagnostics {
* checks, and throw the exact same exception (thus, effectively, we don't change how eclipse operates), but, we <em>do</em> provide a useful message.
*/
public static boolean setSourceRangeCheck(Object astNode, int startPosition, int length) {
+ String nodeTxt;
if (startPosition >= 0 && length < 0) {
+ if (astNode == null) nodeTxt = "(NULL NODE)";
+ else nodeTxt = astNode.getClass() + ": " + astNode.toString();
throw new IllegalArgumentException("startPos = " + startPosition + " and length is " + length + ".\n" +
- "This breaks the rule that lengths are not allowed to be negative. Affected Node:\n" + astNode);
+ "This breaks the rule that lengths are not allowed to be negative. Affected Node:\n" + nodeTxt);
}
if (startPosition < 0 && length != 0) {
+ if (astNode == null) nodeTxt = "(NULL NODE)";
+ else nodeTxt = astNode.getClass() + ": " + astNode.toString();
throw new IllegalArgumentException("startPos = " + startPosition + " and length is " + length + ".\n" +
- "This breaks the rule that length must be 0 if startPosition is negative. Affected Node:\n" + astNode);
+ "This breaks the rule that length must be 0 if startPosition is negative. Affected Node:\n" + nodeTxt);
}
return false;
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java
index ace97a4d..085c903f 100644..100755
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java
@@ -78,7 +78,7 @@ public class PatchExtensionMethodCompletionProposal {
}
}
}
- return proposals.toArray(new IJavaCompletionProposal[proposals.size()]);
+ return proposals.toArray(new IJavaCompletionProposal[0]);
}
diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
index 3c70d81d..3741aba8 100644..100755
--- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java
+++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2015 The Project Lombok Authors.
+ * Copyright (C) 2010-2019 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
@@ -31,8 +31,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
-import lombok.eclipse.EclipseAugments;
-
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IAnnotatable;
import org.eclipse.jdt.core.IAnnotation;
@@ -64,6 +62,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.ASTNodeSearchUtil;
+import lombok.eclipse.EclipseAugments;
+
/** These contain a mix of the following:
* <ul>
* <li> 'dependency free' method wrappers that cross the shadowloader barrier.
@@ -476,8 +476,10 @@ final class PatchFixesHider {
return original == -1 ? start : original;
}
- public static int fixRetrieveIdentifierEndPosition(int original, int end) {
- return original == -1 ? end : original;
+ public static int fixRetrieveIdentifierEndPosition(int original, int start, int end) {
+ if (original == -1) return end;
+ if (original < start) return end;
+ return original;
}
public static int fixRetrieveEllipsisStartPosition(int original, int end) {
@@ -551,7 +553,7 @@ final class PatchFixesHider {
// Since Eclipse doesn't honor the "insert at specified location" for already existing members,
// we'll just add them last
newChildren.addAll(modifiedChildren);
- return newChildren.toArray(new RewriteEvent[newChildren.size()]);
+ return newChildren.toArray(new RewriteEvent[0]);
}
public static int getTokenEndOffsetFixed(TokenScanner scanner, int token, int startOffset, Object domNode) throws CoreException {
@@ -570,7 +572,7 @@ final class PatchFixesHider {
for (IMethod m : methods) {
if (m.getNameRange().getLength() > 0 && !m.getNameRange().equals(m.getSourceRange())) result.add(m);
}
- return result.size() == methods.length ? methods : result.toArray(new IMethod[result.size()]);
+ return result.size() == methods.length ? methods : result.toArray(new IMethod[0]);
}
public static SearchMatch[] removeGenerated(SearchMatch[] returnValue) {
@@ -591,7 +593,7 @@ final class PatchFixesHider {
}
result.add(searchResult);
}
- return result.toArray(new SearchMatch[result.size()]);
+ return result.toArray(new SearchMatch[0]);
}
public static SearchResultGroup[] createFakeSearchResult(SearchResultGroup[] returnValue,
diff --git a/src/utils/lombok/permit/Permit.java b/src/utils/lombok/permit/Permit.java
index 00b8274c..9f0434b8 100644
--- a/src/utils/lombok/permit/Permit.java
+++ b/src/utils/lombok/permit/Permit.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2018-20199 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.permit;
import java.lang.reflect.AccessibleObject;
@@ -84,6 +105,22 @@ public class Permit {
return setAccessible(f);
}
+ public static Field permissiveGetField(Class<?> c, String fName) {
+ try {
+ return getField(c, fName);
+ } catch (Exception ignore) {
+ return null;
+ }
+ }
+
+ public static <T> T permissiveReadField(Class<T> type, Field f, Object instance) {
+ try {
+ return type.cast(f.get(instance));
+ } catch (Exception ignore) {
+ return null;
+ }
+ }
+
public static <T> Constructor<T> getConstructor(Class<T> c, Class<?>... parameterTypes) throws NoSuchMethodException {
return setAccessible(c.getDeclaredConstructor(parameterTypes));
}