diff options
8 files changed, 137 insertions, 8 deletions
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java index c0c2cea6..0c66bb31 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java @@ -21,19 +21,27 @@ */ package lombok.eclipse.agent; +import lombok.permit.Permit; import org.eclipse.jdt.core.compiler.CategorizedProblem; import org.eclipse.jdt.internal.compiler.CompilationResult; +import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; import org.eclipse.jdt.internal.compiler.ast.ASTNode; +import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.ForeachStatement; +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.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.ReferenceContext; import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; @@ -45,12 +53,12 @@ import org.eclipse.jdt.internal.compiler.lookup.Scope; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; - -import lombok.permit.Permit; import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; +import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; import java.lang.reflect.Field; +import static lombok.Lombok.sneakyThrow; import static lombok.eclipse.Eclipse.poss; import static lombok.eclipse.handlers.EclipseHandlerUtil.makeType; import static org.eclipse.jdt.core.compiler.CategorizedProblem.CAT_TYPE; @@ -358,6 +366,10 @@ public class PatchVal { } private static TypeBinding resolveForExpression(Expression collection, BlockScope scope) { + CompilationUnitDeclaration referenceContext = scope.compilationUnitScope().referenceContext; + ProblemReporter oldProblemReporter = referenceContext.problemReporter; + referenceContext.problemReporter = new ProblemReporter(DefaultErrorHandlingPolicies.exitOnFirstError(), + oldProblemReporter.options, oldProblemReporter.problemFactory); try { return collection.resolveType(scope); } catch (ArrayIndexOutOfBoundsException e) { @@ -384,11 +396,76 @@ public class PatchVal { } } 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; + } finally { + referenceContext.problemReporter = oldProblemReporter; + } + } + + private static void clearIgnoreFurtherInvestigationField(ReferenceContext currentContext) { + if (currentContext instanceof AbstractMethodDeclaration) { + AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) currentContext; + methodDeclaration.ignoreFurtherInvestigation = false; + } else if (currentContext instanceof LambdaExpression) { + LambdaExpression lambdaExpression = (LambdaExpression) currentContext; + setValue(getField(LambdaExpression.class, "ignoreFurtherInvestigation"), lambdaExpression, false); + + Scope parent = lambdaExpression.enclosingScope.parent; + while (parent != null) { + switch(parent.kind) { + case Scope.CLASS_SCOPE: + case Scope.METHOD_SCOPE: + ReferenceContext parentAST = parent.referenceContext(); + if (parentAST != lambdaExpression) { + clearIgnoreFurtherInvestigationField(parentAST); + return; + } + default: + parent = parent.parent; + break; + } + } + + } else if (currentContext instanceof TypeDeclaration) { + TypeDeclaration typeDeclaration = (TypeDeclaration) currentContext; + typeDeclaration.ignoreFurtherInvestigation = false; + } else if (currentContext instanceof CompilationUnitDeclaration) { + CompilationUnitDeclaration typeDeclaration = (CompilationUnitDeclaration) currentContext; + typeDeclaration.ignoreFurtherInvestigation = false; + } else { + throw new UnsupportedOperationException("clearIgnoreFurtherInvestigationField for " + currentContext.getClass()); + } + } + + private static void setValue(Field field, Object object, Object value) { + try { + field.set(object, value); + } catch (IllegalAccessException e) { + throw sneakyThrow(e); + } + } + + private static Field getField(Class clazz, String name) { + try { + return Permit.getField(clazz, name); + } catch (NoSuchFieldException e) { + throw sneakyThrow(e); } } } diff --git a/test/transform/resource/after-delombok/ValInLambda.java b/test/transform/resource/after-delombok/ValInLambda.java index 7ce1e1b4..861fb9da 100644 --- a/test/transform/resource/after-delombok/ValInLambda.java +++ b/test/transform/resource/after-delombok/ValInLambda.java @@ -2,17 +2,26 @@ class ValInLambda { Runnable foo = (Runnable) () -> { final int i = 1; + final java.lang.Runnable foo = (System.currentTimeMillis() > 0) ? (Runnable) () -> { + } : System.out::println; }; - + public void easyLambda() { Runnable foo = (Runnable) () -> { final int i = 1; }; } - + public void easyIntersectionLambda() { Runnable foo = (Runnable) () -> { final int i = 1; }; } + + public void easyLubLambda() { + Runnable foo = (Runnable) () -> { + final java.lang.Runnable fooInner = (System.currentTimeMillis() > 0) ? (Runnable) () -> { + } : System.out::println; + }; + } } diff --git a/test/transform/resource/after-delombok/ValLambda.java b/test/transform/resource/after-delombok/ValLambda.java index 00ff27ad..24ae3b5f 100644 --- a/test/transform/resource/after-delombok/ValLambda.java +++ b/test/transform/resource/after-delombok/ValLambda.java @@ -1,15 +1,27 @@ // version 8: class ValLambda { + static { + final java.lang.Runnable foo = (System.currentTimeMillis() > 0) ? (Runnable) () -> { + } : System.out::println; + } + + { + final java.lang.Runnable foo = (System.currentTimeMillis() > 0) ? (Runnable) () -> { + } : System.out::println; + } + public void easyLambda() { final java.lang.Runnable foo = (Runnable) () -> { }; } + public void easyIntersectionLambda() { final java.lang.Runnable foo = (Runnable & java.io.Serializable) () -> { }; final java.io.Serializable bar = (java.io.Serializable & Runnable) () -> { }; } + public void easyLubLambda() { final java.lang.Runnable foo = (System.currentTimeMillis() > 0) ? (Runnable) () -> { } : System.out::println; diff --git a/test/transform/resource/after-ecj/ValInLambda.java b/test/transform/resource/after-ecj/ValInLambda.java index 7669789b..0fac61e9 100644 --- a/test/transform/resource/after-ecj/ValInLambda.java +++ b/test/transform/resource/after-ecj/ValInLambda.java @@ -1,9 +1,9 @@ -// version 8: - import lombok.val; class ValInLambda { Runnable foo = (Runnable) () -> { final @val int i = 1; + final @lombok.val java.lang.Runnable foo = ((System.currentTimeMillis() > 0) ? (Runnable) () -> { +} : System.out::println); }; ValInLambda() { super(); @@ -18,4 +18,10 @@ class ValInLambda { final @val int i = 1; }; } + public void easyLubLambda() { + Runnable foo = (Runnable) () -> { + final @lombok.val java.lang.Runnable fooInner = ((System.currentTimeMillis() > 0) ? (Runnable) () -> { +} : System.out::println); +}; + } } diff --git a/test/transform/resource/after-ecj/ValLambda.java b/test/transform/resource/after-ecj/ValLambda.java index fcb855b3..5b52869f 100644 --- a/test/transform/resource/after-ecj/ValLambda.java +++ b/test/transform/resource/after-ecj/ValLambda.java @@ -1,4 +1,14 @@ class ValLambda { + static { + final @lombok.val java.lang.Runnable foo = ((System.currentTimeMillis() > 0) ? (Runnable) () -> { +} : System.out::println); + } + { + final @lombok.val java.lang.Runnable foo = ((System.currentTimeMillis() > 0) ? (Runnable) () -> { +} : System.out::println); + } + <clinit>() { + } ValLambda() { super(); } diff --git a/test/transform/resource/before/ValInLambda.java b/test/transform/resource/before/ValInLambda.java index 2c2a5942..a5364f8e 100644 --- a/test/transform/resource/before/ValInLambda.java +++ b/test/transform/resource/before/ValInLambda.java @@ -5,6 +5,7 @@ import lombok.val; class ValInLambda { Runnable foo = (Runnable) () -> { val i = 1; + lombok.val foo = (System.currentTimeMillis() > 0) ? (Runnable)()-> {} : System.out::println; }; public void easyLambda() { @@ -18,4 +19,10 @@ class ValInLambda { val i = 1; }; } + + public void easyLubLambda() { + Runnable foo = (Runnable) () -> { + lombok.val fooInner = (System.currentTimeMillis() > 0) ? (Runnable)()-> {} : System.out::println; + }; + } } diff --git a/test/transform/resource/before/ValLambda.java b/test/transform/resource/before/ValLambda.java index 35f83c3c..5c9c4a43 100644 --- a/test/transform/resource/before/ValLambda.java +++ b/test/transform/resource/before/ValLambda.java @@ -1,5 +1,13 @@ // version 8: class ValLambda { + + static { + lombok.val foo = (System.currentTimeMillis() > 0) ? (Runnable)()-> {} : System.out::println; + } + { + lombok.val foo = (System.currentTimeMillis() > 0) ? (Runnable)()-> {} : System.out::println; + } + public void easyLambda() { lombok.val foo = (Runnable)()-> {}; } diff --git a/test/transform/resource/messages-ecj/ValLambda.java.messages b/test/transform/resource/messages-ecj/ValLambda.java.messages index 21c831c3..e6940434 100644 --- a/test/transform/resource/messages-ecj/ValLambda.java.messages +++ b/test/transform/resource/messages-ecj/ValLambda.java.messages @@ -1,2 +1,2 @@ -14 Function is a raw type. References to generic type Function<T,R> should be parameterized -15 Function is a raw type. References to generic type Function<T,R> should be parameterized
\ No newline at end of file +23 Function is a raw type. References to generic type Function<T,R> should be parameterized +24 Function is a raw type. References to generic type Function<T,R> should be parameterized
\ No newline at end of file |