aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRawi01 <Rawi01@users.noreply.github.com>2021-10-21 10:38:37 +0200
committerRawi01 <Rawi01@users.noreply.github.com>2021-10-22 09:24:17 +0200
commit553b25addde4fab136258f7718e274a98bfbe34a (patch)
treef65f76f8c838a73f5f91f8efe0811c6b019857bb
parent13d84b129e562fdc71b049778c3b3bd2376e29a4 (diff)
downloadlombok-553b25addde4fab136258f7718e274a98bfbe34a.tar.gz
lombok-553b25addde4fab136258f7718e274a98bfbe34a.tar.bz2
lombok-553b25addde4fab136258f7718e274a98bfbe34a.zip
[fixes #2985] Resolve var/val only once in eclipse
-rw-r--r--buildScripts/tests.ant.xml16
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java1
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchVal.java85
-rw-r--r--test/core/src/lombok/DirectoryRunner.java3
-rw-r--r--test/core/src/lombok/RunTestsViaEcj.java26
-rw-r--r--test/transform/resource/after-delombok/ValInvalidParameter.java29
-rw-r--r--test/transform/resource/after-ecj/ValErrors.java4
-rw-r--r--test/transform/resource/after-ecj/ValInvalidParameter.java29
-rw-r--r--test/transform/resource/before/ValInvalidParameter.java32
-rw-r--r--test/transform/resource/messages-delombok/ValInvalidParameter.java.messages1
-rw-r--r--test/transform/resource/messages-ecj/ValErrors.java.messages6
-rw-r--r--test/transform/resource/messages-ecj/ValInBasicFor.java.messages6
-rw-r--r--test/transform/resource/messages-ecj/ValInvalidParameter.java.messages9
-rw-r--r--test/transform/resource/messages-idempotent/ValInvalidParameter.java.messages9
14 files changed, 194 insertions, 62 deletions
diff --git a/buildScripts/tests.ant.xml b/buildScripts/tests.ant.xml
index 9d9e9541..838ac353 100644
--- a/buildScripts/tests.ant.xml
+++ b/buildScripts/tests.ant.xml
@@ -152,13 +152,18 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
<macrodef name="test.eclipse-X">
<attribute name="version" />
+ <attribute name="compiler.compliance.level" default="latest" />
<sequential>
- <echo>Running TestEclipse on eclipse-@{version} on JVM${ant.java.version}.</echo>
+ <condition property="compiler.compliance.level" value="-Dcompiler.compliance.level=@{compiler.compliance.level}" else="-Dnot=set">
+ <not><equals arg1="@{compiler.compliance.level}" arg2="latest" /></not>
+ </condition>
+ <echo>Running TestEclipse on eclipse-@{version} on JVM${ant.java.version} using. Compiler compliance level: @{compiler.compliance.level}</echo>
<junit haltonfailure="yes" fork="true" forkmode="once">
<formatter classname="lombok.ant.SimpleTestFormatter" usefile="false" unless="tests.quiet" />
<jvmarg value="-Xbootclasspath/a:${jdk8-rt.loc}" />
<jvmarg value="-Ddelombok.bootclasspath=${jdk8-rt.loc}" />
<jvmarg value="-javaagent:dist/lombok.jar" />
+ <jvmarg value="${compiler.compliance.level}" />
<classpath location="build/ant" />
<classpath refid="cp.test" />
<classpath refid="cp.stripe" />
@@ -175,11 +180,16 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
<test.eclipse-X version="oxygen" />
</target>
- <target name="test.eclipse-202006" depends="test.formatter.compile, test.compile" description="runs the tests on your default VM, testing the 2020-03 release of eclipse">
+ <target name="test.eclipse-202006" depends="test.formatter.compile, test.compile" description="runs the tests on your default VM, testing the 2020-06 release of eclipse">
<fetchdep.eclipse version="202006" />
<test.eclipse-X version="202006" />
</target>
+ <target name="test.eclipse-202006-jdk8" depends="test.formatter.compile, test.compile" description="runs the tests on your default VM, testing the 2020-06 release of eclipse with compiler compliance level 8">
+ <fetchdep.eclipse version="202006" />
+ <test.eclipse-X version="202006" compiler.compliance.level="8" />
+ </target>
+
<macrodef name="test.ecj-X">
<attribute name="version" />
<sequential>
@@ -217,5 +227,5 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
</target>
<target name="test" depends="test.javacCurrent, test.eclipse-202006" description="runs the tests against the default JVM, javac, and eclipse" />
- <target name="test.broad" depends="test.javac8, test.javac14, test.eclipse-oxygen, test.eclipse-202006" description="runs the tests against the default JVM, javac, and eclipse" />
+ <target name="test.broad" depends="test.javac8, test.javac14, test.eclipse-oxygen, test.eclipse-202006, test.eclipse-202006-jdk8" description="runs the tests against the default JVM, javac, and eclipse" />
</project>
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
index 328860e3..33dad64e 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
@@ -764,6 +764,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
sm.addScript(ScriptBuilder.replaceMethodCall()
.target(new MethodTarget(LOCALDECLARATION_SIG, "resolve", "void", BLOCKSCOPE_SIG))
+ .target(new MethodTarget(LOCALDECLARATION_SIG, "resolve", "void", BLOCKSCOPE_SIG, "boolean"))
.methodToReplace(new Hook(EXPRESSION_SIG, "resolveType", TYPEBINDING_SIG, BLOCKSCOPE_SIG))
.requestExtra(StackRequest.THIS)
.replacementMethod(new Hook("lombok.launch.PatchFixesHider$Val", "skipResolveInitializerIfAlreadyCalled2", TYPEBINDING_SIG, EXPRESSION_SIG, BLOCKSCOPE_SIG, LOCALDECLARATION_SIG))
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
index 3e96e75d..e758979d 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
@@ -35,13 +35,11 @@ import org.eclipse.jdt.internal.compiler.ast.FunctionalExpression;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
@@ -250,7 +248,6 @@ public class PatchVal {
}
TypeBinding resolved = null;
- Constant oldConstant = init.constant;
try {
resolved = decomponent ? getForEachComponentType(init, scope) : resolveForExpression(init, scope);
} catch (NullPointerException e) {
@@ -260,6 +257,46 @@ public class PatchVal {
// just go with 'Object' and let the IDE print the appropriate errors.
resolved = null;
}
+
+ if (resolved == null) {
+ if (init instanceof ConditionalExpression) {
+ ConditionalExpression cexp = (ConditionalExpression) init;
+ Expression ifTrue = cexp.valueIfTrue;
+ Expression ifFalse = cexp.valueIfFalse;
+ TypeBinding ifTrueResolvedType = ifTrue.resolvedType;
+ CompilationResult compilationResult = scope.referenceCompilationUnit().compilationResult;
+ CategorizedProblem[] problems = compilationResult.problems;
+ CategorizedProblem lastProblem = problems[compilationResult.problemCount - 1];
+ if (ifTrueResolvedType != null && ifFalse.resolvedType == null && lastProblem.getCategoryID() == CAT_TYPE) {
+ int problemCount = compilationResult.problemCount;
+ for (int i = 0; i < problemCount; ++i) {
+ if (problems[i] == lastProblem) {
+ problems[i] = null;
+ if (i + 1 < problemCount) {
+ System.arraycopy(problems, i + 1, problems, i, problemCount - i + 1);
+ }
+ break;
+ }
+ }
+ compilationResult.removeProblem(lastProblem);
+ if (!compilationResult.hasErrors()) {
+ clearIgnoreFurtherInvestigationField(scope.referenceContext());
+ setValue(getField(CompilationResult.class, "hasMandatoryErrors"), compilationResult, false);
+ }
+
+ if (ifFalse instanceof FunctionalExpression) {
+ FunctionalExpression functionalExpression = (FunctionalExpression) ifFalse;
+ functionalExpression.setExpectedType(ifTrueResolvedType);
+ }
+ if (ifFalse.resolvedType == null) {
+ resolveForExpression(ifFalse, scope);
+ }
+
+ resolved = ifTrueResolvedType;
+ }
+ }
+ }
+
if (resolved != null) {
try {
replacement = makeType(resolved, local.type, false);
@@ -267,10 +304,6 @@ public class PatchVal {
} catch (Exception e) {
// Some type thing failed.
}
- } else {
- if (init instanceof MessageSend && ((MessageSend) init).actualReceiverType == null) {
- init.constant = oldConstant;
- }
}
}
@@ -370,43 +403,7 @@ public class PatchVal {
// Known cause of issues; for example: val e = mth("X"), where mth takes 2 arguments.
return null;
} catch (AbortCompilation e) {
- if (collection instanceof ConditionalExpression) {
- ConditionalExpression cexp = (ConditionalExpression) collection;
- Expression ifTrue = cexp.valueIfTrue;
- Expression ifFalse = cexp.valueIfFalse;
- TypeBinding ifTrueResolvedType = ifTrue.resolvedType;
- CategorizedProblem problem = e.problem;
- if (ifTrueResolvedType != null && ifFalse.resolvedType == null && problem.getCategoryID() == CAT_TYPE) {
- CompilationResult compilationResult = e.compilationResult;
- CategorizedProblem[] problems = compilationResult.problems;
- int problemCount = compilationResult.problemCount;
- for (int i = 0; i < problemCount; ++i) {
- if (problems[i] == problem) {
- problems[i] = null;
- if (i + 1 < problemCount) {
- System.arraycopy(problems, i + 1, problems, i, problemCount - i + 1);
- }
- break;
- }
- }
- compilationResult.removeProblem(problem);
- if (!compilationResult.hasErrors()) {
- clearIgnoreFurtherInvestigationField(scope.referenceContext());
- setValue(getField(CompilationResult.class, "hasMandatoryErrors"), compilationResult, false);
- }
-
- if (ifFalse instanceof FunctionalExpression) {
- FunctionalExpression functionalExpression = (FunctionalExpression) ifFalse;
- functionalExpression.setExpectedType(ifTrueResolvedType);
- }
- if (ifFalse.resolvedType == null) {
- ifFalse.resolve(scope);
- }
-
- return ifTrueResolvedType;
- }
- }
- throw e;
+ return null;
}
}
diff --git a/test/core/src/lombok/DirectoryRunner.java b/test/core/src/lombok/DirectoryRunner.java
index b041c42e..53347e24 100644
--- a/test/core/src/lombok/DirectoryRunner.java
+++ b/test/core/src/lombok/DirectoryRunner.java
@@ -55,7 +55,8 @@ public class DirectoryRunner extends Runner {
},
ECJ {
@Override public int getVersion() {
- return Eclipse.getEcjCompilerVersion();
+ String javaVersionString = System.getProperty("compiler.compliance.level");
+ return javaVersionString != null ? Integer.parseInt(javaVersionString) : Eclipse.getEcjCompilerVersion();
}
};
diff --git a/test/core/src/lombok/RunTestsViaEcj.java b/test/core/src/lombok/RunTestsViaEcj.java
index afba8c7f..6137de49 100644
--- a/test/core/src/lombok/RunTestsViaEcj.java
+++ b/test/core/src/lombok/RunTestsViaEcj.java
@@ -64,9 +64,22 @@ import org.osgi.framework.BundleContext;
public class RunTestsViaEcj extends AbstractRunTests {
protected CompilerOptions ecjCompilerOptions() {
CompilerOptions options = new CompilerOptions();
- options.complianceLevel = Eclipse.getLatestEcjCompilerVersionConstant();
- options.sourceLevel = Eclipse.getLatestEcjCompilerVersionConstant();
- options.targetJDK = Eclipse.getLatestEcjCompilerVersionConstant();
+ Map<String, String> warnings = new HashMap<String, String>();
+
+ String javaVersionString = System.getProperty("compiler.compliance.level");
+ long ecjCompilerVersionConstant = Eclipse.getLatestEcjCompilerVersionConstant();
+ long ecjCompilerVersion = Eclipse.getEcjCompilerVersion();
+ if (javaVersionString != null) {
+ long javaVersion = Long.parseLong(javaVersionString);
+ ecjCompilerVersionConstant = (javaVersion + 44) << 16;
+ ecjCompilerVersion = javaVersion;
+ } else {
+ // Preview features are only allowed if the maximum compiler version is equal to the source version
+ warnings.put("org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures", "enabled");
+ }
+ options.complianceLevel = ecjCompilerVersionConstant;
+ options.sourceLevel = ecjCompilerVersionConstant;
+ options.targetJDK = ecjCompilerVersionConstant;
options.docCommentSupport = false;
options.parseLiteralExpressionsAsConstants = true;
options.inlineJsrBytecode = true;
@@ -78,17 +91,14 @@ public class RunTestsViaEcj extends AbstractRunTests {
options.reportUnusedParameterWhenOverridingConcrete = false;
options.reportDeadCodeInTrivialIfStatement = false;
options.generateClassFiles = false;
- Map<String, String> warnings = new HashMap<String, String>();
warnings.put(CompilerOptions.OPTION_ReportUnusedLocal, "ignore");
warnings.put(CompilerOptions.OPTION_ReportUnusedLabel, "ignore");
warnings.put(CompilerOptions.OPTION_ReportUnusedImport, "ignore");
warnings.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, "ignore");
warnings.put(CompilerOptions.OPTION_ReportIndirectStaticAccess, "warning");
warnings.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, "warning");
- warnings.put("org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures", "enabled");
warnings.put("org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures", "ignore");
- int ecjVersion = Eclipse.getEcjCompilerVersion();
- warnings.put(CompilerOptions.OPTION_Source, (ecjVersion < 9 ? "1." : "") + ecjVersion);
+ warnings.put(CompilerOptions.OPTION_Source, (ecjCompilerVersion < 9 ? "1." : "") + ecjCompilerVersion);
options.set(warnings);
return options;
}
@@ -96,7 +106,7 @@ public class RunTestsViaEcj extends AbstractRunTests {
protected IErrorHandlingPolicy ecjErrorHandlingPolicy() {
return new IErrorHandlingPolicy() {
public boolean stopOnFirstError() {
- return true;
+ return false;
}
public boolean proceedOnErrors() {
diff --git a/test/transform/resource/after-delombok/ValInvalidParameter.java b/test/transform/resource/after-delombok/ValInvalidParameter.java
new file mode 100644
index 00000000..f3d4229c
--- /dev/null
+++ b/test/transform/resource/after-delombok/ValInvalidParameter.java
@@ -0,0 +1,29 @@
+public class ValInvalidParameter {
+ public void val() {
+ final java.lang.Object a = a(new NonExistingClass());
+ final java.lang.Object b = a(a(new NonExistingClass()));
+ final java.lang.Object c = nonExisitingMethod(b(1));
+ final java.lang.Object d = nonExistingObject.nonExistingMethod();
+ final java.lang.Object e = b(1).nonExistingMethod();
+ final java.lang.Object f = 1 > 2 ? a(new NonExistingClass()) : a(new NonExistingClass());
+ final java.lang.Object g = b2(1);
+ final java.lang.Integer h = b2(a("a"), a(null));
+ final int i = a(a(null));
+ }
+
+ public int a(String param) {
+ return 0;
+ }
+
+ public int a(Integer param) {
+ return 0;
+ }
+
+ public Integer b(int i) {
+ return i;
+ }
+
+ public Integer b2(int i, int j) {
+ return i;
+ }
+} \ No newline at end of file
diff --git a/test/transform/resource/after-ecj/ValErrors.java b/test/transform/resource/after-ecj/ValErrors.java
index 1bd61f87..19c2facd 100644
--- a/test/transform/resource/after-ecj/ValErrors.java
+++ b/test/transform/resource/after-ecj/ValErrors.java
@@ -4,9 +4,9 @@ public class ValErrors {
super();
}
public void unresolvableExpression() {
- val c = d;
+ final @val java.lang.Object c = d;
}
public void arrayInitializer() {
- val e = {"foo", "bar"};
+ final @val java.lang.Object e = {"foo", "bar"};
}
} \ No newline at end of file
diff --git a/test/transform/resource/after-ecj/ValInvalidParameter.java b/test/transform/resource/after-ecj/ValInvalidParameter.java
new file mode 100644
index 00000000..14549aa7
--- /dev/null
+++ b/test/transform/resource/after-ecj/ValInvalidParameter.java
@@ -0,0 +1,29 @@
+import lombok.val;
+public class ValInvalidParameter {
+ public ValInvalidParameter() {
+ super();
+ }
+ public void val() {
+ final @val java.lang.Object a = a(new NonExistingClass());
+ final @val java.lang.Object b = a(a(new NonExistingClass()));
+ final @val java.lang.Object c = nonExisitingMethod(b(1));
+ final @val java.lang.Object d = nonExistingObject.nonExistingMethod();
+ final @val java.lang.Object e = b(1).nonExistingMethod();
+ final @val java.lang.Object f = ((1 > 2) ? a(new NonExistingClass()) : a(new NonExistingClass()));
+ final @val java.lang.Object g = b2(1);
+ final @val java.lang.Object h = b2(a("a"), a(null));
+ final @val java.lang.Object i = a(a(null));
+ }
+ public int a(String param) {
+ return 0;
+ }
+ public int a(Integer param) {
+ return 0;
+ }
+ public Integer b(int i) {
+ return i;
+ }
+ public Integer b2(int i, int j) {
+ return i;
+ }
+} \ No newline at end of file
diff --git a/test/transform/resource/before/ValInvalidParameter.java b/test/transform/resource/before/ValInvalidParameter.java
new file mode 100644
index 00000000..f4961c4e
--- /dev/null
+++ b/test/transform/resource/before/ValInvalidParameter.java
@@ -0,0 +1,32 @@
+//version :9
+import lombok.val;
+
+public class ValInvalidParameter {
+ public void val() {
+ val a = a(new NonExistingClass());
+ val b = a(a(new NonExistingClass()));
+ val c = nonExisitingMethod(b(1));
+ val d = nonExistingObject.nonExistingMethod();
+ val e = b(1).nonExistingMethod();
+ val f = 1 > 2 ? a(new NonExistingClass()) : a(new NonExistingClass());
+ val g = b2(1);
+ val h = b2(a("a"), a(null));
+ val i = a(a(null));
+ }
+
+ public int a(String param) {
+ return 0;
+ }
+
+ public int a(Integer param) {
+ return 0;
+ }
+
+ public Integer b(int i) {
+ return i;
+ }
+
+ public Integer b2(int i, int j) {
+ return i;
+ }
+} \ No newline at end of file
diff --git a/test/transform/resource/messages-delombok/ValInvalidParameter.java.messages b/test/transform/resource/messages-delombok/ValInvalidParameter.java.messages
new file mode 100644
index 00000000..da0df315
--- /dev/null
+++ b/test/transform/resource/messages-delombok/ValInvalidParameter.java.messages
@@ -0,0 +1 @@
+12 Cannot use 'val' here because initializer expression does not have a representable type: Type cannot be resolved \ No newline at end of file
diff --git a/test/transform/resource/messages-ecj/ValErrors.java.messages b/test/transform/resource/messages-ecj/ValErrors.java.messages
index c4c76901..9fcec493 100644
--- a/test/transform/resource/messages-ecj/ValErrors.java.messages
+++ b/test/transform/resource/messages-ecj/ValErrors.java.messages
@@ -1,2 +1,4 @@
-6 d cannot be resolved to a variable
-10 'val' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })
+7 d cannot be resolved to a variable
+7 d cannot be resolved or is not a field
+11 'val' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })
+11 Type mismatch: cannot convert from String[] to Object \ No newline at end of file
diff --git a/test/transform/resource/messages-ecj/ValInBasicFor.java.messages b/test/transform/resource/messages-ecj/ValInBasicFor.java.messages
index b32eabe4..00bc643f 100644
--- a/test/transform/resource/messages-ecj/ValInBasicFor.java.messages
+++ b/test/transform/resource/messages-ecj/ValInBasicFor.java.messages
@@ -1,2 +1,4 @@
-7 'val' is not allowed in old-style for loops
-7 Type mismatch: cannot convert from int to val
+8 'val' is not allowed in old-style for loops
+8 Type mismatch: cannot convert from int to val
+8 Type mismatch: cannot convert from String to val
+8 Type mismatch: cannot convert from double to val \ No newline at end of file
diff --git a/test/transform/resource/messages-ecj/ValInvalidParameter.java.messages b/test/transform/resource/messages-ecj/ValInvalidParameter.java.messages
new file mode 100644
index 00000000..cbf2d7c4
--- /dev/null
+++ b/test/transform/resource/messages-ecj/ValInvalidParameter.java.messages
@@ -0,0 +1,9 @@
+5 NonExistingClass cannot be resolved to a type
+6 NonExistingClass cannot be resolved to a type
+7 The method nonExisitingMethod(Integer) is undefined for the type ValInvalidParameter
+8 nonExistingObject cannot be resolved
+9 The method nonExistingMethod() is undefined for the type Integer
+10 NonExistingClass cannot be resolved to a type
+11 The method b2(int, int) in the type ValInvalidParameter is not applicable for the arguments (int)
+12 The method a(String) is ambiguous for the type ValInvalidParameter
+13 The method a(String) is ambiguous for the type ValInvalidParameter \ No newline at end of file
diff --git a/test/transform/resource/messages-idempotent/ValInvalidParameter.java.messages b/test/transform/resource/messages-idempotent/ValInvalidParameter.java.messages
new file mode 100644
index 00000000..539d29cd
--- /dev/null
+++ b/test/transform/resource/messages-idempotent/ValInvalidParameter.java.messages
@@ -0,0 +1,9 @@
+3 cannot find symbol
+4 cannot find symbol
+5 cannot find symbol
+6 cannot find symbol
+7 cannot find symbol
+8 cannot find symbol
+9 method b2 in class ValInvalidParameter cannot be applied to given types;
+10 reference to a is ambiguous
+11 reference to a is ambiguous \ No newline at end of file