diff options
-rw-r--r-- | src/core/lombok/core/AST.java | 2 | ||||
-rw-r--r-- | src/core/lombok/eclipse/Eclipse.java | 44 | ||||
-rw-r--r-- | src/core/lombok/javac/JavacResolution.java | 17 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleVal.java | 11 | ||||
-rw-r--r-- | src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java | 36 |
5 files changed, 79 insertions, 31 deletions
diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java index 7e71b248..8ea554a1 100644 --- a/src/core/lombok/core/AST.java +++ b/src/core/lombok/core/AST.java @@ -65,7 +65,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>, this.imports = Collections.unmodifiableCollection(new ArrayList<String>(imports)); } - protected void setChanged() { + public void setChanged() { this.changed = true; } diff --git a/src/core/lombok/eclipse/Eclipse.java b/src/core/lombok/eclipse/Eclipse.java index c4632fba..4a1a6c7a 100644 --- a/src/core/lombok/eclipse/Eclipse.java +++ b/src/core/lombok/eclipse/Eclipse.java @@ -311,30 +311,52 @@ public class Eclipse { } public static TypeReference makeType(TypeBinding binding, ASTNode pos, boolean allowCompound) { + int dims = binding.dimensions(); + binding = binding.leafComponentType(); + // Primitives + + char[] base = null; + switch (binding.id) { case TypeIds.T_int: - return new SingleTypeReference(TypeConstants.INT, pos(pos)); + base = TypeConstants.INT; + break; case TypeIds.T_long: - return new SingleTypeReference(TypeConstants.LONG, pos(pos)); + base = TypeConstants.LONG; + break; case TypeIds.T_short: - return new SingleTypeReference(TypeConstants.SHORT, pos(pos)); + base = TypeConstants.SHORT; + break; case TypeIds.T_byte: - return new SingleTypeReference(TypeConstants.BYTE, pos(pos)); + base = TypeConstants.BYTE; + break; case TypeIds.T_double: - return new SingleTypeReference(TypeConstants.DOUBLE, pos(pos)); + base = TypeConstants.DOUBLE; + break; case TypeIds.T_float: - return new SingleTypeReference(TypeConstants.FLOAT, pos(pos)); + base = TypeConstants.FLOAT; + break; case TypeIds.T_boolean: - return new SingleTypeReference(TypeConstants.BOOLEAN, pos(pos)); - case TypeIds.T_void: - return new SingleTypeReference(TypeConstants.VOID, pos(pos)); + base = TypeConstants.BOOLEAN; + break; case TypeIds.T_char: - return new SingleTypeReference(TypeConstants.CHAR, pos(pos)); + base = TypeConstants.CHAR; + break; + case TypeIds.T_void: + base = TypeConstants.VOID; + break; case TypeIds.T_null: return null; } + if (base != null) { + if (dims > 0) { + return new ArrayTypeReference(base, dims, pos(pos)); + } + return new SingleTypeReference(base, pos(pos)); + } + if (binding.isAnonymousType()) { ReferenceBinding ref = (ReferenceBinding)binding; ReferenceBinding[] supers = ref.superInterfaces(); @@ -406,8 +428,6 @@ public class Eclipse { } } - int dims = binding.dimensions(); - if (params.length > 0) { if (parts.length > 1) { TypeReference[][] typeArguments = new TypeReference[parts.length][]; diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java index 6c60b11e..14de1ff8 100644 --- a/src/core/lombok/javac/JavacResolution.java +++ b/src/core/lombok/javac/JavacResolution.java @@ -12,6 +12,7 @@ import javax.tools.DiagnosticListener; import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Symbol.TypeSymbol; +import com.sun.tools.javac.code.Type.ArrayType; import com.sun.tools.javac.code.Type.CapturedType; import com.sun.tools.javac.code.Type.ClassType; import com.sun.tools.javac.code.Type; @@ -388,6 +389,22 @@ public class JavacResolution { } private static JCExpression typeToJCTree(Type type, TreeMaker maker, JavacAST ast, boolean allowCompound) throws TypeNotConvertibleException { + int dims = 0; + Type type0 = type; + while (type0 instanceof ArrayType) { + dims++; + type0 = ((ArrayType)type0).elemtype; + } + + JCExpression result = typeToJCTree0(type0, maker, ast, allowCompound); + while (dims > 0) { + result = maker.TypeArray(result); + dims--; + } + return result; + } + + private static JCExpression typeToJCTree0(Type type, TreeMaker maker, JavacAST ast, boolean allowCompound) throws TypeNotConvertibleException { // NB: There's such a thing as maker.Type(type), but this doesn't work very well; it screws up anonymous classes, captures, and adds an extra prefix dot for some reason too. // -- so we write our own take on that here. diff --git a/src/core/lombok/javac/handlers/HandleVal.java b/src/core/lombok/javac/handlers/HandleVal.java index a6f22093..7161a7c3 100644 --- a/src/core/lombok/javac/handlers/HandleVal.java +++ b/src/core/lombok/javac/handlers/HandleVal.java @@ -33,6 +33,7 @@ import com.sun.tools.javac.code.Type; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop; import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCNewArray; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; @ProviderFor(JavacASTVisitor.class) @@ -57,6 +58,11 @@ public class HandleVal extends JavacASTAdapter { return; } + if (local.init instanceof JCNewArray && ((JCNewArray)local.init).elemtype == null) { + localNode.addError("'val' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })"); + return; + } + local.mods.flags |= Flags.FINAL; JCExpression oldVarType = local.vartype; local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst()); @@ -88,7 +94,10 @@ public class HandleVal extends JavacASTAdapter { // TODO: Fix enhanced for loops - then uncomment a bunch of lines in test/transform/resource/*/ValInFor.java } replacement = JavacResolution.typeToJCTree(type, localNode.getTreeMaker(), localNode.getAst()); - if (replacement != null) local.vartype = replacement; + if (replacement != null) { + local.vartype = replacement; + localNode.getAst().setChanged(); + } else local.vartype = oldVarType; } catch (JavacResolution.TypeNotConvertibleException e) { localNode.addError("Cannot use 'val' here because initializer expression does not have a representable type: " + e.getMessage()); diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index e962ecbf..0c9f1ccc 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -69,7 +69,7 @@ public class EclipsePatcher extends Agent { patchPostCompileHookEcj(sm); } - patchEcjTransformers(sm); + patchEcjTransformers(sm, ecjOnly); if (reloadExistingClasses) sm.reloadClasses(instrumentation); } @@ -256,8 +256,8 @@ public class EclipsePatcher extends Agent { .request(StackRequest.THIS, StackRequest.RETURN_VALUE).build()); } - private static void patchEcjTransformers(ScriptManager sm) { - patchHandleVal(sm); + private static void patchEcjTransformers(ScriptManager sm, boolean ecj) { + patchHandleVal(sm, ecj); } // Creates a copy of the 'initialization' field on a LocalDeclaration if the type of the LocalDeclaration is 'val', because the completion parser will null this out, @@ -265,7 +265,7 @@ public class EclipsePatcher extends Agent { // Also patches local declaration to not call .resolveType() on the initializer expression if we've already done so (calling it twice causes weird errors), // and patches .resolve() on LocalDeclaration itself to just-in-time replace the 'val' vartype with the right one. - private static void patchHandleVal(ScriptManager sm) { + private static void patchHandleVal(ScriptManager sm, boolean ecj) { final String LOCALDECLARATION_SIG = "org.eclipse.jdt.internal.compiler.ast.LocalDeclaration"; final String EXPRESSION_SIG = "org.eclipse.jdt.internal.compiler.ast.Expression"; final String BLOCKSCOPE_SIG = "org.eclipse.jdt.internal.compiler.lookup.BlockScope"; @@ -278,19 +278,21 @@ public class EclipsePatcher extends Agent { .decisionMethod(new Hook("lombok.eclipse.agent.PatchFixes", "handleValForLocalDeclaration", "boolean", LOCALDECLARATION_SIG, BLOCKSCOPE_SIG)) .build()); - sm.addScript(ScriptBuilder.addField() - .fieldName("$initCopy") - .fieldType("Lorg/eclipse/jdt/internal/compiler/ast/ASTNode;") - .setPublic() - .setTransient() - .targetClass("org.eclipse.jdt.internal.compiler.ast.LocalDeclaration") - .build()); - - sm.addScript(ScriptBuilder.wrapReturnValue() - .target(new MethodTarget(PARSER_SIG, "consumeExitVariableWithInitialization", "void")) - .request(StackRequest.THIS) - .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "copyInitializationOfLocalDeclarationForVal", "void", PARSER_SIG)) - .build()); + if (!ecj) { + sm.addScript(ScriptBuilder.addField() + .fieldName("$initCopy") + .fieldType("Lorg/eclipse/jdt/internal/compiler/ast/ASTNode;") + .setPublic() + .setTransient() + .targetClass("org.eclipse.jdt.internal.compiler.ast.LocalDeclaration") + .build()); + + sm.addScript(ScriptBuilder.wrapReturnValue() + .target(new MethodTarget(PARSER_SIG, "consumeExitVariableWithInitialization", "void")) + .request(StackRequest.THIS) + .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "copyInitializationOfLocalDeclarationForVal", "void", PARSER_SIG)) + .build()); + } sm.addScript(ScriptBuilder.replaceMethodCall() .target(new MethodTarget(LOCALDECLARATION_SIG, "resolve", "void", BLOCKSCOPE_SIG)) |