aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/lombok/javac/handlers/HandleConstructor.java13
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java74
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;
+ }
}