diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2014-05-12 15:08:55 +0200 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2014-05-21 01:44:45 +0200 |
commit | 8cfa421ce5b07ac4932e13035e71d8a52d45f085 (patch) | |
tree | 7473279fcaf5bbbd9fd246b62903f4351106ff4a /src/core/lombok/javac/handlers/HandleDelegate.java | |
parent | 4996428ea12be7e381d76614e34a15ad1cc6d275 (diff) | |
download | lombok-8cfa421ce5b07ac4932e13035e71d8a52d45f085.tar.gz lombok-8cfa421ce5b07ac4932e13035e71d8a52d45f085.tar.bz2 lombok-8cfa421ce5b07ac4932e13035e71d8a52d45f085.zip |
Added an error if @Delegate is used recursively.
Diffstat (limited to 'src/core/lombok/javac/handlers/HandleDelegate.java')
-rw-r--r-- | src/core/lombok/javac/handlers/HandleDelegate.java | 73 |
1 files changed, 50 insertions, 23 deletions
diff --git a/src/core/lombok/javac/handlers/HandleDelegate.java b/src/core/lombok/javac/handlers/HandleDelegate.java index 9cd8844e..6065242e 100644 --- a/src/core/lombok/javac/handlers/HandleDelegate.java +++ b/src/core/lombok/javac/handlers/HandleDelegate.java @@ -57,6 +57,7 @@ import lombok.javac.JavacResolution.TypeNotConvertibleException; import org.mangosdk.spi.ProviderFor; +import com.sun.tools.javac.code.Attribute.Compound; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.TypeSymbol; @@ -98,6 +99,8 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> { "finalize()")); private static final String LEGALITY_OF_DELEGATE = "@Delegate is legal only on instance fields or no-argument instance methods."; + private static final String RECURSION_NOT_ALLOWED = "@Delegate does not support recursion (delegating to a type that itself has @Delegate members). Member \"%s\" is @Delegate in type \"%s\""; + @Override public void handle(AnnotationValues<Delegate> annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.DELEGATE_FLAG_USAGE, "@Delegate"); @@ -177,31 +180,36 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> { } } */ - 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; + 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)); } - - for (MethodSig sig : signaturesToDelegate) generateAndAdd(sig, annotationNode, delegateName, delegateReceiver); } public void generateAndAdd(MethodSig sig, JavacNode annotation, Name delegateName, DelegateReceiver delegateReceiver) { @@ -338,11 +346,30 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> { return collection == null ? com.sun.tools.javac.util.List.<T>nil() : collection.toList(); } - public void addMethodBindings(List<MethodSig> signatures, ClassType ct, JavacTypes types, Set<String> banList) { + private static class DelegateRecursion extends Throwable { + final String type, member; + + public DelegateRecursion(String type, String member) { + this.type = type; + this.member = member; + } + } + + public void addMethodBindings(List<MethodSig> signatures, ClassType ct, JavacTypes types, Set<String> banList) throws DelegateRecursion { TypeSymbol tsym = ct.asElement(); if (tsym == null) return; for (Symbol member : tsym.getEnclosedElements()) { + for (Compound am : member.getAnnotationMirrors()) { + String name = null; + try { + name = am.type.tsym.flatName().toString(); + } catch (Exception ignore) {} + + if ("lombok.Delegate".equals(name) || "lombok.experimental.Delegate".equals(name)) { + throw new DelegateRecursion(ct.tsym.name.toString(), member.name.toString()); + } + } if (member.getKind() != ElementKind.METHOD) continue; if (member.isStatic()) continue; if (member.isConstructor()) continue; |