use of lombok.experimental.Delegate in project lombok by rzwitserloot.
the class HandleDelegate method handle.
@Override
public void handle(AnnotationValues<Delegate> annotation, JCAnnotation ast, JavacNode annotationNode) {
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.DELEGATE_FLAG_USAGE, "@Delegate");
@SuppressWarnings("deprecation") Class<? extends Annotation> oldDelegate = lombok.Delegate.class;
deleteAnnotationIfNeccessary(annotationNode, Delegate.class, oldDelegate);
Type delegateType;
Name delegateName = annotationNode.toName(annotationNode.up().getName());
DelegateReceiver delegateReceiver;
JavacResolution reso = new JavacResolution(annotationNode.getContext());
JCTree member = annotationNode.up().get();
if (annotationNode.up().getKind() == Kind.FIELD) {
if ((((JCVariableDecl) member).mods.flags & Flags.STATIC) != 0) {
annotationNode.addError(LEGALITY_OF_DELEGATE);
return;
}
delegateReceiver = DelegateReceiver.FIELD;
delegateType = member.type;
if (delegateType == null)
reso.resolveClassMember(annotationNode.up());
delegateType = member.type;
} else if (annotationNode.up().getKind() == Kind.METHOD) {
if (!(member instanceof JCMethodDecl)) {
annotationNode.addError(LEGALITY_OF_DELEGATE);
return;
}
JCMethodDecl methodDecl = (JCMethodDecl) member;
if (!methodDecl.params.isEmpty() || (methodDecl.mods.flags & Flags.STATIC) != 0) {
annotationNode.addError(LEGALITY_OF_DELEGATE);
return;
}
delegateReceiver = DelegateReceiver.METHOD;
delegateType = methodDecl.restype.type;
if (delegateType == null)
reso.resolveClassMember(annotationNode.up());
delegateType = methodDecl.restype.type;
} else {
// As the annotation is legal on fields and methods only, javac itself will take care of printing an error message for this.
return;
}
List<Object> delegateTypes = annotation.getActualExpressions("types");
List<Object> excludeTypes = annotation.getActualExpressions("excludes");
List<Type> toDelegate = new ArrayList<Type>();
List<Type> toExclude = new ArrayList<Type>();
if (delegateTypes.isEmpty()) {
if (delegateType != null)
toDelegate.add(delegateType);
} else {
for (Object dt : delegateTypes) {
if (dt instanceof JCFieldAccess && ((JCFieldAccess) dt).name.toString().equals("class")) {
Type type = ((JCFieldAccess) dt).selected.type;
if (type == null)
reso.resolveClassMember(annotationNode);
type = ((JCFieldAccess) dt).selected.type;
if (type != null)
toDelegate.add(type);
}
}
}
for (Object et : excludeTypes) {
if (et instanceof JCFieldAccess && ((JCFieldAccess) et).name.toString().equals("class")) {
Type type = ((JCFieldAccess) et).selected.type;
if (type == null)
reso.resolveClassMember(annotationNode);
type = ((JCFieldAccess) et).selected.type;
if (type != null)
toExclude.add(type);
}
}
List<MethodSig> signaturesToDelegate = new ArrayList<MethodSig>();
List<MethodSig> signaturesToExclude = new ArrayList<MethodSig>();
Set<String> banList = new HashSet<String>();
banList.addAll(METHODS_IN_OBJECT);
try {
for (Type t : toExclude) {
if (t instanceof ClassType) {
ClassType ct = (ClassType) t;
addMethodBindings(signaturesToExclude, ct, annotationNode.getTypesUtil(), banList);
} else {
annotationNode.addError("@Delegate can only use concrete class types, not wildcards, arrays, type variables, or primitives.");
return;
}
}
for (MethodSig sig : signaturesToExclude) {
banList.add(printSig(sig.type, sig.name, annotationNode.getTypesUtil()));
}
for (Type t : toDelegate) {
if (t instanceof ClassType) {
ClassType ct = (ClassType) t;
addMethodBindings(signaturesToDelegate, ct, annotationNode.getTypesUtil(), banList);
} else {
annotationNode.addError("@Delegate can only use concrete class types, not wildcards, arrays, type variables, or primitives.");
return;
}
}
for (MethodSig sig : signaturesToDelegate) generateAndAdd(sig, annotationNode, delegateName, delegateReceiver);
} catch (DelegateRecursion e) {
annotationNode.addError(String.format(RECURSION_NOT_ALLOWED, e.member, e.type));
}
}
Aggregations