aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac
diff options
context:
space:
mode:
authorKevin Chirls <kchirls@users.noreply.github.com>2017-03-15 09:26:36 -0700
committerKevin Chirls <kchirls@users.noreply.github.com>2017-03-15 09:26:36 -0700
commitd146f362682654afd1a01c477836e72eadbd9e42 (patch)
tree5491f9510b0539fdfc2e8f188d6f1ef89c77242a /src/core/lombok/javac
parentf765730526e061d39c3ecd44f37de6a7f7887cf0 (diff)
parenta2c10c70fa8e2c8736464a5c3d445e2ca6e8a296 (diff)
downloadlombok-d146f362682654afd1a01c477836e72eadbd9e42.tar.gz
lombok-d146f362682654afd1a01c477836e72eadbd9e42.tar.bz2
lombok-d146f362682654afd1a01c477836e72eadbd9e42.zip
Merge remote-tracking branch 'rzwitserloot/master'
Diffstat (limited to 'src/core/lombok/javac')
-rw-r--r--src/core/lombok/javac/apt/Javac9BaseFileObjectWrapper.java113
-rw-r--r--src/core/lombok/javac/apt/LombokFileObjects.java78
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java20
-rw-r--r--src/core/lombok/javac/handlers/HandleConstructor.java44
-rw-r--r--src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java38
-rw-r--r--src/core/lombok/javac/handlers/HandleGetter.java2
-rw-r--r--src/core/lombok/javac/handlers/HandleSetter.java4
-rw-r--r--src/core/lombok/javac/handlers/HandleUtilityClass.java2
-rw-r--r--src/core/lombok/javac/handlers/HandleWither.java4
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java141
10 files changed, 313 insertions, 133 deletions
diff --git a/src/core/lombok/javac/apt/Javac9BaseFileObjectWrapper.java b/src/core/lombok/javac/apt/Javac9BaseFileObjectWrapper.java
new file mode 100644
index 00000000..f9fe2a7d
--- /dev/null
+++ b/src/core/lombok/javac/apt/Javac9BaseFileObjectWrapper.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2010-2017 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.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.net.URI;
+import java.nio.file.Path;
+
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.NestingKind;
+
+import com.sun.tools.javac.file.BaseFileManager;
+
+class Javac9BaseFileObjectWrapper extends com.sun.tools.javac.file.PathFileObject {
+ private final LombokFileObject delegate;
+
+ public Javac9BaseFileObjectWrapper(BaseFileManager fileManager, Path path, LombokFileObject delegate) {
+ super(fileManager, path);
+ this.delegate = delegate;
+ }
+
+ @Override public boolean isNameCompatible(String simpleName, Kind kind) {
+ return delegate.isNameCompatible(simpleName, kind);
+ }
+
+ @Override public URI toUri() {
+ return delegate.toUri();
+ }
+
+ @SuppressWarnings("all")
+ @Override public String getName() {
+ return delegate.getName();
+ }
+
+ @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return delegate.getCharContent(ignoreEncodingErrors);
+ }
+
+ @Override public InputStream openInputStream() throws IOException {
+ return delegate.openInputStream();
+ }
+
+ @Override public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
+ return delegate.openReader(ignoreEncodingErrors);
+ }
+
+ @Override public Writer openWriter() throws IOException {
+ return delegate.openWriter();
+ }
+
+ @Override public OutputStream openOutputStream() throws IOException {
+ return delegate.openOutputStream();
+ }
+
+ @Override public long getLastModified() {
+ return delegate.getLastModified();
+ }
+
+ @Override public boolean delete() {
+ return delegate.delete();
+ }
+
+ @Override public Kind getKind() {
+ return delegate.getKind();
+ }
+
+ @Override public NestingKind getNestingKind() {
+ return delegate.getNestingKind();
+ }
+
+ @Override public Modifier getAccessLevel() {
+ return delegate.getAccessLevel();
+ }
+
+ @Override public boolean equals(Object obj) {
+ if (!(obj instanceof Javac9BaseFileObjectWrapper)) {
+ return false;
+ }
+ return delegate.equals(((Javac9BaseFileObjectWrapper)obj).delegate);
+ }
+
+ @Override public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ @Override public String toString() {
+ return delegate.toString();
+ }
+} \ No newline at end of file
diff --git a/src/core/lombok/javac/apt/LombokFileObjects.java b/src/core/lombok/javac/apt/LombokFileObjects.java
index 412e449b..7e818cab 100644
--- a/src/core/lombok/javac/apt/LombokFileObjects.java
+++ b/src/core/lombok/javac/apt/LombokFileObjects.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 The Project Lombok Authors.
+ * Copyright (C) 2010-2017 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
@@ -23,19 +23,24 @@
package lombok.javac.apt;
import java.lang.reflect.Method;
+import java.net.URI;
+import java.nio.file.Paths;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
+import com.sun.tools.javac.file.BaseFileManager;
+
import lombok.core.DiagnosticsReceiver;
//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 {
- enum Compiler {
- JAVAC6 {
+
+ interface Compiler {
+ Compiler JAVAC6 = new Compiler() {
private Method decoderMethod = null;
private final AtomicBoolean decoderIsSet = new AtomicBoolean();
@@ -46,13 +51,13 @@ final class LombokFileObjects {
@Override public Method getDecoderMethod() {
synchronized (decoderIsSet) {
if (decoderIsSet.get()) return decoderMethod;
- decoderMethod = getDecoderMethod("com.sun.tools.javac.util.BaseFileObject");
+ decoderMethod = LombokFileObjects.getDecoderMethod("com.sun.tools.javac.util.BaseFileObject");
decoderIsSet.set(true);
return decoderMethod;
}
}
- },
- JAVAC7 {
+ };
+ Compiler JAVAC7 = new Compiler() {
private Method decoderMethod = null;
private final AtomicBoolean decoderIsSet = new AtomicBoolean();
@@ -63,28 +68,28 @@ final class LombokFileObjects {
@Override public Method getDecoderMethod() {
synchronized (decoderIsSet) {
if (decoderIsSet.get()) return decoderMethod;
- decoderMethod = getDecoderMethod("com.sun.tools.javac.file.BaseFileObject");
+ decoderMethod = LombokFileObjects.getDecoderMethod("com.sun.tools.javac.file.BaseFileObject");
decoderIsSet.set(true);
return decoderMethod;
}
}
};
- static Method getDecoderMethod(String className) {
- Method m = null;
- try {
- m = Class.forName(className).getDeclaredMethod("getDecoder", boolean.class);
- m.setAccessible(true);
- } catch (NoSuchMethodException e) {
- // Intentional fallthrough - getDecoder(boolean) is not always present.
- } catch (ClassNotFoundException e) {
- // Intentional fallthrough - getDecoder(boolean) is not always present.
- }
- return m;
- }
+ JavaFileObject wrap(LombokFileObject fileObject);
+ Method getDecoderMethod();
+ }
- abstract JavaFileObject wrap(LombokFileObject fileObject);
- abstract Method getDecoderMethod();
+ static Method getDecoderMethod(String className) {
+ Method m = null;
+ try {
+ m = Class.forName(className).getDeclaredMethod("getDecoder", boolean.class);
+ m.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ // Intentional fallthrough - getDecoder(boolean) is not always present.
+ } catch (ClassNotFoundException e) {
+ // Intentional fallthrough - getDecoder(boolean) is not always present.
+ }
+ return m;
}
private LombokFileObjects() {}
@@ -93,7 +98,16 @@ final class LombokFileObjects {
String jfmClassName = jfm != null ? jfm.getClass().getName() : "null";
if (jfmClassName.equals("com.sun.tools.javac.util.DefaultFileManager")) return Compiler.JAVAC6;
if (jfmClassName.equals("com.sun.tools.javac.util.JavacFileManager")) return Compiler.JAVAC6;
- if (jfmClassName.equals("com.sun.tools.javac.file.JavacFileManager")) return Compiler.JAVAC7;
+ if (jfmClassName.equals("com.sun.tools.javac.file.JavacFileManager")) {
+ try {
+ Class<?> superType = Class.forName("com.sun.tools.javac.file.BaseFileManager");
+ if (superType.isInstance(jfm)) {
+ return new Java9Compiler(jfm);
+ }
+ }
+ catch (Exception e) {}
+ return Compiler.JAVAC7;
+ }
try {
if (Class.forName("com.sun.tools.javac.file.BaseFileObject") == null) throw new NullPointerException();
return Compiler.JAVAC7;
@@ -112,4 +126,24 @@ final class LombokFileObjects {
static JavaFileObject createIntercepting(Compiler compiler, JavaFileObject delegate, String fileName, DiagnosticsReceiver diagnostics) {
return compiler.wrap(new InterceptingJavaFileObject(delegate, fileName, diagnostics, compiler.getDecoderMethod()));
}
+
+ static class Java9Compiler implements Compiler {
+ private final BaseFileManager fileManager;
+
+ public Java9Compiler(JavaFileManager jfm) {
+ fileManager = (BaseFileManager) jfm;
+ }
+
+ @Override public JavaFileObject wrap(LombokFileObject fileObject) {
+ URI uri = fileObject.toUri();
+ if (uri.getScheme() == null) {
+ uri = URI.create("file://" + uri);
+ }
+ return new Javac9BaseFileObjectWrapper(fileManager, Paths.get(uri), fileObject);
+ }
+
+ @Override public Method getDecoderMethod() {
+ throw new UnsupportedOperationException();
+ }
+ }
}
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index 8588fc16..4c670433 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -155,7 +155,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
allFields.append(fieldNode);
}
- new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, List.<JCAnnotation>nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, null, annotationNode);
+ new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, List.<JCAnnotation>nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, annotationNode);
returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams);
typeParams = td.typarams;
@@ -270,8 +270,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
if (pos == -1 || tpOnType.size() <= pos) {
- annotationNode.addError("**" + returnType.getClass().toString());
-// annotationNode.addError("@Builder(toBuilder=true) requires that each type parameter on the static method is part of the typeargs of the return value. Type parameter " + tp.name + " is not part of the return type.");
+ annotationNode.addError("@Builder(toBuilder=true) requires that each type parameter on the static method is part of the typeargs of the return value. Type parameter " + tp.name + " is not part of the return type.");
return;
}
typeArgsForToBuilder.add(tpOnType.get(pos).name);
@@ -298,7 +297,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JavacNode builderType = findInnerClass(tdParent, builderClassName);
if (builderType == null) {
- builderType = makeBuilderClass(isStatic, tdParent, builderClassName, typeParams, ast);
+ builderType = makeBuilderClass(isStatic, annotationNode, tdParent, builderClassName, typeParams, ast);
} else {
JCClassDecl builderTypeDeclaration = (JCClassDecl) builderType.get();
if (isStatic && !builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) {
@@ -320,7 +319,6 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
}
}
-
}
for (BuilderFieldData bfd : builderFields) {
@@ -350,7 +348,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
if (constructorExists(builderType) == MemberExistsResult.NOT_EXISTS) {
- JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PACKAGE, List.<JCAnnotation>nil(), builderType, List.<JavacNode>nil(), false, null, annotationNode);
+ JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PACKAGE, List.<JCAnnotation>nil(), builderType, List.<JavacNode>nil(), false, annotationNode);
if (cd != null) injectMethod(builderType, cd);
}
@@ -375,7 +373,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
if (addCleaning) injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
- JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, tdParent, typeParams);
+ JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, annotationNode, tdParent, typeParams);
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
if (md != null) injectMethod(tdParent, md);
}
@@ -550,7 +548,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName(buildName), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null);
}
- public JCMethodDecl generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, JavacNode type, List<JCTypeParameter> typeParams) {
+ public JCMethodDecl generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, JavacNode source, JavacNode type, List<JCTypeParameter> typeParams) {
JavacTreeMaker maker = type.getTreeMaker();
ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
@@ -564,7 +562,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
int modifiers = Flags.PUBLIC;
if (isStatic) modifiers |= Flags.STATIC;
- return maker.MethodDef(maker.Modifiers(modifiers), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(maker, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
+ return maker.MethodDef(maker.Modifiers(modifiers), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(source, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
}
public void generateBuilderFields(JavacNode builderType, java.util.List<BuilderFieldData> builderFields, JCTree source) {
@@ -629,12 +627,12 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
return null;
}
- public JavacNode makeBuilderClass(boolean isStatic, JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast) {
+ public JavacNode makeBuilderClass(boolean isStatic, JavacNode source, JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast) {
JavacTreeMaker maker = tdParent.getTreeMaker();
int modifiers = Flags.PUBLIC;
if (isStatic) modifiers |= Flags.STATIC;
JCModifiers mods = maker.Modifiers(modifiers);
- JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(maker, typeParams), null, List.<JCExpression>nil(), List.<JCTree>nil());
+ JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(source, typeParams), null, List.<JCExpression>nil(), List.<JCTree>nil());
return injectType(tdParent, builder);
}
diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java
index 5f523ce6..25e96d75 100644
--- a/src/core/lombok/javac/handlers/HandleConstructor.java
+++ b/src/core/lombok/javac/handlers/HandleConstructor.java
@@ -71,14 +71,14 @@ public class HandleConstructor {
deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
JavacNode typeNode = annotationNode.up();
if (!checkLegality(typeNode, annotationNode, NoArgsConstructor.class.getSimpleName())) return;
- List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor=", annotationNode);
+ List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor", annotationNode);
NoArgsConstructor ann = annotation.getInstance();
AccessLevel level = ann.access();
if (level == AccessLevel.NONE) return;
String staticName = ann.staticName();
boolean force = ann.force();
List<JavacNode> fields = force ? findFinalFields(typeNode) : List.<JavacNode>nil();
- new HandleConstructor().generateConstructor(typeNode, level, onConstructor, fields, force, staticName, SkipIfConstructorExists.NO, null, annotationNode);
+ new HandleConstructor().generateConstructor(typeNode, level, onConstructor, fields, force, staticName, SkipIfConstructorExists.NO, annotationNode);
}
}
@@ -91,19 +91,16 @@ public class HandleConstructor {
deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
JavacNode typeNode = annotationNode.up();
if (!checkLegality(typeNode, annotationNode, RequiredArgsConstructor.class.getSimpleName())) return;
- List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@RequiredArgsConstructor(onConstructor=", annotationNode);
+ List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@RequiredArgsConstructor(onConstructor", annotationNode);
RequiredArgsConstructor ann = annotation.getInstance();
AccessLevel level = ann.access();
if (level == AccessLevel.NONE) return;
String staticName = ann.staticName();
- Boolean suppressConstructorProperties = null;
if (annotation.isExplicit("suppressConstructorProperties")) {
- @SuppressWarnings("deprecation")
- boolean suppress = ann.suppressConstructorProperties();
- suppressConstructorProperties = suppress;
+ annotationNode.addError("This deprecated feature is no longer supported. Remove it; you can create a lombok.config file with 'lombok.anyConstructor.suppressConstructorProperties = true'.");
}
- new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findRequiredFields(typeNode), false, staticName, SkipIfConstructorExists.NO, suppressConstructorProperties, annotationNode);
+ new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findRequiredFields(typeNode), false, staticName, SkipIfConstructorExists.NO, annotationNode);
}
}
@@ -141,18 +138,15 @@ public class HandleConstructor {
deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
JavacNode typeNode = annotationNode.up();
if (!checkLegality(typeNode, annotationNode, AllArgsConstructor.class.getSimpleName())) return;
- List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor=", annotationNode);
+ List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor", annotationNode);
AllArgsConstructor ann = annotation.getInstance();
AccessLevel level = ann.access();
if (level == AccessLevel.NONE) return;
String staticName = ann.staticName();
- Boolean suppressConstructorProperties = null;
if (annotation.isExplicit("suppressConstructorProperties")) {
- @SuppressWarnings("deprecation")
- boolean suppress = ann.suppressConstructorProperties();
- suppressConstructorProperties = suppress;
+ annotationNode.addError("This deprecated feature is no longer supported. Remove it; you can create a lombok.config file with 'lombok.anyConstructor.suppressConstructorProperties = true'.");
}
- new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findAllFields(typeNode), false, staticName, SkipIfConstructorExists.NO, suppressConstructorProperties, annotationNode);
+ new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findAllFields(typeNode), false, staticName, SkipIfConstructorExists.NO, annotationNode);
}
}
@@ -188,7 +182,7 @@ public class HandleConstructor {
}
public void generateRequiredArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) {
- generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findRequiredFields(typeNode), false, staticName, skipIfConstructorExists, null, source);
+ generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findRequiredFields(typeNode), false, staticName, skipIfConstructorExists, source);
}
public enum SkipIfConstructorExists {
@@ -196,10 +190,10 @@ public class HandleConstructor {
}
public void generateAllArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) {
- generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findAllFields(typeNode), false, staticName, skipIfConstructorExists, null, source);
+ generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findAllFields(typeNode), false, staticName, skipIfConstructorExists, source);
}
- public void generateConstructor(JavacNode typeNode, AccessLevel level, List<JCAnnotation> onConstructor, List<JavacNode> fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, Boolean suppressConstructorProperties, JavacNode source) {
+ public void generateConstructor(JavacNode typeNode, AccessLevel level, List<JCAnnotation> onConstructor, List<JavacNode> fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) {
boolean staticConstrRequired = staticName != null && !staticName.equals("");
if (skipIfConstructorExists != SkipIfConstructorExists.NO && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS) return;
@@ -228,7 +222,7 @@ public class HandleConstructor {
}
}
- JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, onConstructor, typeNode, fields, allToDefault, suppressConstructorProperties, source);
+ JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, onConstructor, typeNode, fields, allToDefault, source);
ListBuffer<Type> argTypes = new ListBuffer<Type>();
for (JavacNode fieldNode : fields) {
Type mirror = getMirrorForFieldType(fieldNode);
@@ -262,18 +256,18 @@ public class HandleConstructor {
mods.annotations = mods.annotations.append(annotation);
}
- public static JCMethodDecl createConstructor(AccessLevel level, List<JCAnnotation> onConstructor, JavacNode typeNode, List<JavacNode> fields, boolean allToDefault, Boolean suppressConstructorProperties, JavacNode source) {
+ public static JCMethodDecl createConstructor(AccessLevel level, List<JCAnnotation> onConstructor, JavacNode typeNode, List<JavacNode> fields, boolean allToDefault, JavacNode source) {
JavacTreeMaker maker = typeNode.getTreeMaker();
boolean isEnum = (((JCClassDecl) typeNode.get()).mods.flags & Flags.ENUM) != 0;
if (isEnum) level = AccessLevel.PRIVATE;
- if (suppressConstructorProperties == null) {
- if (fields.isEmpty()) {
- suppressConstructorProperties = false;
- } else {
- suppressConstructorProperties = Boolean.TRUE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES));
- }
+ boolean suppressConstructorProperties;
+
+ if (fields.isEmpty()) {
+ suppressConstructorProperties = false;
+ } else {
+ suppressConstructorProperties = Boolean.TRUE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES));
}
ListBuffer<JCStatement> nullChecks = new ListBuffer<JCStatement>();
diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
index f34b4f6b..6df56ed6 100644
--- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
@@ -95,7 +95,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
List<String> excludes = List.from(ann.exclude());
List<String> includes = List.from(ann.of());
JavacNode typeNode = annotationNode.up();
- List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@EqualsAndHashCode(onParam=", annotationNode);
+ List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@EqualsAndHashCode(onParam", annotationNode);
checkForBogusFieldNames(typeNode, annotation);
Boolean callSuper = ann.callSuper();
@@ -363,7 +363,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
return maker.TypeCast(maker.TypeIdent(CTC_INT), maker.Parens(xorBits));
}
- public JCExpression createTypeReference(JavacNode type) {
+ public JCExpression createTypeReference(JavacNode type, boolean addWildcards) {
java.util.List<String> list = new ArrayList<String>();
list.add(type.getName());
JavacNode tNode = type.up();
@@ -372,20 +372,28 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
tNode = tNode.up();
}
Collections.reverse(list);
+ JCClassDecl typeDecl = (JCClassDecl) type.get();
JavacTreeMaker maker = type.getTreeMaker();
+
JCExpression chain = maker.Ident(type.toName(list.get(0)));
for (int i = 1; i < list.size(); i++) {
chain = maker.Select(chain, type.toName(list.get(i)));
}
- return chain;
+ if (!addWildcards || typeDecl.typarams.length() == 0) return chain;
+
+ ListBuffer<JCExpression> wildcards = new ListBuffer<JCExpression>();
+ for (int i = 0 ; i < typeDecl.typarams.length() ; i++) {
+ wildcards.append(maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null));
+ }
+
+ return maker.TypeApply(chain, wildcards.toList());
}
public JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source, List<JCAnnotation> onParam) {
JavacTreeMaker maker = typeNode.getTreeMaker();
- JCClassDecl type = (JCClassDecl) typeNode.get();
Name oName = typeNode.toName("o");
Name otherName = typeNode.toName("other");
@@ -408,27 +416,13 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
/* if (!(o instanceof Outer.Inner.MyType)) return false; */ {
- JCUnary notInstanceOf = maker.Unary(CTC_NOT, maker.Parens(maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode))));
+ JCUnary notInstanceOf = maker.Unary(CTC_NOT, maker.Parens(maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode, false))));
statements.append(maker.If(notInstanceOf, returnBool(maker, false), null));
}
- /* MyType<?> other = (MyType<?>) o; */ {
+ /* Outer.Inner.MyType<?> other = (Outer.Inner.MyType<?>) o; */ {
if (!fields.isEmpty() || needsCanEqual) {
- final JCExpression selfType1, selfType2;
- ListBuffer<JCExpression> wildcards1 = new ListBuffer<JCExpression>();
- ListBuffer<JCExpression> wildcards2 = new ListBuffer<JCExpression>();
- for (int i = 0 ; i < type.typarams.length() ; i++) {
- wildcards1.append(maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null));
- wildcards2.append(maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null));
- }
-
- if (type.typarams.isEmpty()) {
- selfType1 = maker.Ident(type.name);
- selfType2 = maker.Ident(type.name);
- } else {
- selfType1 = maker.TypeApply(maker.Ident(type.name), wildcards1.toList());
- selfType2 = maker.TypeApply(maker.Ident(type.name), wildcards2.toList());
- }
+ final JCExpression selfType1 = createTypeReference(typeNode, true), selfType2 = createTypeReference(typeNode, true);
statements.append(
maker.VarDef(maker.Modifiers(finalFlag), otherName, selfType1, maker.TypeCast(selfType2, maker.Ident(oName))));
@@ -533,7 +527,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(flags, onParam), otherName, objectType, null));
JCBlock body = maker.Block(0, List.<JCStatement>of(
- maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode)))));
+ maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode, false)))));
return recursiveSetGeneratedBy(maker.MethodDef(mods, canEqualName, returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source, typeNode.getContext());
}
diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java
index 60dbe8ee..5a2e1993 100644
--- a/src/core/lombok/javac/handlers/HandleGetter.java
+++ b/src/core/lombok/javac/handlers/HandleGetter.java
@@ -147,7 +147,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> {
if (node == null) return;
- List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod=", annotationNode);
+ List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod", annotationNode);
switch (node.getKind()) {
case FIELD:
diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java
index 02cc3775..e766127a 100644
--- a/src/core/lombok/javac/handlers/HandleSetter.java
+++ b/src/core/lombok/javac/handlers/HandleSetter.java
@@ -129,8 +129,8 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> {
if (level == AccessLevel.NONE || node == null) return;
- List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Setter(onMethod=", annotationNode);
- List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Setter(onParam=", annotationNode);
+ List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Setter(onMethod", annotationNode);
+ List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Setter(onParam", annotationNode);
switch (node.getKind()) {
case FIELD:
diff --git a/src/core/lombok/javac/handlers/HandleUtilityClass.java b/src/core/lombok/javac/handlers/HandleUtilityClass.java
index 6d3ec63b..ee8081d6 100644
--- a/src/core/lombok/javac/handlers/HandleUtilityClass.java
+++ b/src/core/lombok/javac/handlers/HandleUtilityClass.java
@@ -44,6 +44,7 @@ import com.sun.tools.javac.util.Name;
import lombok.ConfigurationKeys;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
+import lombok.core.HandlerPriority;
import lombok.experimental.UtilityClass;
import lombok.javac.Javac;
import lombok.javac.JavacAnnotationHandler;
@@ -53,6 +54,7 @@ import lombok.javac.JavacTreeMaker;
/**
* Handles the {@code @UtilityClass} annotation for javac.
*/
+@HandlerPriority(-4096) //-2^12; to ensure @FieldDefaults picks up on the 'static' we set here.
@ProviderFor(JavacAnnotationHandler.class)
public class HandleUtilityClass extends JavacAnnotationHandler<UtilityClass> {
@Override public void handle(AnnotationValues<UtilityClass> annotation, JCAnnotation ast, JavacNode annotationNode) {
diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java
index 8aec0240..987a3d34 100644
--- a/src/core/lombok/javac/handlers/HandleWither.java
+++ b/src/core/lombok/javac/handlers/HandleWither.java
@@ -131,8 +131,8 @@ public class HandleWither extends JavacAnnotationHandler<Wither> {
if (level == AccessLevel.NONE || node == null) return;
- List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Wither(onMethod=", annotationNode);
- List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Wither(onParam=", annotationNode);
+ List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Wither(onMethod", annotationNode);
+ List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Wither(onParam", annotationNode);
switch (node.getKind()) {
case FIELD:
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 949c9f5c..68d8061c 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -92,6 +92,7 @@ import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.JCTree.JCWildcard;
import com.sun.tools.javac.tree.JCTree.TypeBoundKind;
+import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -894,16 +895,20 @@ public class JavacHandlerUtil {
static class ClassSymbolMembersField {
private static final Field membersField;
private static final Method removeMethod;
+ private static final Method enterMethod;
static {
Field f = null;
- Method m = null;
+ Method r = null;
+ Method e = null;
try {
f = ClassSymbol.class.getField("members_field");
- m = f.getType().getMethod("remove", Symbol.class);
- } catch (Exception e) {}
+ r = f.getType().getMethod("remove", Symbol.class);
+ e = f.getType().getMethod("enter", Symbol.class);
+ } catch (Exception ex) {}
membersField = f;
- removeMethod = m;
+ removeMethod = r;
+ enterMethod = e;
}
static void remove(ClassSymbol from, Symbol toRemove) {
@@ -914,6 +919,15 @@ public class JavacHandlerUtil {
removeMethod.invoke(scope, toRemove);
} catch (Exception e) {}
}
+
+ static void enter(ClassSymbol from, Symbol toEnter) {
+ if (from == null) return;
+ try {
+ Scope scope = (Scope) membersField.get(from);
+ if (scope == null) return;
+ enterMethod.invoke(scope, toEnter);
+ } catch (Exception e) {}
+ }
}
public static void injectMethod(JavacNode typeNode, JCMethodDecl method) {
@@ -959,7 +973,7 @@ public class JavacHandlerUtil {
if (typeMirror == null || paramTypes == null || returnType == null) return;
ClassSymbol cs = (ClassSymbol) typeMirror;
MethodSymbol methodSymbol = new MethodSymbol(access, methodName, new MethodType(paramTypes, returnType, List.<Type>nil(), Symtab.instance(context).methodClass), cs);
- cs.members_field.enter(methodSymbol);
+ ClassSymbolMembersField.enter(cs, methodSymbol);
}
/**
@@ -1025,10 +1039,10 @@ public class JavacHandlerUtil {
public static void addGenerated(JCModifiers mods, JavacNode node, int pos, JCTree source, Context context) {
if (!LombokOptionsFactory.getDelombokOptions(context).getFormatPreferences().generateGenerated()) return;
- if (HandlerUtil.shouldAddGenerated(node, ConfigurationKeys.ADD_JAVAX_GENERATED_ANNOTATIONS)) {
+ if (HandlerUtil.shouldAddGenerated(node)) {
addAnnotation(mods, node, pos, source, context, "javax.annotation.Generated", node.getTreeMaker().Literal("lombok"));
}
- if (HandlerUtil.shouldAddGenerated(node, ConfigurationKeys.ADD_LOMBOK_GENERATED_ANNOTATIONS)) {
+ if (Boolean.TRUE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_LOMBOK_GENERATED_ANNOTATIONS))) {
addAnnotation(mods, node, pos, source, context, "lombok.Generated", null);
}
}
@@ -1233,19 +1247,9 @@ public class JavacHandlerUtil {
ListBuffer<JCExpression> params = new ListBuffer<JCExpression>();
ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
- try {
- for (JCExpression arg : ast.args) {
- String argName = "value";
- if (arg instanceof JCAssign) {
- JCAssign as = (JCAssign) arg;
- argName = as.lhs.toString();
- }
- if (!argName.equals(parameterName)) continue;
- }
- } catch (Exception ignore) {}
-
outer:
for (JCExpression param : ast.args) {
+ boolean allowRaw;
String nameOfParam = "value";
JCExpression valueOfParam = null;
if (param instanceof JCAssign) {
@@ -1257,6 +1261,15 @@ public class JavacHandlerUtil {
valueOfParam = assign.rhs;
}
+ /* strip trailing underscores */ {
+ int lastIdx;
+ for (lastIdx = nameOfParam.length() ; lastIdx > 0; lastIdx--) {
+ if (nameOfParam.charAt(lastIdx - 1) != '_') break;
+ }
+ allowRaw = lastIdx < nameOfParam.length();
+ nameOfParam = nameOfParam.substring(0, lastIdx);
+ }
+
if (!parameterName.equals(nameOfParam)) {
params.append(param);
continue outer;
@@ -1269,52 +1282,84 @@ public class JavacHandlerUtil {
String dummyAnnotationName = ((JCAnnotation) valueOfParam).annotationType.toString();
dummyAnnotationName = dummyAnnotationName.replace("_", "").replace("$", "").replace("x", "").replace("X", "");
if (dummyAnnotationName.length() > 0) {
- annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))");
- continue outer;
- }
- for (JCExpression expr : ((JCAnnotation) valueOfParam).args) {
- if (expr instanceof JCAssign && ((JCAssign) expr).lhs instanceof JCIdent) {
- JCIdent id = (JCIdent) ((JCAssign) expr).lhs;
- if ("value".equals(id.name.toString())) {
- expr = ((JCAssign) expr).rhs;
- } else {
- annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))");
- continue outer;
- }
+ if (allowRaw) {
+ result.append((JCAnnotation) valueOfParam);
+ } else {
+ addError(errorName, annotationNode);
+ continue outer;
}
-
- if (expr instanceof JCAnnotation) {
- result.append((JCAnnotation) expr);
- } else if (expr instanceof JCNewArray) {
- for (JCExpression expr2 : ((JCNewArray) expr).elems) {
- if (expr2 instanceof JCAnnotation) {
- result.append((JCAnnotation) expr2);
+ } else {
+ for (JCExpression expr : ((JCAnnotation) valueOfParam).args) {
+ if (expr instanceof JCAssign && ((JCAssign) expr).lhs instanceof JCIdent) {
+ JCIdent id = (JCIdent) ((JCAssign) expr).lhs;
+ if ("value".equals(id.name.toString())) {
+ expr = ((JCAssign) expr).rhs;
} else {
- annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))");
- continue outer;
+ addError(errorName, annotationNode);
}
}
- } else {
- annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))");
- continue outer;
+
+ if (expr instanceof JCAnnotation) {
+ result.append((JCAnnotation) expr);
+ } else if (expr instanceof JCNewArray) {
+ for (JCExpression expr2 : ((JCNewArray) expr).elems) {
+ if (expr2 instanceof JCAnnotation) {
+ result.append((JCAnnotation) expr2);
+ } else {
+ addError(errorName, annotationNode);
+ continue outer;
+ }
+ }
+ } else {
+ addError(errorName, annotationNode);
+ continue outer;
+ }
}
}
- } else {
- if (valueOfParam instanceof JCNewArray && ((JCNewArray) valueOfParam).elems.isEmpty()) {
- // Then we just remove it and move on (it's onMethod={} for example).
+ } else if (valueOfParam instanceof JCNewArray) {
+ JCNewArray arr = (JCNewArray) valueOfParam;
+ if (arr.elems.isEmpty()) {
+ // Just remove it, this is always fine.
+ } else if (allowRaw) {
+ for (JCExpression jce : arr.elems) {
+ if (jce instanceof JCAnnotation) result.append((JCAnnotation) jce);
+ else addError(errorName, annotationNode);
+ }
} else {
- annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))");
+ addError(errorName, annotationNode);
}
+ } else {
+ addError(errorName, annotationNode);
}
}
ast.args = params.toList();
return result.toList();
}
- public static List<JCTypeParameter> copyTypeParams(JavacTreeMaker maker, List<JCTypeParameter> params) {
+ private static void addError(String errorName, JavacNode node) {
+ if (node.getLatestJavaSpecSupported() < 8) {
+ node.addError("The correct format up to JDK7 is " + errorName + "=@__({@SomeAnnotation, @SomeOtherAnnotation}))");
+ } else {
+ node.addError("The correct format for JDK8+ is " + errorName + "_={@SomeAnnotation, @SomeOtherAnnotation})");
+ }
+ }
+
+ public static List<JCTypeParameter> copyTypeParams(JavacNode source, List<JCTypeParameter> params) {
if (params == null || params.isEmpty()) return params;
ListBuffer<JCTypeParameter> out = new ListBuffer<JCTypeParameter>();
- for (JCTypeParameter tp : params) out.append(maker.TypeParameter(tp.name, tp.bounds));
+ JavacTreeMaker maker = source.getTreeMaker();
+ Context context = source.getContext();
+ for (JCTypeParameter tp : params) {
+ List<JCExpression> bounds = tp.bounds;
+ if (bounds != null && !bounds.isEmpty()) {
+ ListBuffer<JCExpression> boundsCopy = new ListBuffer<JCExpression>();
+ for (JCExpression expr : tp.bounds) {
+ boundsCopy.append(cloneType(maker, expr, source.get(), context));
+ }
+ bounds = boundsCopy.toList();
+ }
+ out.append(maker.TypeParameter(tp.name, bounds));
+ }
return out.toList();
}