mirror of
https://github.com/tiennm99/lombok.git
synced 2026-09-04 22:16:48 +00:00
Merge branch 'enter-types-methods-fields' of git://github.com/Rawi01/lombok into Rawi01-enter-types-methods-fields
This commit is contained in:
@@ -26,8 +26,6 @@ import static lombok.javac.Javac.*;
|
||||
import static lombok.javac.handlers.JavacHandlerUtil.*;
|
||||
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCBlock;
|
||||
@@ -55,7 +53,6 @@ import lombok.core.AST.Kind;
|
||||
import lombok.core.AnnotationValues;
|
||||
import lombok.core.configuration.CheckerFrameworkVersion;
|
||||
import lombok.delombok.LombokOptionsFactory;
|
||||
import lombok.javac.Javac;
|
||||
import lombok.javac.JavacAnnotationHandler;
|
||||
import lombok.javac.JavacNode;
|
||||
import lombok.javac.JavacTreeMaker;
|
||||
@@ -243,30 +240,17 @@ public class HandleConstructor {
|
||||
|
||||
if (noArgs && noArgsConstructorExists(typeNode)) return;
|
||||
|
||||
ListBuffer<Type> argTypes = new ListBuffer<Type>();
|
||||
for (JavacNode fieldNode : fields) {
|
||||
Type mirror = getMirrorForFieldType(fieldNode);
|
||||
if (mirror == null) {
|
||||
argTypes = null;
|
||||
break;
|
||||
}
|
||||
argTypes.append(mirror);
|
||||
}
|
||||
List<Type> argTypes_ = argTypes == null ? null : argTypes.toList();
|
||||
|
||||
if (!(skipIfConstructorExists != SkipIfConstructorExists.NO && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS)) {
|
||||
JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, onConstructor, typeNode, fields, allToDefault, source);
|
||||
injectMethod(typeNode, constr, argTypes_, Javac.createVoidType(typeNode.getSymbolTable(), CTC_VOID));
|
||||
injectMethod(typeNode, constr);
|
||||
}
|
||||
generateStaticConstructor(staticConstrRequired, typeNode, staticName, level, allToDefault, fields, source, argTypes_);
|
||||
generateStaticConstructor(staticConstrRequired, typeNode, staticName, level, allToDefault, fields, source);
|
||||
}
|
||||
|
||||
private void generateStaticConstructor(boolean staticConstrRequired, JavacNode typeNode, String staticName, AccessLevel level, boolean allToDefault, List<JavacNode> fields, JavacNode source, List<Type> argTypes_) {
|
||||
private void generateStaticConstructor(boolean staticConstrRequired, JavacNode typeNode, String staticName, AccessLevel level, boolean allToDefault, List<JavacNode> fields, JavacNode source) {
|
||||
if (staticConstrRequired) {
|
||||
ClassSymbol sym = ((JCClassDecl) typeNode.get()).sym;
|
||||
Type returnType = sym == null ? null : sym.type;
|
||||
JCMethodDecl staticConstr = createStaticConstructor(staticName, level, typeNode, allToDefault ? List.<JavacNode>nil() : fields, source);
|
||||
injectMethod(typeNode, staticConstr, argTypes_, returnType);
|
||||
injectMethod(typeNode, staticConstr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ import lombok.javac.JavacTreeMaker.TypeTag;
|
||||
import lombok.spi.Provides;
|
||||
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCBinary;
|
||||
@@ -214,7 +213,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> {
|
||||
|
||||
long access = toJavacModifier(level) | (fieldDecl.mods.flags & Flags.STATIC);
|
||||
|
||||
injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker(), source, lazy, onMethod), List.<Type>nil(), getMirrorForFieldType(fieldNode));
|
||||
injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker(), source, lazy, onMethod));
|
||||
}
|
||||
|
||||
public JCMethodDecl createGetter(long access, JavacNode field, JavacTreeMaker treeMaker, JavacNode source, boolean lazy, List<JCAnnotation> onMethod) {
|
||||
|
||||
@@ -40,8 +40,6 @@ import lombok.javac.JavacTreeMaker;
|
||||
import lombok.spi.Provides;
|
||||
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAssign;
|
||||
import com.sun.tools.javac.tree.JCTree.JCBlock;
|
||||
@@ -184,17 +182,7 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> {
|
||||
long access = toJavacModifier(level) | (fieldDecl.mods.flags & Flags.STATIC);
|
||||
|
||||
JCMethodDecl createdSetter = createSetter(access, fieldNode, fieldNode.getTreeMaker(), sourceNode, onMethod, onParam);
|
||||
Type fieldType = getMirrorForFieldType(fieldNode);
|
||||
Type returnType;
|
||||
|
||||
if (shouldReturnThis(fieldNode)) {
|
||||
ClassSymbol sym = ((JCClassDecl) fieldNode.up().get()).sym;
|
||||
returnType = sym == null ? null : sym.type;
|
||||
} else {
|
||||
returnType = Javac.createVoidType(fieldNode.getSymbolTable(), CTC_VOID);
|
||||
}
|
||||
|
||||
injectMethod(fieldNode.up(), createdSetter, fieldType == null ? null : List.of(fieldType), returnType);
|
||||
injectMethod(fieldNode.up(), createdSetter);
|
||||
}
|
||||
|
||||
public static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeMaker treeMaker, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) {
|
||||
|
||||
@@ -583,7 +583,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
|
||||
null, List.<JCTypeParameter>nil(), params.toList(), List.<JCExpression>nil(),
|
||||
maker.Block(0L, statements.toList()), null), job.sourceNode);
|
||||
|
||||
injectMethod(job.parentType, constr, null, Javac.createVoidType(job.builderType.getSymbolTable(), CTC_VOID));
|
||||
injectMethod(job.parentType, constr);
|
||||
}
|
||||
|
||||
private JCMethodDecl generateBuilderMethod(SuperBuilderJob job) {
|
||||
|
||||
@@ -22,11 +22,9 @@
|
||||
package lombok.javac.handlers;
|
||||
|
||||
import static lombok.core.handlers.HandlerUtil.handleExperimentalFlagUsage;
|
||||
import static lombok.javac.Javac.CTC_VOID;
|
||||
import static lombok.javac.handlers.JavacHandlerUtil.*;
|
||||
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCBlock;
|
||||
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
|
||||
@@ -44,7 +42,6 @@ import lombok.core.AST.Kind;
|
||||
import lombok.core.AnnotationValues;
|
||||
import lombok.core.HandlerPriority;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import lombok.javac.Javac;
|
||||
import lombok.javac.JavacAnnotationHandler;
|
||||
import lombok.javac.JavacNode;
|
||||
import lombok.javac.JavacTreeMaker;
|
||||
@@ -141,7 +138,7 @@ public class HandleUtilityClass extends JavacAnnotationHandler<UtilityClass> {
|
||||
JCBlock block = maker.Block(0L, createThrowStatement(typeNode, maker));
|
||||
JCMethodDecl methodDef = maker.MethodDef(mods, name, null, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), block, null);
|
||||
JCMethodDecl constructor = recursiveSetGeneratedBy(methodDef, typeNode);
|
||||
JavacHandlerUtil.injectMethod(typeNode, constructor, List.<Type>nil(), Javac.createVoidType(typeNode.getSymbolTable(), CTC_VOID));
|
||||
JavacHandlerUtil.injectMethod(typeNode, constructor);
|
||||
}
|
||||
|
||||
private List<JCStatement> createThrowStatement(JavacNode typeNode, JavacTreeMaker maker) {
|
||||
|
||||
@@ -40,8 +40,6 @@ import lombok.javac.handlers.JavacHandlerUtil.CopyJavadoc;
|
||||
import lombok.spi.Provides;
|
||||
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCBlock;
|
||||
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
|
||||
@@ -211,11 +209,8 @@ public class HandleWith extends JavacAnnotationHandler<With> {
|
||||
|
||||
JCMethodDecl createdWith = createWith(access, fieldNode, fieldNode.getTreeMaker(), source, onMethod, onParam, makeAbstract);
|
||||
createRelevantNonNullAnnotation(fieldNode, createdWith);
|
||||
ClassSymbol sym = ((JCClassDecl) fieldNode.up().get()).sym;
|
||||
Type returnType = sym == null ? null : sym.type;
|
||||
|
||||
recursiveSetGeneratedBy(createdWith, source);
|
||||
injectMethod(typeNode, createdWith, List.<Type>of(getMirrorForFieldType(fieldNode)), returnType);
|
||||
injectMethod(typeNode, createdWith);
|
||||
}
|
||||
|
||||
public JCMethodDecl createWith(long access, JavacNode field, JavacTreeMaker maker, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam, boolean makeAbstract) {
|
||||
|
||||
@@ -45,8 +45,6 @@ import lombok.spi.Provides;
|
||||
|
||||
import com.sun.tools.javac.code.BoundKind;
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCBlock;
|
||||
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
|
||||
@@ -204,11 +202,8 @@ public class HandleWithBy extends JavacAnnotationHandler<WithBy> {
|
||||
long access = toJavacModifier(level);
|
||||
|
||||
JCMethodDecl createdWithBy = createWithBy(access, fieldNode, fieldNode.getTreeMaker(), source, onMethod, makeAbstract);
|
||||
ClassSymbol sym = ((JCClassDecl) fieldNode.up().get()).sym;
|
||||
Type returnType = sym == null ? null : sym.type;
|
||||
|
||||
recursiveSetGeneratedBy(createdWithBy, source);
|
||||
injectMethod(typeNode, createdWithBy, List.<Type>of(getMirrorForFieldType(fieldNode)), returnType);
|
||||
injectMethod(typeNode, createdWithBy);
|
||||
}
|
||||
|
||||
private static final LombokImmutableList<String> NAME_JUF_FUNCTION = LombokImmutableList.of("java", "util", "function", "Function");
|
||||
|
||||
@@ -37,19 +37,19 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.tools.javac.code.Attribute;
|
||||
import com.sun.tools.javac.code.BoundKind;
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Scope;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.MethodSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.VarSymbol;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.code.Symbol.TypeSymbol;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Type.MethodType;
|
||||
import com.sun.tools.javac.comp.Annotate;
|
||||
import com.sun.tools.javac.comp.AttrContext;
|
||||
import com.sun.tools.javac.comp.Enter;
|
||||
import com.sun.tools.javac.comp.Env;
|
||||
import com.sun.tools.javac.comp.MemberEnter;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
|
||||
@@ -1010,12 +1010,6 @@ public class JavacHandlerUtil {
|
||||
return call;
|
||||
}
|
||||
|
||||
public static Type getMirrorForFieldType(JavacNode fieldNode) {
|
||||
Element fieldElement = fieldNode.getElement();
|
||||
if (fieldElement instanceof VarSymbol) return ((VarSymbol) fieldElement).type;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given new field declaration to the provided type AST Node.
|
||||
* The field carries the @{@link SuppressWarnings}("all") annotation.
|
||||
@@ -1071,6 +1065,8 @@ public class JavacHandlerUtil {
|
||||
insertAfter.tail = fieldEntry;
|
||||
}
|
||||
|
||||
EnterReflect.memberEnter(field, typeNode);
|
||||
|
||||
return typeNode.add(field, Kind.FIELD);
|
||||
}
|
||||
|
||||
@@ -1148,19 +1144,30 @@ public class JavacHandlerUtil {
|
||||
}
|
||||
|
||||
static class JCAnnotationReflect {
|
||||
private static Field ATTRIBUTE;
|
||||
|
||||
private static final Field ATTRIBUTE;
|
||||
|
||||
static {
|
||||
try {
|
||||
ATTRIBUTE = Permit.getField(JCAnnotation.class, "attribute");
|
||||
} catch (Exception ignore) {}
|
||||
ATTRIBUTE = Permit.permissiveGetField(JCAnnotation.class, "attribute");
|
||||
}
|
||||
|
||||
static Attribute.Compound getAttribute(JCAnnotation jcAnnotation) {
|
||||
try {
|
||||
return (Attribute.Compound) ATTRIBUTE.get(jcAnnotation);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
if (ATTRIBUTE != null) {
|
||||
try {
|
||||
return (Attribute.Compound) ATTRIBUTE.get(jcAnnotation);
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static void setAttribute(JCAnnotation jcAnnotation, Attribute.Compound attribute) {
|
||||
if (ATTRIBUTE != null) {
|
||||
try {
|
||||
Permit.set(ATTRIBUTE, jcAnnotation, attribute);
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1204,8 +1211,10 @@ public class JavacHandlerUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void injectMethod(JavacNode typeNode, JCMethodDecl method) {
|
||||
injectMethod(typeNode, method, null, null);
|
||||
|
||||
@Deprecated
|
||||
public static void injectMethod(JavacNode typeNode, JCMethodDecl method, List<Type> paramTypes, Type returnType) {
|
||||
injectMethod(typeNode, method);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1214,9 +1223,7 @@ public class JavacHandlerUtil {
|
||||
*
|
||||
* Also takes care of updating the JavacAST.
|
||||
*/
|
||||
public static void injectMethod(JavacNode typeNode, JCMethodDecl method, List<Type> paramTypes, Type returnType) {
|
||||
Context context = typeNode.getContext();
|
||||
Symtab symtab = Symtab.instance(context);
|
||||
public static void injectMethod(JavacNode typeNode, JCMethodDecl method) {
|
||||
JCClassDecl type = (JCClassDecl) typeNode.get();
|
||||
|
||||
if (method.getName().contentEquals("<init>")) {
|
||||
@@ -1240,55 +1247,11 @@ public class JavacHandlerUtil {
|
||||
addGenerated(method.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(method)), typeNode.getContext());
|
||||
type.defs = type.defs.append(method);
|
||||
|
||||
List<Symbol.VarSymbol> params = null;
|
||||
if (method.getParameters() != null && !method.getParameters().isEmpty()) {
|
||||
ListBuffer<Symbol.VarSymbol> newParams = new ListBuffer<Symbol.VarSymbol>();
|
||||
for (int i = 0; i < method.getParameters().size(); i++) {
|
||||
JCTree.JCVariableDecl param = method.getParameters().get(i);
|
||||
if (param.sym == null) {
|
||||
Type paramType = paramTypes == null ? param.getType().type : paramTypes.get(i);
|
||||
VarSymbol varSymbol = new VarSymbol(param.mods.flags, param.name, paramType, symtab.noSymbol);
|
||||
varSymbol.adr = 1 << i;
|
||||
List<JCAnnotation> annotations = param.getModifiers().getAnnotations();
|
||||
if (annotations != null && !annotations.isEmpty()) {
|
||||
ListBuffer<Attribute.Compound> newAnnotations = new ListBuffer<Attribute.Compound>();
|
||||
for (JCAnnotation jcAnnotation : annotations) {
|
||||
Attribute.Compound attribute = JCAnnotationReflect.getAttribute(jcAnnotation);
|
||||
if (attribute != null) {
|
||||
newAnnotations.append(attribute);
|
||||
}
|
||||
}
|
||||
if (annotations.length() == newAnnotations.length()) {
|
||||
varSymbol.appendAttributes(newAnnotations.toList());
|
||||
}
|
||||
}
|
||||
newParams.append(varSymbol);
|
||||
} else {
|
||||
newParams.append(param.sym);
|
||||
}
|
||||
}
|
||||
params = newParams.toList();
|
||||
if (params.length() != method.getParameters().length()) params = null;
|
||||
}
|
||||
|
||||
fixMethodMirror(typeNode.getContext(), typeNode.getElement(), method.getModifiers().flags, method.getName(), paramTypes, params, returnType);
|
||||
EnterReflect.memberEnter(method, typeNode);
|
||||
|
||||
typeNode.add(method, Kind.METHOD);
|
||||
}
|
||||
|
||||
private static void fixMethodMirror(Context context, Element typeMirror, long access, Name methodName, List<Type> paramTypes, List<Symbol.VarSymbol> params, Type returnType) {
|
||||
if (typeMirror == null || paramTypes == null || returnType == null) return;
|
||||
ClassSymbol cs = (ClassSymbol) typeMirror;
|
||||
MethodSymbol methodSymbol = new MethodSymbol(access, methodName, new MethodType(paramTypes, returnType, List.<Type>nil(), Symtab.instance(context).methodClass), cs);
|
||||
if (params != null && !params.isEmpty()) {
|
||||
methodSymbol.params = params;
|
||||
for (VarSymbol varSymbol : params) {
|
||||
varSymbol.owner = methodSymbol;
|
||||
}
|
||||
}
|
||||
ClassSymbolMembersField.enter(cs, methodSymbol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an inner type (class, interface, enum) to the given type. Cannot inject top-level types.
|
||||
*
|
||||
@@ -1301,9 +1264,55 @@ public class JavacHandlerUtil {
|
||||
addSuppressWarningsAll(type.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(type)), typeNode.getContext());
|
||||
addGenerated(type.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(type)), typeNode.getContext());
|
||||
typeDecl.defs = typeDecl.defs.append(type);
|
||||
|
||||
EnterReflect.classEnter(type, typeNode);
|
||||
|
||||
return typeNode.add(type, Kind.TYPE);
|
||||
}
|
||||
|
||||
static class EnterReflect {
|
||||
private static final Method classEnter;
|
||||
private static final Method memberEnter;
|
||||
private static final Method blockAnnotations;
|
||||
private static final Method unblockAnnotations;
|
||||
|
||||
static {
|
||||
classEnter = Permit.permissiveGetMethod(Enter.class, "classEnter", JCTree.class, Env.class);
|
||||
memberEnter = Permit.permissiveGetMethod(MemberEnter.class, "memberEnter", JCTree.class, Env.class);
|
||||
|
||||
Method block = Permit.permissiveGetMethod(Annotate.class, "blockAnnotations");
|
||||
if (block == null) block = Permit.permissiveGetMethod(Annotate.class, "enterStart");
|
||||
blockAnnotations = block;
|
||||
|
||||
Method unblock = Permit.permissiveGetMethod(Annotate.class, "unblockAnnotations");
|
||||
if (unblock == null) unblock = Permit.permissiveGetMethod(Annotate.class, "enterDone");
|
||||
unblockAnnotations = unblock;
|
||||
}
|
||||
|
||||
static Type classEnter(JCTree tree, JavacNode parent) {
|
||||
Enter enter = Enter.instance(parent.getContext());
|
||||
Env<AttrContext> classEnv = enter.getEnv((TypeSymbol) parent.getElement());
|
||||
Type type = (Type) Permit.invokeSneaky(classEnter, enter, tree, classEnv);
|
||||
if (type == null) return null;
|
||||
type.complete();
|
||||
return type;
|
||||
}
|
||||
|
||||
static void memberEnter(JCTree tree, JavacNode parent) {
|
||||
Context context = parent.getContext();
|
||||
MemberEnter me = MemberEnter.instance(context);
|
||||
Annotate annotate = Annotate.instance(context);
|
||||
Enter enter = Enter.instance(context);
|
||||
|
||||
Env<AttrContext> classEnv = enter.getEnv((TypeSymbol) parent.getElement());
|
||||
if (classEnv == null) return;
|
||||
|
||||
Permit.invokeSneaky(blockAnnotations, annotate);
|
||||
Permit.invokeSneaky(memberEnter, me, tree, classEnv);
|
||||
Permit.invokeSneaky(unblockAnnotations, annotate);
|
||||
}
|
||||
}
|
||||
|
||||
public static long addFinalIfNeeded(long flags, Context context) {
|
||||
boolean addFinal = LombokOptionsFactory.getDelombokOptions(context).getFormatPreferences().generateFinalParams();
|
||||
|
||||
@@ -1802,10 +1811,49 @@ public class JavacHandlerUtil {
|
||||
addError(errorName, annotationNode);
|
||||
}
|
||||
}
|
||||
for (JCAnnotation annotation : result) {
|
||||
clearTypes(annotation);
|
||||
}
|
||||
ast.args = params.toList();
|
||||
return result.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all type information from the provided tree.
|
||||
*/
|
||||
private static void clearTypes(JCTree tree) {
|
||||
tree.accept(new TreeScanner() {
|
||||
@Override public void scan(JCTree tree) {
|
||||
tree.type = null;
|
||||
super.scan(tree);
|
||||
}
|
||||
@Override public void visitClassDef(JCClassDecl tree) {
|
||||
tree.sym = null;
|
||||
super.visitClassDef(tree);
|
||||
}
|
||||
@Override public void visitMethodDef(JCMethodDecl tree) {
|
||||
tree.sym = null;
|
||||
super.visitMethodDef(tree);
|
||||
}
|
||||
@Override public void visitVarDef(JCVariableDecl tree) {
|
||||
tree.sym = null;
|
||||
super.visitVarDef(tree);
|
||||
}
|
||||
@Override public void visitSelect(JCFieldAccess tree) {
|
||||
tree.sym = null;
|
||||
super.visitSelect(tree);
|
||||
}
|
||||
@Override public void visitIdent(JCIdent tree) {
|
||||
tree.sym = null;
|
||||
super.visitIdent(tree);
|
||||
}
|
||||
@Override public void visitAnnotation(JCAnnotation tree) {
|
||||
JCAnnotationReflect.setAttribute(tree, null);
|
||||
super.visitAnnotation(tree);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void addError(String errorName, JavacNode node) {
|
||||
if (node.getLatestJavaSpecSupported() < 8) {
|
||||
node.addError("The correct format up to JDK7 is " + errorName + "=@__({@SomeAnnotation, @SomeOtherAnnotation}))");
|
||||
|
||||
@@ -35,19 +35,21 @@ import java.util.Deque;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.source.util.Trees;
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.TreeScanner;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAssign;
|
||||
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
|
||||
@@ -57,11 +59,12 @@ import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCModifiers;
|
||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.TypeBoundKind;
|
||||
import com.sun.tools.javac.tree.TreeScanner;
|
||||
|
||||
import lombok.delombok.Delombok;
|
||||
import lombok.javac.CapturingDiagnosticListener;
|
||||
import lombok.javac.Javac;
|
||||
import lombok.javac.CapturingDiagnosticListener.CompilerMessage;
|
||||
import lombok.javac.Javac;
|
||||
|
||||
public class RunTestsViaDelombok extends AbstractRunTests {
|
||||
private Delombok delombok = new Delombok();
|
||||
@@ -78,6 +81,7 @@ public class RunTestsViaDelombok extends AbstractRunTests {
|
||||
delombok.setDiagnosticsListener(new CapturingDiagnosticListener(file, messages));
|
||||
|
||||
if (checkPositions) delombok.addAdditionalAnnotationProcessor(new ValidatePositionProcessor(version));
|
||||
delombok.addAdditionalAnnotationProcessor(new ValidateTypesProcessor());
|
||||
|
||||
delombok.addFile(file.getAbsoluteFile().getParentFile(), file.getName());
|
||||
delombok.setSourcepath(file.getAbsoluteFile().getParent());
|
||||
@@ -178,6 +182,57 @@ public class RunTestsViaDelombok extends AbstractRunTests {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ValidateTypesProcessor extends TreeProcessor {
|
||||
@Override void processCompilationUnit(final JCCompilationUnit unit) {
|
||||
final Stack<JCTree> parents = new Stack<JCTree>();
|
||||
parents.add(unit);
|
||||
|
||||
unit.accept(new TreeScanner() {
|
||||
private JCTree parent;
|
||||
@Override public void scan(JCTree tree) {
|
||||
parent = parents.peek();
|
||||
|
||||
parents.push(tree);
|
||||
super.scan(tree);
|
||||
parents.pop();
|
||||
}
|
||||
|
||||
@Override public void visitClassDef(JCClassDecl tree) {
|
||||
// Skip anonymous or local classes, they have no symbol
|
||||
if (!(parent instanceof JCClassDecl || parent instanceof JCCompilationUnit)) return;
|
||||
|
||||
validateSymbol(tree, tree.sym);
|
||||
super.visitClassDef(tree);
|
||||
};
|
||||
|
||||
@Override public void visitMethodDef(JCMethodDecl tree) {
|
||||
validateSymbol(tree, tree.sym);
|
||||
super.visitMethodDef(tree);
|
||||
}
|
||||
|
||||
@Override public void visitVarDef(JCVariableDecl tree) {
|
||||
// Skip non-field variables
|
||||
if (!(parent instanceof JCClassDecl)) return;
|
||||
|
||||
validateSymbol(tree, tree.sym);
|
||||
super.visitVarDef(tree);
|
||||
}
|
||||
|
||||
private void validateSymbol(JCTree tree, Symbol sym) {
|
||||
if (sym == null) {
|
||||
fail("Missing symbol for " + tree);
|
||||
}
|
||||
// Skip top level classes
|
||||
if (sym.owner.getKind() == ElementKind.PACKAGE) return;
|
||||
|
||||
if (!sym.owner.getEnclosedElements().contains(sym)) {
|
||||
fail(tree + " not added to parent");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class TreeProcessor extends AbstractProcessor {
|
||||
private Trees trees;
|
||||
@Override public synchronized void init(ProcessingEnvironment processingEnv) {
|
||||
|
||||
Reference in New Issue
Block a user