aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--build.xml21
-rw-r--r--buildScripts/ivy.xml3
-rw-r--r--doc/changelog.markdown5
-rw-r--r--jitpack.yml4
-rw-r--r--src/core/lombok/core/AST.java12
-rw-r--r--src/core/lombok/core/AnnotationProcessor.java15
-rw-r--r--src/core/lombok/core/LombokInternalAliasing.java6
-rw-r--r--src/core/lombok/core/LombokNode.java38
-rw-r--r--src/core/lombok/core/configuration/StringConfigurationSource.java1
-rw-r--r--src/core/lombok/eclipse/EclipseASTAdapter.java7
-rw-r--r--src/core/lombok/eclipse/EclipseASTVisitor.java6
-rw-r--r--src/core/lombok/eclipse/EclipseNode.java10
-rw-r--r--src/core/lombok/eclipse/HandlerLibrary.java24
-rw-r--r--src/core/lombok/eclipse/TransformEclipseAST.java26
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java26
-rw-r--r--src/core/lombok/eclipse/handlers/HandleBuilder.java36
-rw-r--r--src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java26
-rw-r--r--src/core/lombok/eclipse/handlers/HandleSuperBuilder.java2
-rw-r--r--src/core/lombok/javac/JavacNode.java9
-rw-r--r--src/core/lombok/javac/apt/LombokProcessor.java26
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java28
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java9
-rw-r--r--src/core9/module-info.java2
-rw-r--r--src/eclipseAgent/lombok/launch/PatchFixesHider.java2
-rw-r--r--src/launch/lombok/launch/Agent.java2
-rw-r--r--src/launch/lombok/launch/AnnotationProcessor.java2
-rw-r--r--src/launch/lombok/launch/Main.java12
-rw-r--r--src/launch/lombok/launch/ShadowClassLoader.java28
-rw-r--r--src/utils/lombok/eclipse/Eclipse.java24
-rw-r--r--test/core/src/lombok/RunTestsViaEcj.java2
-rw-r--r--test/transform/resource/after-delombok/BuilderSingularToBuilderWithNull.java63
-rw-r--r--test/transform/resource/after-delombok/BuilderWithToBuilder.java2
-rw-r--r--test/transform/resource/after-ecj/BuilderSingularToBuilderWithNull.java57
-rw-r--r--test/transform/resource/after-ecj/BuilderWithToBuilder.java2
-rw-r--r--test/transform/resource/before/BuilderSingularToBuilderWithNull.java10
-rw-r--r--website/usageExamples/LogExample_post.jpage2
-rw-r--r--website/usageExamples/LogExample_pre.jpage2
38 files changed, 395 insertions, 158 deletions
diff --git a/AUTHORS b/AUTHORS
index 5246fde7..822c1161 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -19,6 +19,7 @@ Michiel Verheul <cheelio@gmail.com>
Pascal Bihler <pascal@qfs.de>
Peter Grant <petercgrant@users.noreply.github.com>
Philipp Eichhorn <peichhor@web.de>
+Philippe Charles <philippe.charles@nbb.be>
Rabea Gransberger <rgra@users.noreply.github.com>
Reinier Zwitserloot <reinier@zwitserloot.com>
Robbert Jan Grootjans <grootjans@gmail.com>
diff --git a/build.xml b/build.xml
index c1d13bd7..c50bf644 100644
--- a/build.xml
+++ b/build.xml
@@ -112,7 +112,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr
</target>
<target name="ensureBuildDeps" depends="config-ivy,ensureOpenJdk6Rt">
- <ivy:resolve file="buildScripts/ivy.xml" refresh="true" conf="build, javac7" />
+ <ivy:resolve file="buildScripts/ivy.xml" refresh="true" conf="build, javac7, moduleBuild" />
<ivy:retrieve />
</target>
@@ -163,15 +163,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr
<target name="-ensureJdk9">
<condition property="java.version.insufficient">
- <or>
- <equals arg1="${ant.java.version}" arg2="1.2" />
- <equals arg1="${ant.java.version}" arg2="1.3" />
- <equals arg1="${ant.java.version}" arg2="1.4" />
- <equals arg1="${ant.java.version}" arg2="1.5" />
- <equals arg1="${ant.java.version}" arg2="1.6" />
- <equals arg1="${ant.java.version}" arg2="1.7" />
- <equals arg1="${ant.java.version}" arg2="1.8" />
- </or>
+ <matches string="${java.version}" pattern="^1\.[2-8](\..*)?" />
</condition>
<fail if="java.version.insufficient">To compile lombok, you need JDK9 or higher; lombok requires this version because it's rather difficult to produce lombok builds that are compatible on JDK9 without at least building with JDK9. Sorry about that.</fail>
</target>
@@ -254,15 +246,18 @@ the common tasks and can be called on to run the main aspects of all the sub-scr
<classpath refid="build.path" />
</ivy:compile>
- <ivy:compile destdir="build/lombok" source="1.9" target="1.9">
+ <javac includeAntRuntime="false" source="1.9" target="1.9" destdir="build/lombok" modulepath="lib/moduleBuild">
<compilerarg value="-Xlint:none" />
<!-- The above is because javac9 warns about 'service interface provided but not exported or used', probably because lombok uses SPI internally, and uses the 'old' classpath discovery system for it. We're fine with this, hence, ignore this warning. -->
<src path="src/core9" />
+ </javac>
+ <mkdir dir="build/lombokMapstruct" />
+ <javac includeAntRuntime="false" source="1.9" target="1.9" destdir="build/lombokMapstruct">
<src path="src/j9stubs" />
<!-- This includes org.mapstruct.ap.spi.AstModifyingAnnotationProcessor; putting this on the classpath doesn't work (needs to be internal or a module) so we just add it and then delete the class file for convenience. -->
- </ivy:compile>
+ </javac>
<mkdir dir="build/lombok/secondaryLoading.SCL.lombok/org/mapstruct/ap/spi" />
- <move file="build/lombok/org/mapstruct/ap/spi/AstModifyingAnnotationProcessor.class" tofile="build/lombok/secondaryLoading.SCL.lombok/org/mapstruct/ap/spi/AstModifyingAnnotationProcessor.SCL.lombok" />
+ <move file="build/lombokMapstruct/org/mapstruct/ap/spi/AstModifyingAnnotationProcessor.class" tofile="build/lombok/secondaryLoading.SCL.lombok/org/mapstruct/ap/spi/AstModifyingAnnotationProcessor.SCL.lombok" />
<ivy:compile destdir="build/lombok/Class50" source="1.5" target="1.6" ecj="true" nowarn="true" includeSystemBootclasspath="true">
<bootclasspath location="build/stubs" />
diff --git a/buildScripts/ivy.xml b/buildScripts/ivy.xml
index c1ddc6fd..4eed2fa6 100644
--- a/buildScripts/ivy.xml
+++ b/buildScripts/ivy.xml
@@ -5,6 +5,7 @@
<conf name="netbeansBuild" />
<conf name="buildBase" extends="netbeansBuild, javac6" />
<conf name="build" extends="buildBase, eclipseBuild" />
+ <conf name="moduleBuild" />
<conf name="buildWithoutEclipse" extends="buildBase" />
<conf name="runtime" />
<conf name="test" extends="runtime" />
@@ -64,5 +65,7 @@
<dependency org="com.jcraft" name="jsch" rev="0.1.54" conf="supporters->default" />
<dependency org="com.rimerosolutions.ant" name="ant-git-tasks" rev="1.3.2" conf="supporters->default" />
<dependency org="org.slf4j" name="slf4j-simple" rev="1.6.1" conf="supporters->default" />
+
+ <dependency org="org.mapstruct" name="mapstruct-processor" rev="1.3.0.Beta1" conf="moduleBuild->default" />
</dependencies>
</ivy-module>
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index 238b4a38..a294d6a1 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -2,7 +2,10 @@ Lombok Changelog
----------------
### v1.18.3 "Edgy Guinea Pig"
-* FEATURE: THe `@FieldNameConstants` feature has been completely redesigned. [Issue #1774](https://github.com/rzwitserloot/lombok/issues/1774) [FieldNameConstants documentation](https://projectlombok.org/features/experimental/FieldNameConstants)
+* FEATURE: The `@FieldNameConstants` feature has been completely redesigned. [Issue #1774](https://github.com/rzwitserloot/lombok/issues/1774) [FieldNameConstants documentation](https://projectlombok.org/features/experimental/FieldNameConstants)
+* BUGFIX: When using lombok to compile modularized (`module-info.java`-style) code, if the module name has dots in it, it wouldn't work. [Issue #1808](https://github.com/rzwitserloot/lombok/issues/1808)
+* BUGFIX: Errors about lombok not reading a module providing `org.mapstruct.ap.spi` when trying to use lombok in jigsaw-mode on JDK 11. [Issue #1806](https://github.com/rzwitserloot/lombok/issues/1806)
+* BUGFIX: Fix NetBeans compile on save. [Issue #1770](https://github.com/rzwitserloot/lombok/issues/1770)
### v1.18.2 (July 26th, 2018)
* BUGFIX: mapstruct + lombok in eclipse should hopefully work again. [Issue #1359](https://github.com/rzwitserloot/lombok/issues/1359) and [mapstruct issue #1159](https://github.com/mapstruct/mapstruct/issues/1159)
diff --git a/jitpack.yml b/jitpack.yml
new file mode 100644
index 00000000..334e7acc
--- /dev/null
+++ b/jitpack.yml
@@ -0,0 +1,4 @@
+jdk:
+- openjdk9
+before_install:
+- export JAVA_HOME=/usr/lib/jvm/java-9-oracle
diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java
index 1142018f..fe7a4330 100644
--- a/src/core/lombok/core/AST.java
+++ b/src/core/lombok/core/AST.java
@@ -216,19 +216,19 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
}
}
- private static final ConcurrentMap<Class<?>, Collection<FieldAccess>> fieldsOfASTClasses = new ConcurrentHashMap<Class<?>, Collection<FieldAccess>>();
+ private static final ConcurrentMap<Class<?>, FieldAccess[]> fieldsOfASTClasses = new ConcurrentHashMap<Class<?>, FieldAccess[]>();
/** Returns FieldAccess objects for the stated class. Each field that contains objects of the kind returned by
* {@link #getStatementTypes()}, either directly or inside of an array or java.util.collection (or array-of-arrays,
* or collection-of-collections, et cetera), is returned.
*/
- protected Collection<FieldAccess> fieldsOf(Class<?> c) {
- Collection<FieldAccess> fields = fieldsOfASTClasses.get(c);
+ protected FieldAccess[] fieldsOf(Class<?> c) {
+ FieldAccess[] fields = fieldsOfASTClasses.get(c);
if (fields != null) return fields;
- fields = new ArrayList<FieldAccess>();
- getFields(c, fields);
- fieldsOfASTClasses.putIfAbsent(c, fields);
+ List<FieldAccess> fieldList = new ArrayList<FieldAccess>();
+ getFields(c, fieldList);
+ fieldsOfASTClasses.putIfAbsent(c, fieldList.toArray(new FieldAccess[fieldList.size()]));
return fieldsOfASTClasses.get(c);
}
diff --git a/src/core/lombok/core/AnnotationProcessor.java b/src/core/lombok/core/AnnotationProcessor.java
index 89dfa555..293bfef6 100644
--- a/src/core/lombok/core/AnnotationProcessor.java
+++ b/src/core/lombok/core/AnnotationProcessor.java
@@ -72,15 +72,7 @@ public class AnnotationProcessor extends AbstractProcessor {
* the delegate ProcessingEnvironment of the gradle wrapper is returned.
*/
public static ProcessingEnvironment getJavacProcessingEnvironment(ProcessingEnvironment procEnv, List<String> delayedWarnings) {
- ProcessingEnvironment javacProcEnv = tryRecursivelyObtainJavacProcessingEnvironment(procEnv);
-
- if (javacProcEnv == null) {
- if (!procEnv.getClass().getName().startsWith("org.eclipse.jdt.")) {
- delayedWarnings.add("Can't get the delegate of the gradle IncrementalProcessingEnvironment.");
- }
- }
-
- return javacProcEnv;
+ return tryRecursivelyObtainJavacProcessingEnvironment(procEnv);
}
private static ProcessingEnvironment tryRecursivelyObtainJavacProcessingEnvironment(ProcessingEnvironment procEnv) {
@@ -111,6 +103,9 @@ public class AnnotationProcessor extends AbstractProcessor {
}
@Override boolean want(ProcessingEnvironment procEnv, List<String> delayedWarnings) {
+ // do not run on ECJ as it may print warnings
+ if (procEnv.getClass().getName().startsWith("org.eclipse.jdt.")) return false;
+
ProcessingEnvironment javacProcEnv = getJavacProcessingEnvironment(procEnv, delayedWarnings);
if (javacProcEnv == null) return false;
@@ -210,7 +205,7 @@ public class AnnotationProcessor extends AbstractProcessor {
for (TypeElement elem : annotations) {
zeroElems = false;
Name n = elem.getQualifiedName();
- if (n.length() > 7 && n.subSequence(0, 7).toString().equals("lombok.")) continue;
+ if (n.toString().startsWith("lombok.")) continue;
onlyLombok = false;
}
diff --git a/src/core/lombok/core/LombokInternalAliasing.java b/src/core/lombok/core/LombokInternalAliasing.java
index 3dc1bfa2..c1089580 100644
--- a/src/core/lombok/core/LombokInternalAliasing.java
+++ b/src/core/lombok/core/LombokInternalAliasing.java
@@ -36,10 +36,8 @@ public class LombokInternalAliasing {
*/
public static String processAliases(String in) {
if (in == null) return null;
- for (Map.Entry<String, String> e : ALIASES.entrySet()) {
- if (in.equals(e.getKey())) return e.getValue();
- }
- return in;
+ String ret = ALIASES.get(in);
+ return ret == null ? in : ret;
}
static {
diff --git a/src/core/lombok/core/LombokNode.java b/src/core/lombok/core/LombokNode.java
index d6708956..5a0842bc 100644
--- a/src/core/lombok/core/LombokNode.java
+++ b/src/core/lombok/core/LombokNode.java
@@ -40,7 +40,6 @@ import lombok.core.AST.Kind;
* For example, JCTree for javac, and ASTNode for Eclipse.
*/
public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A, L, N>, N> implements DiagnosticsReceiver {
- protected final A ast;
protected final Kind kind;
protected final N node;
protected LombokImmutableList<L> children;
@@ -59,8 +58,7 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
* @param kind The kind of node represented by this object.
*/
@SuppressWarnings("unchecked")
- protected LombokNode(A ast, N node, List<L> children, Kind kind) {
- this.ast = ast;
+ protected LombokNode(N node, List<L> children, Kind kind) {
this.kind = kind;
this.node = node;
this.children = children != null ? LombokImmutableList.copyOf(children) : LombokImmutableList.<L>of();
@@ -72,9 +70,7 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
this.isStructurallySignificant = calculateIsStructurallySignificant(null);
}
- public A getAst() {
- return ast;
- }
+ public abstract A getAst();
/** {@inheritDoc} */
@Override public String toString() {
@@ -88,7 +84,7 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
* @see AST#getPackageDeclaration()
*/
public String getPackageDeclaration() {
- return ast.getPackageDeclaration();
+ return getAst().getPackageDeclaration();
}
/**
@@ -97,7 +93,7 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
* @see AST#getImportList()
*/
public ImportList getImportList() {
- return ast.getImportList();
+ return getAst().getImportList();
}
/**
@@ -111,7 +107,7 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
* @see AST#get(Object)
*/
public L getNodeFor(N obj) {
- return ast.get(obj);
+ return getAst().get(obj);
}
/**
@@ -187,7 +183,7 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
* @see AST#getLatestJavaSpecSupported()
*/
public int getLatestJavaSpecSupported() {
- return ast.getLatestJavaSpecSupported();
+ return getAst().getLatestJavaSpecSupported();
}
/**
@@ -196,7 +192,7 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
* @see AST#getSourceVersion()
*/
public int getSourceVersion() {
- return ast.getSourceVersion();
+ return getAst().getSourceVersion();
}
/**
@@ -205,7 +201,7 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
* @see AST#top()
*/
public L top() {
- return ast.top();
+ return getAst().top();
}
/**
@@ -214,7 +210,7 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
* @see AST#getFileName()
*/
public String getFileName() {
- return ast.getFileName();
+ return getAst().getFileName();
}
/**
@@ -224,8 +220,8 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
*/
@SuppressWarnings({"unchecked"})
public L add(N newChild, Kind newChildKind) {
- ast.setChanged();
- L n = ast.buildTree(newChild, newChildKind);
+ getAst().setChanged();
+ L n = getAst().buildTree(newChild, newChildKind);
if (n == null) return null;
n.parent = (L) this;
children = children.append(n);
@@ -242,20 +238,20 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
Map<N, L> oldNodes = new IdentityHashMap<N, L>();
gatherAndRemoveChildren(oldNodes);
- L newNode = ast.buildTree(get(), kind);
+ L newNode = getAst().buildTree(get(), kind);
- ast.setChanged();
+ getAst().setChanged();
- ast.replaceNewWithExistingOld(oldNodes, newNode);
+ getAst().replaceNewWithExistingOld(oldNodes, newNode);
}
@SuppressWarnings({"unchecked", "rawtypes"})
private void gatherAndRemoveChildren(Map<N, L> map) {
for (LombokNode child : children) child.gatherAndRemoveChildren(map);
- ast.identityDetector.remove(get());
+ getAst().identityDetector.remove(get());
map.put(get(), (L) this);
children = LombokImmutableList.of();
- ast.getNodeMap().remove(get());
+ getAst().getNodeMap().remove(get());
}
/**
@@ -264,7 +260,7 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
* Does not change the underlying (javac/Eclipse) AST, only the wrapped view.
*/
public void removeChild(L child) {
- ast.setChanged();
+ getAst().setChanged();
children = children.removeElement(child);
}
diff --git a/src/core/lombok/core/configuration/StringConfigurationSource.java b/src/core/lombok/core/configuration/StringConfigurationSource.java
index dd2f0319..abf6eea0 100644
--- a/src/core/lombok/core/configuration/StringConfigurationSource.java
+++ b/src/core/lombok/core/configuration/StringConfigurationSource.java
@@ -67,7 +67,6 @@ public class StringConfigurationSource implements ConfigurationSource {
list.add(new ListModification(value, add));
}
});
-
return new StringConfigurationSource(values);
}
diff --git a/src/core/lombok/eclipse/EclipseASTAdapter.java b/src/core/lombok/eclipse/EclipseASTAdapter.java
index 2a78c270..61807fff 100644
--- a/src/core/lombok/eclipse/EclipseASTAdapter.java
+++ b/src/core/lombok/eclipse/EclipseASTAdapter.java
@@ -36,6 +36,9 @@ import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
* has been implemented with an empty body. Override whichever methods you need.
*/
public abstract class EclipseASTAdapter implements EclipseASTVisitor {
+
+ private final boolean deferUntilPostDiet = getClass().isAnnotationPresent(DeferUntilPostDiet.class);
+
/** {@inheritDoc} */
public void visitCompilationUnit(EclipseNode top, CompilationUnitDeclaration unit) {}
@@ -98,4 +101,8 @@ public abstract class EclipseASTAdapter implements EclipseASTVisitor {
/** {@inheritDoc} */
public void endVisitStatement(EclipseNode statementNode, Statement statement) {}
+
+ public boolean isDeferUntilPostDiet() {
+ return deferUntilPostDiet ;
+ }
}
diff --git a/src/core/lombok/eclipse/EclipseASTVisitor.java b/src/core/lombok/eclipse/EclipseASTVisitor.java
index 63557f41..b2fd4b2f 100644
--- a/src/core/lombok/eclipse/EclipseASTVisitor.java
+++ b/src/core/lombok/eclipse/EclipseASTVisitor.java
@@ -416,5 +416,11 @@ public interface EclipseASTVisitor {
int end = node.get().sourceEnd();
return String.format(" [%d, %d]", start, end);
}
+
+ public boolean isDeferUntilPostDiet() {
+ return false;
+ }
}
+
+ boolean isDeferUntilPostDiet();
}
diff --git a/src/core/lombok/eclipse/EclipseNode.java b/src/core/lombok/eclipse/EclipseNode.java
index 4db1d38d..1738c770 100644
--- a/src/core/lombok/eclipse/EclipseNode.java
+++ b/src/core/lombok/eclipse/EclipseNode.java
@@ -44,16 +44,22 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
* Eclipse specific version of the LombokNode class.
*/
public class EclipseNode extends lombok.core.LombokNode<EclipseAST, EclipseNode, ASTNode> {
+ private EclipseAST ast;
/** {@inheritDoc} */
EclipseNode(EclipseAST ast, ASTNode node, List<EclipseNode> children, Kind kind) {
- super(ast, node, children, kind);
+ super(node, children, kind);
+ this.ast = ast;
}
+ @Override
+ public EclipseAST getAst() {
+ return ast;
+ }
/**
* Visits this node and all child nodes depth-first, calling the provided visitor's visit methods.
*/
public void traverse(EclipseASTVisitor visitor) {
- if (!this.isCompleteParse() && visitor.getClass().isAnnotationPresent(DeferUntilPostDiet.class)) return;
+ if (visitor.isDeferUntilPostDiet() && !isCompleteParse()) return;
switch (getKind()) {
case COMPILATION_UNIT:
diff --git a/src/core/lombok/eclipse/HandlerLibrary.java b/src/core/lombok/eclipse/HandlerLibrary.java
index 07c6f97b..0e72fb38 100644
--- a/src/core/lombok/eclipse/HandlerLibrary.java
+++ b/src/core/lombok/eclipse/HandlerLibrary.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2014 The Project Lombok Authors.
+ * Copyright (C) 2009-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
@@ -212,21 +212,25 @@ public class HandlerLibrary {
* @param ast The Compilation Unit that contains the Annotation AST Node.
* @param annotationNode The Lombok AST Node representing the Annotation AST Node.
* @param annotation 'node.get()' - convenience parameter.
+ * @param priority current prioritiy
+ * @return the priority we want to run - MAX_VALUE means never
*/
- public void handleAnnotation(CompilationUnitDeclaration ast, EclipseNode annotationNode, org.eclipse.jdt.internal.compiler.ast.Annotation annotation, long priority) {
+ public long handleAnnotation(CompilationUnitDeclaration ast, EclipseNode annotationNode, org.eclipse.jdt.internal.compiler.ast.Annotation annotation, long priority) {
TypeResolver resolver = new TypeResolver(annotationNode.getImportList());
TypeReference rawType = annotation.type;
- if (rawType == null) return;
+ if (rawType == null) return Long.MAX_VALUE;
String fqn = resolver.typeRefToFullyQualifiedName(annotationNode, typeLibrary, toQualifiedName(annotation.type.getTypeName()));
- if (fqn == null) return;
+ if (fqn == null) return Long.MAX_VALUE;
AnnotationHandlerContainer<?> container = annotationHandlers.get(fqn);
- if (container == null) return;
- if (priority != container.getPriority()) return;
+ if (container == null) return Long.MAX_VALUE;
+
+ if (priority < container.getPriority()) return container.getPriority(); // we want to run at this priority
+ if (priority > container.getPriority()) return Long.MAX_VALUE; // it's over- we do not want to run again
if (!annotationNode.isCompleteParse() && container.deferUntilPostDiet()) {
if (needsHandling(annotation)) container.preHandle(annotation, annotationNode);
- return;
+ return Long.MAX_VALUE;
}
try {
@@ -236,13 +240,16 @@ public class HandlerLibrary {
} catch (Throwable t) {
error(ast, String.format("Lombok annotation handler %s failed", container.handler.getClass()), t);
}
+ return Long.MAX_VALUE;
}
/**
* Will call all registered {@link EclipseASTVisitor} instances.
*/
- public void callASTVisitors(EclipseAST ast, long priority, boolean isCompleteParse) {
+ public long callASTVisitors(EclipseAST ast, long priority, boolean isCompleteParse) {
+ long nearestPriority = Long.MAX_VALUE;
for (VisitorContainer container : visitorHandlers) {
+ if (priority < container.getPriority()) nearestPriority = Math.min(container.getPriority(), nearestPriority);
if (!isCompleteParse && container.deferUntilPostDiet()) continue;
if (priority != container.getPriority()) continue;
try {
@@ -252,5 +259,6 @@ public class HandlerLibrary {
String.format("Lombok visitor handler %s failed", container.visitor.getClass()), t);
}
}
+ return nearestPriority;
}
}
diff --git a/src/core/lombok/eclipse/TransformEclipseAST.java b/src/core/lombok/eclipse/TransformEclipseAST.java
index 541924ad..323fc171 100644
--- a/src/core/lombok/eclipse/TransformEclipseAST.java
+++ b/src/core/lombok/eclipse/TransformEclipseAST.java
@@ -186,42 +186,54 @@ public class TransformEclipseAST {
* then handles any PrintASTs.
*/
public void go() {
+ long nextPriority = Long.MIN_VALUE;
for (Long d : handlers.getPriorities()) {
- ast.traverse(new AnnotationVisitor(d));
- handlers.callASTVisitors(ast, d, ast.isCompleteParse());
+ if (nextPriority > d) continue;
+ AnnotationVisitor visitor = new AnnotationVisitor(d);
+ ast.traverse(visitor);
+ // if no visitor interested for this AST, nextPriority would be MAX_VALUE and we bail out immediatetly
+ nextPriority = visitor.getNextPriority();
+ nextPriority = Math.min(nextPriority, handlers.callASTVisitors(ast, d, ast.isCompleteParse()));
}
}
private static class AnnotationVisitor extends EclipseASTAdapter {
private final long priority;
+ // this is the next priority we continue to visit.
+ // Long.MAX_VALUE means never. Each visit method will potentially reduce the next priority
+ private long nextPriority = Long.MAX_VALUE;
public AnnotationVisitor(long priority) {
this.priority = priority;
}
+ public long getNextPriority() {
+ return nextPriority;
+ }
+
@Override public void visitAnnotationOnField(FieldDeclaration field, EclipseNode annotationNode, Annotation annotation) {
CompilationUnitDeclaration top = (CompilationUnitDeclaration) annotationNode.top().get();
- handlers.handleAnnotation(top, annotationNode, annotation, priority);
+ nextPriority = Math.min(nextPriority, handlers.handleAnnotation(top, annotationNode, annotation, priority));
}
@Override public void visitAnnotationOnMethodArgument(Argument arg, AbstractMethodDeclaration method, EclipseNode annotationNode, Annotation annotation) {
CompilationUnitDeclaration top = (CompilationUnitDeclaration) annotationNode.top().get();
- handlers.handleAnnotation(top, annotationNode, annotation, priority);
+ nextPriority = Math.min(nextPriority, handlers.handleAnnotation(top, annotationNode, annotation, priority));
}
@Override public void visitAnnotationOnLocal(LocalDeclaration local, EclipseNode annotationNode, Annotation annotation) {
CompilationUnitDeclaration top = (CompilationUnitDeclaration) annotationNode.top().get();
- handlers.handleAnnotation(top, annotationNode, annotation, priority);
+ nextPriority = Math.min(nextPriority, handlers.handleAnnotation(top, annotationNode, annotation, priority));
}
@Override public void visitAnnotationOnMethod(AbstractMethodDeclaration method, EclipseNode annotationNode, Annotation annotation) {
CompilationUnitDeclaration top = (CompilationUnitDeclaration) annotationNode.top().get();
- handlers.handleAnnotation(top, annotationNode, annotation, priority);
+ nextPriority = Math.min(nextPriority, handlers.handleAnnotation(top, annotationNode, annotation, priority));
}
@Override public void visitAnnotationOnType(TypeDeclaration type, EclipseNode annotationNode, Annotation annotation) {
CompilationUnitDeclaration top = (CompilationUnitDeclaration) annotationNode.top().get();
- handlers.handleAnnotation(top, annotationNode, annotation, priority);
+ nextPriority = Math.min(nextPriority, handlers.handleAnnotation(top, annotationNode, annotation, priority));
}
}
}
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 2dce285c..87df6d1b 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -24,6 +24,7 @@ package lombok.eclipse.handlers;
import static lombok.core.handlers.HandlerUtil.*;
import static lombok.eclipse.Eclipse.*;
import static lombok.eclipse.EclipseAugments.*;
+import static lombok.eclipse.handlers.EclipseHandlerUtil.setGeneratedBy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
@@ -1862,4 +1863,29 @@ public class EclipseHandlerUtil {
String p = typeDecl.superclass.toString();
return p.equals("Object") || p.equals("java.lang.Object");
}
+
+ public static NameReference generateQualifiedNameRef(ASTNode source, char[]... varNames) {
+ int pS = source.sourceStart, pE = source.sourceEnd;
+ long p = (long)pS << 32 | pE;
+
+ NameReference ref;
+
+ if (varNames.length > 1) ref = new QualifiedNameReference(varNames, new long[varNames.length], pS, pE);
+ else ref = new SingleNameReference(varNames[0], p);
+ setGeneratedBy(ref, source);
+ return ref;
+ }
+
+ public static TypeReference generateQualifiedTypeRef(ASTNode source, char[]... varNames) {
+ int pS = source.sourceStart, pE = source.sourceEnd;
+ long p = (long)pS << 32 | pE;
+
+ TypeReference ref;
+
+ long[] poss = Eclipse.poss(source, varNames.length);
+ if (varNames.length > 1) ref = new QualifiedTypeReference(varNames, poss);
+ else ref = new SingleTypeReference(varNames[0], p);
+ setGeneratedBy(ref, source);
+ return ref;
+ }
}
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index e1b1af26..9a069c58 100644
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -40,6 +40,7 @@ import org.eclipse.jdt.internal.compiler.ast.Assignment;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
@@ -47,6 +48,7 @@ import org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
@@ -146,6 +148,8 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
@Override public void handle(AnnotationValues<Builder> annotation, Annotation ast, EclipseNode annotationNode) {
+ handleFlagUsage(annotationNode, ConfigurationKeys.BUILDER_FLAG_USAGE, "@Builder");
+
long p = (long) ast.sourceStart << 32 | ast.sourceEnd;
Builder builderInstance = annotation.getInstance();
@@ -490,6 +494,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
}
+ private static final char[] EMPTY_LIST = "emptyList".toCharArray();
private MethodDeclaration generateToBuilderMethod(String methodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, List<BuilderFieldData> builderFields, boolean fluent, ASTNode source) {
// return new ThingieBuilder<A, B>().setA(this.a).setB(this.b);
@@ -509,19 +514,34 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
for (BuilderFieldData bfd : builderFields) {
char[] setterName = fluent ? bfd.name : HandlerUtil.buildAccessorName("set", new String(bfd.name)).toCharArray();
MessageSend ms = new MessageSend();
+ Expression[] tgt = new Expression[bfd.singularData == null ? 1 : 2];
+
if (bfd.obtainVia == null || !bfd.obtainVia.field().isEmpty()) {
char[] fieldName = bfd.obtainVia == null ? bfd.rawName : bfd.obtainVia.field().toCharArray();
- FieldReference fr = new FieldReference(fieldName, 0);
- fr.receiver = new ThisReference(0, 0);
- ms.arguments = new Expression[] {fr};
+ for (int i = 0; i < tgt.length; i++) {
+ FieldReference fr = new FieldReference(fieldName, 0);
+ fr.receiver = new ThisReference(0, 0);
+ tgt[i] = fr;
+ }
} else {
String obtainName = bfd.obtainVia.method();
boolean obtainIsStatic = bfd.obtainVia.isStatic();
- MessageSend obtainExpr = new MessageSend();
- obtainExpr.receiver = obtainIsStatic ? new SingleNameReference(type.getName().toCharArray(), 0) : new ThisReference(0, 0);
- obtainExpr.selector = obtainName.toCharArray();
- if (obtainIsStatic) obtainExpr.arguments = new Expression[] {new ThisReference(0, 0)};
- ms.arguments = new Expression[] {obtainExpr};
+ for (int i = 0; i < tgt.length; i++) {
+ MessageSend obtainExpr = new MessageSend();
+ obtainExpr.receiver = obtainIsStatic ? new SingleNameReference(type.getName().toCharArray(), 0) : new ThisReference(0, 0);
+ obtainExpr.selector = obtainName.toCharArray();
+ if (obtainIsStatic) obtainExpr.arguments = new Expression[] {new ThisReference(0, 0)};
+ tgt[i] = obtainExpr;
+ }
+ }
+ if (bfd.singularData == null) {
+ ms.arguments = tgt;
+ } else {
+ Expression ifNull = new EqualExpression(tgt[0], new NullLiteral(0, 0), OperatorIds.EQUAL_EQUAL);
+ MessageSend emptyList = new MessageSend();
+ emptyList.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.UTIL, "Collections".toCharArray());
+ emptyList.selector = EMPTY_LIST;
+ ms.arguments = new Expression[] {new ConditionalExpression(ifNull, emptyList, tgt[1])};
}
ms.receiver = receiver;
ms.selector = setterName;
diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
index c99b9b5f..6945e5d9 100644
--- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
@@ -69,7 +69,6 @@ import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
@@ -819,29 +818,4 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
expr.sourceStart = pS; expr.sourceEnd = pE;
return expr;
}
-
- public NameReference generateQualifiedNameRef(ASTNode source, char[]... varNames) {
- int pS = source.sourceStart, pE = source.sourceEnd;
- long p = (long)pS << 32 | pE;
-
- NameReference ref;
-
- if (varNames.length > 1) ref = new QualifiedNameReference(varNames, new long[varNames.length], pS, pE);
- else ref = new SingleNameReference(varNames[0], p);
- setGeneratedBy(ref, source);
- return ref;
- }
-
- public TypeReference generateQualifiedTypeRef(ASTNode source, char[]... varNames) {
- int pS = source.sourceStart, pE = source.sourceEnd;
- long p = (long)pS << 32 | pE;
-
- TypeReference ref;
-
- long[] poss = Eclipse.poss(source, varNames.length);
- if (varNames.length > 1) ref = new QualifiedTypeReference(varNames, poss);
- else ref = new SingleTypeReference(varNames[0], p);
- setGeneratedBy(ref, source);
- return ref;
- }
}
diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
index 52b6345e..a0102220 100644
--- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
@@ -48,6 +48,7 @@ import org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
@@ -60,6 +61,7 @@ import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
diff --git a/src/core/lombok/javac/JavacNode.java b/src/core/lombok/javac/JavacNode.java
index 2bce6e3a..3963c892 100644
--- a/src/core/lombok/javac/JavacNode.java
+++ b/src/core/lombok/javac/JavacNode.java
@@ -50,11 +50,18 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
* Javac specific version of the LombokNode class.
*/
public class JavacNode extends lombok.core.LombokNode<JavacAST, JavacNode, JCTree> {
+ private JavacAST ast;
/**
* Passes through to the parent constructor.
*/
public JavacNode(JavacAST ast, JCTree node, List<JavacNode> children, Kind kind) {
- super(ast, node, children, kind);
+ super(node, children, kind);
+ this.ast = ast;
+ }
+
+ @Override
+ public JavacAST getAst() {
+ return ast;
}
public Element getElement() {
diff --git a/src/core/lombok/javac/apt/LombokProcessor.java b/src/core/lombok/javac/apt/LombokProcessor.java
index 04b494bf..247d0560 100644
--- a/src/core/lombok/javac/apt/LombokProcessor.java
+++ b/src/core/lombok/javac/apt/LombokProcessor.java
@@ -43,6 +43,7 @@ import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
+import javax.lang.model.element.QualifiedNameable;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;
import javax.tools.JavaFileManager;
@@ -166,14 +167,17 @@ public class LombokProcessor extends AbstractProcessor {
if (!(originalFiler instanceof InterceptingJavaFileManager)) {
final Messager messager = processingEnv.getMessager();
DiagnosticsReceiver receiver = new MessagerDiagnosticsReceiver(messager);
-
+
JavaFileManager newFilerManager = new InterceptingJavaFileManager(originalFiler, receiver);
ht.put(key, newFilerManager);
Field filerFileManagerField = JavacFiler.class.getDeclaredField("fileManager");
filerFileManagerField.setAccessible(true);
filerFileManagerField.set(javacFiler, newFilerManager);
-
- replaceFileManagerJdk9(context, newFilerManager);
+
+ if (lombok.javac.Javac.getJavaCompilerVersion() > 8
+ && !lombok.javac.handlers.JavacHandlerUtil.inNetbeansCompileOnSave(context)) {
+ replaceFileManagerJdk9(context, newFilerManager);
+ }
}
} catch (Exception e) {
throw Lombok.sneakyThrow(e);
@@ -380,10 +384,7 @@ public class LombokProcessor extends AbstractProcessor {
private String getModuleNameFor(Element element) {
while (element != null) {
- if (element.getKind().name().equals("MODULE")) {
- String n = element.getSimpleName().toString().trim();
- return n.isEmpty() ? null : n;
- }
+ if (element.getKind().name().equals("MODULE")) return ModuleNameOracle.getModuleName(element);
Element n = element.getEnclosingElement();
if (n == element) return null;
element = n;
@@ -391,6 +392,15 @@ public class LombokProcessor extends AbstractProcessor {
return null;
}
+ // QualifiedNameable is a java7 thing, so to remain compatible with java6, shove this into an inner class to avoid the ClassNotFoundError.
+ private static class ModuleNameOracle {
+ static String getModuleName(Element element) {
+ if (!(element instanceof QualifiedNameable)) return null;
+ String name = ((QualifiedNameable) element).getQualifiedName().toString().trim();
+ return name.isEmpty() ? null : name;
+ }
+ }
+
private JCCompilationUnit toUnit(Element element) {
TreePath path = trees == null ? null : trees.getPath(element);
if (path == null) return null;
@@ -429,7 +439,7 @@ public class LombokProcessor extends AbstractProcessor {
}
/**
- * This class returns the given filer as a JavacFiler. In case the case that the filer is no
+ * This class returns the given filer as a JavacFiler. In case the filer is no
* JavacFiler (e.g. the Gradle IncrementalFiler), its "delegate" field is used to get the JavacFiler
* (directly or through a delegate field again)
*/
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index a6ba5d0a..63697691 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -492,18 +492,34 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCExpression invoke = call;
for (BuilderFieldData bfd : builderFields) {
Name setterName = fluent ? bfd.name : type.toName(HandlerUtil.buildAccessorName("set", bfd.name.toString()));
- JCExpression arg;
+ JCExpression[] tgt = new JCExpression[bfd.singularData == null ? 1 : 2];
if (bfd.obtainVia == null || !bfd.obtainVia.field().isEmpty()) {
- arg = maker.Select(maker.Ident(type.toName("this")), bfd.obtainVia == null ? bfd.rawName : type.toName(bfd.obtainVia.field()));
+ for (int i = 0; i < tgt.length; i++) {
+ tgt[i] = maker.Select(maker.Ident(type.toName("this")), bfd.obtainVia == null ? bfd.rawName : type.toName(bfd.obtainVia.field()));
+ }
} else {
if (bfd.obtainVia.isStatic()) {
- JCExpression c = maker.Select(maker.Ident(type.toName(type.getName())), type.toName(bfd.obtainVia.method()));
- arg = maker.Apply(List.<JCExpression>nil(), c, List.<JCExpression>of(maker.Ident(type.toName("this"))));
+ for (int i = 0; i < tgt.length; i++) {
+ JCExpression c = maker.Select(maker.Ident(type.toName(type.getName())), type.toName(bfd.obtainVia.method()));
+ tgt[i] = maker.Apply(List.<JCExpression>nil(), c, List.<JCExpression>of(maker.Ident(type.toName("this"))));
+ }
} else {
- JCExpression c = maker.Select(maker.Ident(type.toName("this")), type.toName(bfd.obtainVia.method()));
- arg = maker.Apply(List.<JCExpression>nil(), c, List.<JCExpression>nil());
+ for (int i = 0; i < tgt.length; i++) {
+ JCExpression c = maker.Select(maker.Ident(type.toName("this")), type.toName(bfd.obtainVia.method()));
+ tgt[i] = maker.Apply(List.<JCExpression>nil(), c, List.<JCExpression>nil());
+ }
}
}
+
+ JCExpression arg;
+ if (bfd.singularData == null) {
+ arg = tgt[0];
+ } else {
+ JCExpression eqNull = maker.Binary(CTC_EQUAL, tgt[0], maker.Literal(CTC_BOT, null));
+ JCExpression emptyList = maker.Apply(List.<JCExpression>nil(), chainDots(type, "java", "util", "Collections", "emptyList"), List.<JCExpression>nil());
+ arg = maker.Conditional(eqNull, emptyList, tgt[1]);
+ }
+
invoke = maker.Apply(List.<JCExpression>nil(), maker.Select(invoke, setterName), List.of(arg));
}
JCStatement statement = maker.Return(invoke);
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index f335cf94..570d1a7e 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -134,11 +134,16 @@ public class JavacHandlerUtil {
return inNetbeansEditor(node.getContext());
}
- private static boolean inNetbeansEditor(Context context) {
+ public static boolean inNetbeansEditor(Context context) {
Options options = Options.instance(context);
return (options.keySet().contains("ide") && !options.keySet().contains("backgroundCompilation"));
}
-
+
+ public static boolean inNetbeansCompileOnSave(Context context) {
+ Options options = Options.instance(context);
+ return (options.keySet().contains("ide") && options.keySet().contains("backgroundCompilation"));
+ }
+
public static JCTree getGeneratedBy(JCTree node) {
return JCTree_generatedNode.get(node);
}
diff --git a/src/core9/module-info.java b/src/core9/module-info.java
index f4d5815f..56e54270 100644
--- a/src/core9/module-info.java
+++ b/src/core9/module-info.java
@@ -23,6 +23,7 @@ module lombok {
requires java.compiler;
requires java.instrument;
requires jdk.unsupported;
+ requires static org.mapstruct.processor;
exports lombok;
exports lombok.experimental;
@@ -36,4 +37,3 @@ module lombok {
provides javax.annotation.processing.Processor with lombok.launch.AnnotationProcessorHider.AnnotationProcessor;
provides org.mapstruct.ap.spi.AstModifyingAnnotationProcessor with lombok.launch.AnnotationProcessorHider.AstModificationNotifier;
}
-
diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
index 317b06a4..3c70d81d 100644
--- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java
+++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
@@ -92,7 +92,7 @@ final class PatchFixesHider {
shadowLoader = Util.class.getClassLoader();
} catch (ClassNotFoundException e) {
// If we get here, it isn't, and we should use the shadowloader.
- shadowLoader = Main.createShadowClassLoader();
+ shadowLoader = Main.getShadowClassLoader();
}
}
diff --git a/src/launch/lombok/launch/Agent.java b/src/launch/lombok/launch/Agent.java
index 7989e51f..357a8e48 100644
--- a/src/launch/lombok/launch/Agent.java
+++ b/src/launch/lombok/launch/Agent.java
@@ -35,7 +35,7 @@ final class Agent {
}
private static void runLauncher(String agentArgs, Instrumentation instrumentation, boolean injected) throws Throwable {
- ClassLoader cl = Main.createShadowClassLoader();
+ ClassLoader cl = Main.getShadowClassLoader();
try {
Class<?> c = cl.loadClass("lombok.core.AgentLauncher");
Method m = c.getDeclaredMethod("runAgents", String.class, Instrumentation.class, boolean.class, Class.class);
diff --git a/src/launch/lombok/launch/AnnotationProcessor.java b/src/launch/lombok/launch/AnnotationProcessor.java
index c4f922b9..b03dec76 100644
--- a/src/launch/lombok/launch/AnnotationProcessor.java
+++ b/src/launch/lombok/launch/AnnotationProcessor.java
@@ -104,7 +104,7 @@ class AnnotationProcessorHider {
}
private static AbstractProcessor createWrappedInstance() {
- ClassLoader cl = Main.createShadowClassLoader();
+ ClassLoader cl = Main.getShadowClassLoader();
try {
Class<?> mc = cl.loadClass("lombok.core.AnnotationProcessor");
return (AbstractProcessor) mc.getDeclaredConstructor().newInstance();
diff --git a/src/launch/lombok/launch/Main.java b/src/launch/lombok/launch/Main.java
index b81b6268..82913f8e 100644
--- a/src/launch/lombok/launch/Main.java
+++ b/src/launch/lombok/launch/Main.java
@@ -25,12 +25,18 @@ import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
class Main {
- static ClassLoader createShadowClassLoader() {
- return new ShadowClassLoader(Main.class.getClassLoader(), "lombok", null, Arrays.<String>asList(), Arrays.asList("lombok.patcher.Symbols"));
+
+ private static ShadowClassLoader classLoader;
+
+ static synchronized ClassLoader getShadowClassLoader() {
+ if (classLoader == null) {
+ classLoader = new ShadowClassLoader(Main.class.getClassLoader(), "lombok", null, Arrays.<String>asList(), Arrays.asList("lombok.patcher.Symbols"));
+ }
+ return classLoader;
}
public static void main(String[] args) throws Throwable {
- ClassLoader cl = createShadowClassLoader();
+ ClassLoader cl = getShadowClassLoader();
Class<?> mc = cl.loadClass("lombok.core.Main");
try {
mc.getMethod("main", String[].class).invoke(null, new Object[] {args});
diff --git a/src/launch/lombok/launch/ShadowClassLoader.java b/src/launch/lombok/launch/ShadowClassLoader.java
index 32363469..5489f3ea 100644
--- a/src/launch/lombok/launch/ShadowClassLoader.java
+++ b/src/launch/lombok/launch/ShadowClassLoader.java
@@ -296,17 +296,18 @@ class ShadowClassLoader extends ClassLoader {
return null;
}
- private boolean partOfShadow(URL item, String name) {
- return inOwnBase(item, name) || isPartOfShadowSuffix(item, name, sclSuffix);
+ private boolean partOfShadow(String item, String name) {
+ return !name.startsWith("java/")
+ && !name.startsWith("sun/")
+ && (inOwnBase(item, name) || isPartOfShadowSuffix(item, name, sclSuffix));
}
/**
* Checks if the stated item is located inside the same classpath root as the jar that hosts ShadowClassLoader.class. {@code item} and {@code name} refer to the same thing.
*/
- private boolean inOwnBase(URL item, String name) {
+ private boolean inOwnBase(String item, String name) {
if (item == null) return false;
- String itemString = item.toString();
- return (itemString.length() == SELF_BASE_LENGTH + name.length()) && SELF_BASE.regionMatches(0, itemString, 0, SELF_BASE_LENGTH);
+ return (item.length() == SELF_BASE_LENGTH + name.length()) && SELF_BASE.regionMatches(0, item, 0, SELF_BASE_LENGTH);
}
private static boolean sclFileContainsSuffix(InputStream in, String suffix) throws IOException {
@@ -386,12 +387,11 @@ class ShadowClassLoader extends ClassLoader {
}
}
- private boolean isPartOfShadowSuffix(URL item, String name, String suffix) {
+ private boolean isPartOfShadowSuffix(String url, String name, String suffix) {
// Instead of throwing an exception or logging, weird, unexpected cases just return false.
// This is better than throwing an exception, because exceptions would make your build tools unusable.
// Such cases are marked with the comment: // *unexpected*
- if (item == null) return false;
- String url = item.toString();
+ if (url == null) return false;
if (url.startsWith("file:/")) {
url = urlDecode(url.substring(5));
if (url.length() <= name.length() || !url.endsWith(name) || url.charAt(url.length() - name.length() - 1) != '/') {
@@ -436,14 +436,14 @@ class ShadowClassLoader extends ClassLoader {
Enumeration<URL> sec = super.getResources(name);
while (sec.hasMoreElements()) {
URL item = sec.nextElement();
- if (!partOfShadow(item, name)) vector.add(item);
+ if (!partOfShadow(item.toString(), name)) vector.add(item);
}
if (altName != null) {
Enumeration<URL> tern = super.getResources(altName);
while (tern.hasMoreElements()) {
URL item = tern.nextElement();
- if (!partOfShadow(item, altName)) vector.add(item);
+ if (!partOfShadow(item.toString(), altName)) vector.add(item);
}
}
@@ -483,11 +483,11 @@ class ShadowClassLoader extends ClassLoader {
if (altName != null) {
URL res = super.getResource(altName);
- if (res != null && (!noSuper || partOfShadow(res, altName))) return res;
+ if (res != null && (!noSuper || partOfShadow(res.toString(), altName))) return res;
}
URL res = super.getResource(name);
- if (res != null && (!noSuper || partOfShadow(res, name))) return res;
+ if (res != null && (!noSuper || partOfShadow(res.toString(), name))) return res;
return null;
}
@@ -501,12 +501,12 @@ class ShadowClassLoader extends ClassLoader {
private URL getResourceSkippingSelf(String name) throws IOException {
URL candidate = super.getResource(name);
if (candidate == null) return null;
- if (!partOfShadow(candidate, name)) return candidate;
+ if (!partOfShadow(candidate.toString(), name)) return candidate;
Enumeration<URL> en = super.getResources(name);
while (en.hasMoreElements()) {
candidate = en.nextElement();
- if (!partOfShadow(candidate, name)) return candidate;
+ if (!partOfShadow(candidate.toString(), name)) return candidate;
}
return null;
diff --git a/src/utils/lombok/eclipse/Eclipse.java b/src/utils/lombok/eclipse/Eclipse.java
index 5ef33086..943a7a7a 100644
--- a/src/utils/lombok/eclipse/Eclipse.java
+++ b/src/utils/lombok/eclipse/Eclipse.java
@@ -56,6 +56,8 @@ public class Eclipse {
*/
public static final int ECLIPSE_DO_NOT_TOUCH_FLAG = ASTNode.Bit24;
+ private static final Pattern SPLIT_AT_DOT = Pattern.compile("\\.");
+
private Eclipse() {
//Prevent instantiation
}
@@ -65,19 +67,25 @@ public class Eclipse {
* but we need to deal with it. This turns [[java][lang][String]] into "java.lang.String".
*/
public static String toQualifiedName(char[][] typeName) {
- int len = typeName.length - 1;
+ int len = typeName.length - 1; // number of dots
+ if (len == 0) return new String(typeName[0]);
+
for (char[] c : typeName) len += c.length;
- StringBuilder sb = new StringBuilder(len);
- boolean first = true;
- for (char[] c : typeName) {
- sb.append(first ? "" : ".").append(c);
- first = false;
+ char[] ret = new char[len];
+ char[] part = typeName[0];
+ System.arraycopy(part, 0, ret, 0, part.length);
+ int pos = part.length;
+ for (int i = 1; i < typeName.length; i++) {
+ ret[pos++] = '.';
+ part = typeName[i];
+ System.arraycopy(part, 0, ret, pos, part.length);
+ pos += part.length;
}
- return sb.toString();
+ return new String(ret);
}
public static char[][] fromQualifiedName(String typeName) {
- String[] split = typeName.split("\\.");
+ String[] split = SPLIT_AT_DOT.split(typeName);
char[][] result = new char[split.length][];
for (int i = 0; i < split.length; i++) {
result[i] = split[i].toCharArray();
diff --git a/test/core/src/lombok/RunTestsViaEcj.java b/test/core/src/lombok/RunTestsViaEcj.java
index 4e6a6a55..3efe38f5 100644
--- a/test/core/src/lombok/RunTestsViaEcj.java
+++ b/test/core/src/lombok/RunTestsViaEcj.java
@@ -122,7 +122,7 @@ public class RunTestsViaEcj extends AbstractRunTests {
CompilationUnitDeclaration cud = compilationUnit_.get();
- if (cud == null) result.append("---- NO CompilationUnit provided by ecj ----");
+ if (cud == null) result.append("---- No CompilationUnit provided by ecj ----");
else result.append(cud.toString());
return true;
diff --git a/test/transform/resource/after-delombok/BuilderSingularToBuilderWithNull.java b/test/transform/resource/after-delombok/BuilderSingularToBuilderWithNull.java
new file mode 100644
index 00000000..1f472438
--- /dev/null
+++ b/test/transform/resource/after-delombok/BuilderSingularToBuilderWithNull.java
@@ -0,0 +1,63 @@
+class BuilderSingularToBuilderWithNull {
+ private java.util.List<String> elems;
+ public static void test() {
+ new BuilderSingularToBuilderWithNull(null).toBuilder();
+ }
+ @java.lang.SuppressWarnings("all")
+ BuilderSingularToBuilderWithNull(final java.util.List<String> elems) {
+ this.elems = elems;
+ }
+ @java.lang.SuppressWarnings("all")
+ public static class BuilderSingularToBuilderWithNullBuilder {
+ @java.lang.SuppressWarnings("all")
+ private java.util.ArrayList<String> elems;
+ @java.lang.SuppressWarnings("all")
+ BuilderSingularToBuilderWithNullBuilder() {
+ }
+ @java.lang.SuppressWarnings("all")
+ public BuilderSingularToBuilderWithNullBuilder elem(final String elem) {
+ if (this.elems == null) this.elems = new java.util.ArrayList<String>();
+ this.elems.add(elem);
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ public BuilderSingularToBuilderWithNullBuilder elems(final java.util.Collection<? extends String> elems) {
+ if (this.elems == null) this.elems = new java.util.ArrayList<String>();
+ this.elems.addAll(elems);
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ public BuilderSingularToBuilderWithNullBuilder clearElems() {
+ if (this.elems != null) this.elems.clear();
+ return this;
+ }
+ @java.lang.SuppressWarnings("all")
+ public BuilderSingularToBuilderWithNull build() {
+ java.util.List<String> elems;
+ switch (this.elems == null ? 0 : this.elems.size()) {
+ case 0:
+ elems = java.util.Collections.emptyList();
+ break;
+ case 1:
+ elems = java.util.Collections.singletonList(this.elems.get(0));
+ break;
+ default:
+ elems = java.util.Collections.unmodifiableList(new java.util.ArrayList<String>(this.elems));
+ }
+ return new BuilderSingularToBuilderWithNull(elems);
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public java.lang.String toString() {
+ return "BuilderSingularToBuilderWithNull.BuilderSingularToBuilderWithNullBuilder(elems=" + this.elems + ")";
+ }
+ }
+ @java.lang.SuppressWarnings("all")
+ public static BuilderSingularToBuilderWithNullBuilder builder() {
+ return new BuilderSingularToBuilderWithNullBuilder();
+ }
+ @java.lang.SuppressWarnings("all")
+ public BuilderSingularToBuilderWithNullBuilder toBuilder() {
+ return new BuilderSingularToBuilderWithNullBuilder().elems(this.elems == null ? java.util.Collections.emptyList() : this.elems);
+ }
+}
diff --git a/test/transform/resource/after-delombok/BuilderWithToBuilder.java b/test/transform/resource/after-delombok/BuilderWithToBuilder.java
index 46387f0f..b644a16f 100644
--- a/test/transform/resource/after-delombok/BuilderWithToBuilder.java
+++ b/test/transform/resource/after-delombok/BuilderWithToBuilder.java
@@ -86,7 +86,7 @@ class BuilderWithToBuilder<T> {
}
@java.lang.SuppressWarnings("all")
public BuilderWithToBuilderBuilder<T> toBuilder() {
- return new BuilderWithToBuilderBuilder<T>().one(this.mOne).two(this.mTwo).foo(BuilderWithToBuilder.rrr(this)).bars(this.bars);
+ return new BuilderWithToBuilderBuilder<T>().one(this.mOne).two(this.mTwo).foo(BuilderWithToBuilder.rrr(this)).bars(this.bars == null ? java.util.Collections.emptyList() : this.bars);
}
}
class ConstructorWithToBuilder<T> {
diff --git a/test/transform/resource/after-ecj/BuilderSingularToBuilderWithNull.java b/test/transform/resource/after-ecj/BuilderSingularToBuilderWithNull.java
new file mode 100644
index 00000000..7265e17a
--- /dev/null
+++ b/test/transform/resource/after-ecj/BuilderSingularToBuilderWithNull.java
@@ -0,0 +1,57 @@
+import lombok.Singular;
+@lombok.Builder(toBuilder = true) class BuilderSingularToBuilderWithNull {
+ public static @java.lang.SuppressWarnings("all") class BuilderSingularToBuilderWithNullBuilder {
+ private @java.lang.SuppressWarnings("all") java.util.ArrayList<String> elems;
+ @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNullBuilder() {
+ super();
+ }
+ public @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNullBuilder elem(String elem) {
+ if ((this.elems == null))
+ this.elems = new java.util.ArrayList<String>();
+ this.elems.add(elem);
+ return this;
+ }
+ public @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNullBuilder elems(java.util.Collection<? extends String> elems) {
+ if ((this.elems == null))
+ this.elems = new java.util.ArrayList<String>();
+ this.elems.addAll(elems);
+ return this;
+ }
+ public @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNullBuilder clearElems() {
+ if ((this.elems != null))
+ this.elems.clear();
+ return this;
+ }
+ public @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNull build() {
+ java.util.List<String> elems;
+ switch (((this.elems == null) ? 0 : this.elems.size())) {
+ case 0 :
+ elems = java.util.Collections.emptyList();
+ break;
+ case 1 :
+ elems = java.util.Collections.singletonList(this.elems.get(0));
+ break;
+ default :
+ elems = java.util.Collections.unmodifiableList(new java.util.ArrayList<String>(this.elems));
+ }
+ return new BuilderSingularToBuilderWithNull(elems);
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
+ return (("BuilderSingularToBuilderWithNull.BuilderSingularToBuilderWithNullBuilder(elems=" + this.elems) + ")");
+ }
+ }
+ private @Singular java.util.List<String> elems;
+ public static void test() {
+ new BuilderSingularToBuilderWithNull(null).toBuilder();
+ }
+ @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNull(final java.util.List<String> elems) {
+ super();
+ this.elems = elems;
+ }
+ public static @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNullBuilder builder() {
+ return new BuilderSingularToBuilderWithNullBuilder();
+ }
+ public @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNullBuilder toBuilder() {
+ return new BuilderSingularToBuilderWithNullBuilder().elems(((this.elems == null) ? java.util.Collections.emptyList() : this.elems));
+ }
+}
diff --git a/test/transform/resource/after-ecj/BuilderWithToBuilder.java b/test/transform/resource/after-ecj/BuilderWithToBuilder.java
index d304293c..b9cc27dd 100644
--- a/test/transform/resource/after-ecj/BuilderWithToBuilder.java
+++ b/test/transform/resource/after-ecj/BuilderWithToBuilder.java
@@ -74,7 +74,7 @@ import lombok.Builder;
return new BuilderWithToBuilderBuilder<T>();
}
public @java.lang.SuppressWarnings("all") BuilderWithToBuilderBuilder<T> toBuilder() {
- return new BuilderWithToBuilderBuilder<T>().one(this.mOne).two(this.mTwo).foo(BuilderWithToBuilder.rrr(this)).bars(this.bars);
+ return new BuilderWithToBuilderBuilder<T>().one(this.mOne).two(this.mTwo).foo(BuilderWithToBuilder.rrr(this)).bars(((this.bars == null) ? java.util.Collections.emptyList() : this.bars));
}
}
@lombok.experimental.Accessors(prefix = "m") class ConstructorWithToBuilder<T> {
diff --git a/test/transform/resource/before/BuilderSingularToBuilderWithNull.java b/test/transform/resource/before/BuilderSingularToBuilderWithNull.java
new file mode 100644
index 00000000..92a102cb
--- /dev/null
+++ b/test/transform/resource/before/BuilderSingularToBuilderWithNull.java
@@ -0,0 +1,10 @@
+import lombok.Singular;
+
+@lombok.Builder(toBuilder = true)
+class BuilderSingularToBuilderWithNull {
+ @Singular private java.util.List<String> elems;
+
+ public static void test() {
+ new BuilderSingularToBuilderWithNull(null).toBuilder();
+ }
+}
diff --git a/website/usageExamples/LogExample_post.jpage b/website/usageExamples/LogExample_post.jpage
index eab3b046..78c0fdd9 100644
--- a/website/usageExamples/LogExample_post.jpage
+++ b/website/usageExamples/LogExample_post.jpage
@@ -2,7 +2,7 @@ public class LogExample {
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
public static void main(String... args) {
- log.error("Something's wrong here");
+ log.severe("Something's wrong here");
}
}
diff --git a/website/usageExamples/LogExample_pre.jpage b/website/usageExamples/LogExample_pre.jpage
index ba27dd27..9fa1e91c 100644
--- a/website/usageExamples/LogExample_pre.jpage
+++ b/website/usageExamples/LogExample_pre.jpage
@@ -5,7 +5,7 @@ import lombok.extern.slf4j.Slf4j;
public class LogExample {
public static void main(String... args) {
- log.error("Something's wrong here");
+ log.severe("Something's wrong here");
}
}