aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lombok/javac/handlers')
-rw-r--r--src/core/lombok/javac/handlers/HandleSuperBuilder.java8
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java72
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java6
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java6
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java11
5 files changed, 94 insertions, 9 deletions
diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
index bcb7ee33..66d6e47e 100644
--- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
@@ -80,6 +80,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
private static final String SELF_METHOD = "self";
private static class BuilderFieldData {
+ List<JCAnnotation> annotations;
JCExpression type;
Name rawName;
Name name;
@@ -135,6 +136,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
BuilderFieldData bfd = new BuilderFieldData();
bfd.rawName = fd.name;
bfd.name = removePrefixFromField(fieldNode);
+ bfd.annotations = findCopyableAnnotations(fieldNode);
bfd.type = fd.vartype;
bfd.singularData = getSingularData(fieldNode);
bfd.originalFieldNode = fieldNode;
@@ -616,13 +618,13 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
}};
if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) {
- generateSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, true, true, returnTypeMaker.make(), returnStatementMaker.make());
+ generateSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, true, true, returnTypeMaker.make(), returnStatementMaker.make(), fieldNode.annotations);
} else {
fieldNode.singularData.getSingularizer().generateMethods(fieldNode.singularData, deprecate, builderType, source.get(), true, returnTypeMaker, returnStatementMaker);
}
}
- private void generateSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, JCExpression returnType, JCStatement returnStatement) {
+ private void generateSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, JCExpression returnType, JCStatement returnStatement, List<JCAnnotation> annosOnParam) {
Name fieldName = ((JCVariableDecl) fieldNode.get()).name;
for (JavacNode child : builderType.down()) {
@@ -636,7 +638,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
JavacTreeMaker maker = fieldNode.getTreeMaker();
- JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, nameOfSetFlag, returnType, returnStatement, source, List.<JCAnnotation>nil(), List.<JCAnnotation>nil());
+ JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, nameOfSetFlag, returnType, returnStatement, source, List.<JCAnnotation>nil(), annosOnParam);
injectMethod(builderType, newMethod);
}
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index b1557533..e4e40095 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -27,6 +27,7 @@ import static lombok.javac.Javac.*;
import static lombok.javac.JavacAugments.JCTree_generatedNode;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -1039,6 +1040,57 @@ public class JavacHandlerUtil {
return (field.mods.flags & Flags.ENUM) != 0;
}
+ static class JCAnnotatedTypeReflect {
+ private static Class<?> TYPE;
+ private static Constructor<?> CONSTRUCTOR;
+ private static Field ANNOTATIONS, UNDERLYING_TYPE;
+
+ private static void init(Class<?> in) {
+ if (TYPE != null) return;
+ if (!in.getName().equals("com.sun.tools.javac.tree.JCTree$JCAnnotatedType")) return;
+ try {
+ CONSTRUCTOR = in.getDeclaredConstructor(List.class, JCExpression.class);
+ CONSTRUCTOR.setAccessible(true);
+ ANNOTATIONS = in.getDeclaredField("annotations");
+ UNDERLYING_TYPE = in.getDeclaredField("underlyingType");
+ TYPE = in;
+ } catch (Exception ignore) {}
+ }
+
+ static boolean is(JCTree obj) {
+ if (obj == null) return false;
+ init(obj.getClass());
+ return obj.getClass() == TYPE;
+ }
+
+ @SuppressWarnings("unchecked")
+ static List<JCAnnotation> getAnnotations(JCTree obj) {
+ init(obj.getClass());
+ try {
+ return (List<JCAnnotation>) ANNOTATIONS.get(obj);
+ } catch (Exception e) {
+ return List.nil();
+ }
+ }
+
+ static JCExpression getUnderlyingType(JCTree obj) {
+ init(obj.getClass());
+ try {
+ return (JCExpression) UNDERLYING_TYPE.get(obj);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ static JCExpression create(List<JCAnnotation> annotations, JCExpression underlyingType) {
+ try {
+ return (JCExpression) CONSTRUCTOR.newInstance(annotations, underlyingType);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ }
+
// jdk9 support, types have changed, names stay the same
static class ClassSymbolMembersField {
private static final Field membersField;
@@ -1570,6 +1622,16 @@ public class JavacHandlerUtil {
return out.toList();
}
+ public static List<JCAnnotation> getTypeUseAnnotations(JCExpression from) {
+ if (!JCAnnotatedTypeReflect.is(from)) return List.nil();
+ return JCAnnotatedTypeReflect.getAnnotations(from);
+ }
+
+ public static JCExpression removeTypeUseAnnotations(JCExpression from) {
+ if (!JCAnnotatedTypeReflect.is(from)) return from;
+ return JCAnnotatedTypeReflect.getUnderlyingType(from);
+ }
+
public static JCExpression namePlusTypeParamsToTypeReference(JavacTreeMaker maker, Name typeName, List<JCTypeParameter> params) {
if (params.isEmpty()) {
return maker.Ident(typeName);
@@ -1650,7 +1712,7 @@ public class JavacHandlerUtil {
}
/**
- * Creates a full clone of a given javac AST type node. Every part is cloned (every identifier, every select, every wildcard, every type apply).
+ * Creates a full clone of a given javac AST type node. Every part is cloned (every identifier, every select, every wildcard, every type apply, every type_use annotation).
*
* 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.
@@ -1712,6 +1774,12 @@ public class JavacHandlerUtil {
return maker.Wildcard(newKind, newInner);
}
+ if (JCAnnotatedTypeReflect.is(in)) {
+ JCExpression underlyingType = cloneType0(maker, JCAnnotatedTypeReflect.getUnderlyingType(in));
+ List<JCAnnotation> anns = copyAnnotations(JCAnnotatedTypeReflect.getAnnotations(in));
+ return JCAnnotatedTypeReflect.create(anns, underlyingType);
+ }
+
// 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;
}
@@ -1887,7 +1955,7 @@ public class JavacHandlerUtil {
public static boolean isDirectDescendantOfObject(JavacNode typeNode) {
if (!(typeNode.get() instanceof JCClassDecl)) throw new IllegalArgumentException("not a type node");
- JCTree extending = Javac.getExtendsClause((JCClassDecl)typeNode.get());
+ JCTree extending = Javac.getExtendsClause((JCClassDecl) typeNode.get());
if (extending == null) return true;
String p = extending.toString();
return p.equals("Object") || p.equals("java.lang.Object");
diff --git a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
index ffaf6674..74010d52 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
@@ -39,6 +39,7 @@ import lombok.javac.handlers.JavacSingularsRecipes.StatementMaker;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
@@ -125,7 +126,10 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
for (int i = 0; i < suffixes.size(); i++) {
JCExpression pt = cloneParamType(i, maker, data.getTypeArgs(), builderType, source);
- JCVariableDecl p = maker.VarDef(maker.Modifiers(paramFlags), names[i], pt, null);
+ List<JCAnnotation> typeUseAnns = getTypeUseAnnotations(pt);
+ pt = removeTypeUseAnnotations(pt);
+ JCModifiers paramMods = typeUseAnns.isEmpty() ? maker.Modifiers(paramFlags) : maker.Modifiers(paramFlags, typeUseAnns);
+ JCVariableDecl p = maker.VarDef(paramMods, names[i], pt, null);
params.append(p);
}
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java
index 39e53ebb..26ff8ba6 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java
@@ -36,6 +36,7 @@ import lombok.javac.handlers.JavacSingularsRecipes.StatementMaker;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
@@ -124,7 +125,10 @@ abstract class JavacJavaUtilListSetSingularizer extends JavacJavaUtilSingularize
long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
if (!fluent) name = builderType.toName(HandlerUtil.buildAccessorName("add", name.toString()));
JCExpression paramType = cloneParamType(0, maker, data.getTypeArgs(), builderType, source);
- JCVariableDecl param = maker.VarDef(maker.Modifiers(paramFlags), data.getSingularName(), paramType, null);
+ List<JCAnnotation> typeUseAnns = getTypeUseAnnotations(paramType);
+ paramType = removeTypeUseAnnotations(paramType);
+ JCModifiers paramMods = typeUseAnns.isEmpty() ? maker.Modifiers(paramFlags) : maker.Modifiers(paramFlags, typeUseAnns);
+ JCVariableDecl param = maker.VarDef(paramMods, data.getSingularName(), paramType, null);
JCMethodDecl method = maker.MethodDef(mods, name, returnType, typeParams, List.of(param), thrown, body, null);
injectMethod(builderType, method);
}
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java
index 34350f40..a009b88c 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java
@@ -40,6 +40,7 @@ import org.mangosdk.spi.ProviderFor;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
@@ -165,8 +166,14 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
if (!fluent) name = builderType.toName(HandlerUtil.buildAccessorName("put", name.toString()));
JCExpression paramTypeKey = cloneParamType(0, maker, data.getTypeArgs(), builderType, source);
JCExpression paramTypeValue = cloneParamType(1, maker, data.getTypeArgs(), builderType, source);
- JCVariableDecl paramKey = maker.VarDef(maker.Modifiers(paramFlags), keyName, paramTypeKey, null);
- JCVariableDecl paramValue = maker.VarDef(maker.Modifiers(paramFlags), valueName, paramTypeValue, null);
+ List<JCAnnotation> typeUseAnnsKey = getTypeUseAnnotations(paramTypeKey);
+ List<JCAnnotation> typeUseAnnsValue = getTypeUseAnnotations(paramTypeValue);
+ paramTypeKey = removeTypeUseAnnotations(paramTypeKey);
+ paramTypeValue = removeTypeUseAnnotations(paramTypeValue);
+ JCModifiers paramModsKey = typeUseAnnsKey.isEmpty() ? maker.Modifiers(paramFlags) : maker.Modifiers(paramFlags, typeUseAnnsKey);
+ JCModifiers paramModsValue = typeUseAnnsValue.isEmpty() ? maker.Modifiers(paramFlags) : maker.Modifiers(paramFlags, typeUseAnnsValue);
+ JCVariableDecl paramKey = maker.VarDef(paramModsKey, keyName, paramTypeKey, null);
+ JCVariableDecl paramValue = maker.VarDef(paramModsValue, valueName, paramTypeValue, null);
JCMethodDecl method = maker.MethodDef(mods, name, returnType, typeParams, List.of(paramKey, paramValue), thrown, body, null);
injectMethod(builderType, method);
}