diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/lombok/javac/handlers/HandleConstructor.java | 13 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/JavacHandlerUtil.java | 74 |
2 files changed, 75 insertions, 12 deletions
diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index 65ad2547..d701b41e 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -43,12 +43,10 @@ import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; -import com.sun.tools.javac.tree.JCTree.JCIdent; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCModifiers; import com.sun.tools.javac.tree.JCTree.JCReturn; import com.sun.tools.javac.tree.JCTree.JCStatement; -import com.sun.tools.javac.tree.JCTree.JCTypeApply; import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.List; @@ -268,16 +266,7 @@ public class HandleConstructor { for (JavacNode fieldNode : fields) { JCVariableDecl field = (JCVariableDecl) fieldNode.get(); - JCExpression pType; - if (field.vartype instanceof JCIdent) pType = maker.Ident(((JCIdent)field.vartype).name); - else if (field.vartype instanceof JCTypeApply) { - JCTypeApply typeApply = (JCTypeApply) field.vartype; - ListBuffer<JCExpression> tArgs = ListBuffer.lb(); - for (JCExpression arg : typeApply.arguments) tArgs.append(arg); - pType = maker.TypeApply(typeApply.clazz, tArgs.toList()); - } else { - pType = field.vartype; - } + JCExpression pType = cloneType(maker, field.vartype, source); List<JCAnnotation> nonNulls = findAnnotations(fieldNode, TransformationsUtil.NON_NULL_PATTERN); List<JCAnnotation> nullables = findAnnotations(fieldNode, TransformationsUtil.NULLABLE_PATTERN); JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL, nonNulls.appendList(nullables)), field.name, pType, null); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index d2905101..ce7421b1 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -45,14 +45,17 @@ import lombok.experimental.Accessors; import lombok.javac.Javac; import lombok.javac.JavacNode; +import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.TypeTags; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; import com.sun.tools.javac.tree.JCTree.JCAssign; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCIdent; import com.sun.tools.javac.tree.JCTree.JCImport; import com.sun.tools.javac.tree.JCTree.JCLiteral; @@ -60,8 +63,12 @@ import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; import com.sun.tools.javac.tree.JCTree.JCModifiers; import com.sun.tools.javac.tree.JCTree.JCNewArray; +import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree; import com.sun.tools.javac.tree.JCTree.JCStatement; +import com.sun.tools.javac.tree.JCTree.JCTypeApply; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.tree.JCTree.JCWildcard; +import com.sun.tools.javac.tree.JCTree.TypeBoundKind; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -920,4 +927,71 @@ public class JavacHandlerUtil { return node; } + + /** + * Creates a full clone of a given javac AST type node. Every part is cloned (every identifier, every select, every wildcard, every type apply). + * + * If there's any node in the tree that we don't know how to clone, that part isn't cloned. However, we wouldn't know what could possibly show up that we + * can't currently clone; that's just a safeguard. + * + * This should be used if the type looks the same in the code, but resolves differently. For example, a static method that has some generics in it named after + * the class's own parameter, but as its a static method, the static method's notion of {@code T} is different from the class notion of {@code T}. If you're duplicating + * a type used in the class context, you need to use this method. + */ + public static JCExpression cloneType(TreeMaker maker, JCExpression in, JCTree source) { + JCExpression out = cloneType0(maker, in); + if (out != null) recursiveSetGeneratedBy(out, source); + return out; + } + + private static JCExpression cloneType0(TreeMaker maker, JCTree in) { + if (in == null) return null; + + if (in instanceof JCPrimitiveTypeTree) return (JCExpression) in; + + if (in instanceof JCIdent) { + return maker.Ident(((JCIdent) in).name); + } + + if (in instanceof JCFieldAccess) { + JCFieldAccess fa = (JCFieldAccess) in; + return maker.Select(cloneType0(maker, fa.selected), fa.name); + } + + if (in instanceof JCArrayTypeTree) { + JCArrayTypeTree att = (JCArrayTypeTree) in; + return maker.TypeArray(cloneType0(maker, att.elemtype)); + } + + if (in instanceof JCTypeApply) { + JCTypeApply ta = (JCTypeApply) in; + ListBuffer<JCExpression> lb = ListBuffer.lb(); + for (JCExpression typeArg : ta.arguments) { + lb.append(cloneType0(maker, typeArg)); + } + return maker.TypeApply(cloneType0(maker, ta.clazz), lb.toList()); + } + + if (in instanceof JCWildcard) { + JCWildcard w = (JCWildcard) in; + JCExpression newInner = cloneType0(maker, w.inner); + TypeBoundKind newKind; + switch (w.getKind()) { + case SUPER_WILDCARD: + newKind = maker.TypeBoundKind(BoundKind.SUPER); + break; + case EXTENDS_WILDCARD: + newKind = maker.TypeBoundKind(BoundKind.EXTENDS); + break; + default: + case UNBOUNDED_WILDCARD: + newKind = maker.TypeBoundKind(BoundKind.UNBOUND); + break; + } + return maker.Wildcard(newKind, newInner); + } + + // This is somewhat unsafe, but it's better than outright throwing an exception here. Returning null will just cause an exception down the pipeline. + return (JCExpression) in; + } } |