aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/lombok/javac/handlers/HandleDelegate.java13
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java73
-rw-r--r--test/transform/resource/after-delombok/DelegateAlreadyImplemented.java43
-rw-r--r--test/transform/resource/after-ecj/DelegateAlreadyImplemented.java29
-rw-r--r--test/transform/resource/before/DelegateAlreadyImplemented.java45
5 files changed, 194 insertions, 9 deletions
diff --git a/src/core/lombok/javac/handlers/HandleDelegate.java b/src/core/lombok/javac/handlers/HandleDelegate.java
index c19540fa..d6e76ab1 100644
--- a/src/core/lombok/javac/handlers/HandleDelegate.java
+++ b/src/core/lombok/javac/handlers/HandleDelegate.java
@@ -48,6 +48,7 @@ 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.MethodSymbol;
import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.ClassType;
@@ -175,14 +176,14 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> {
List<MethodSig> signaturesToExclude = new ArrayList<MethodSig>();
Set<String> banList = new HashSet<String>();
banList.addAll(METHODS_IN_OBJECT);
- /* To exclude all methods in the class itself, try this:
- for (Symbol member : ((JCClassDecl)typeNode.get()).sym.getEnclosedElements()) {
- if (member instanceof MethodSymbol) {
- MethodSymbol method = (MethodSymbol) member;
- banList.add(printSig((ExecutableType) method.asType(), method.name, annotationNode.getTypesUtil()));
+
+ // Add already implemented methods to ban list
+ JavacNode typeNode = upToTypeNode(annotationNode);
+ for (Symbol m : ((JCClassDecl)typeNode.get()).sym.getEnclosedElements()) {
+ if (m instanceof MethodSymbol) {
+ banList.add(printSig((ExecutableType) m.asType(), m.name, annotationNode.getTypesUtil()));
}
}
- */
try {
for (Type t : toExclude) {
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
index 02760e35..ebd60ce9 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
@@ -29,11 +29,14 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import lombok.core.AST.Kind;
+import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAST;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.TransformEclipseAST;
@@ -67,6 +70,7 @@ import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
@@ -214,7 +218,7 @@ public class PatchDelegate {
addAllMethodBindings(methodsToExclude, cla.type.resolveType(decl.initializerScope), new HashSet<String>(), field.name, ann);
}
- Set<String> banList = new HashSet<String>();
+ Set<String> banList = findAlreadyImplementedMethods(decl);
for (BindingTuple excluded : methodsToExclude) banList.add(printSig(excluded.parameterized));
if (rawTypes.isEmpty()) {
@@ -283,8 +287,8 @@ public class PatchDelegate {
for (ClassLiteralAccess cla : excludedRawTypes) {
addAllMethodBindings(methodsToExclude, cla.type.resolveType(decl.initializerScope), new HashSet<String>(), method.selector, ann);
}
-
- Set<String> banList = new HashSet<String>();
+
+ Set<String> banList = findAlreadyImplementedMethods(decl);
for (BindingTuple excluded : methodsToExclude) banList.add(printSig(excluded.parameterized));
if (rawTypes.isEmpty()) {
@@ -764,6 +768,21 @@ public class PatchDelegate {
}
}
+ private static Set<String> findAlreadyImplementedMethods(TypeDeclaration decl) {
+ Set<String> sigs = new HashSet<String>();
+ for (AbstractMethodDeclaration md : decl.methods) {
+ if (md.isStatic()) continue;
+ if ((md.modifiers & ClassFileConstants.AccBridge) != 0) continue;
+ if (md.isConstructor()) continue;
+ if ((md.modifiers & ExtraCompilerModifiers.AccDefaultAbstract) != 0) continue;
+ if ((md.modifiers & ClassFileConstants.AccPublic) == 0) continue;
+ if ((md.modifiers & ClassFileConstants.AccSynthetic) != 0) continue;
+
+ sigs.add(printSig(md, decl.scope));
+ }
+ return sigs;
+ }
+
private static final char[] STRING_LOMBOK = new char[] {'l', 'o', 'm', 'b', 'o', 'k'};
private static final char[] STRING_EXPERIMENTAL = new char[] {'e', 'x', 'p', 'e', 'r', 'i', 'm', 'e', 'n', 't', 'a', 'l'};
private static final char[] STRING_DELEGATE = new char[] {'D', 'e', 'l', 'e', 'g', 'a', 't', 'e'};
@@ -839,6 +858,54 @@ public class PatchDelegate {
return signature.toString();
}
+ private static String printSig(AbstractMethodDeclaration md, ClassScope scope) {
+ StringBuilder signature = new StringBuilder();
+
+ signature.append(md.selector);
+ signature.append("(");
+ boolean first = true;
+ if (md.arguments != null) {
+ TypeParameter[] typeParameters = md.typeParameters();
+ Map<String, TypeParameter> typeParametersMap = new HashMap<String, TypeParameter>();
+ if (typeParameters != null) {
+ for (TypeParameter typeParameter : typeParameters) {
+ typeParametersMap.put(new String(typeParameter.name), typeParameter);
+ }
+ }
+
+ for (Argument argument : md.arguments) {
+ TypeBinding typeBinding = makeTypeBinding(argument.type, typeParametersMap, scope);
+
+ if (!first) signature.append(", ");
+ first = false;
+ signature.append(typeBindingToSignature(typeBinding));
+ }
+ }
+ signature.append(")");
+
+ return signature.toString();
+ }
+
+ private static TypeBinding makeTypeBinding(TypeReference typeReference, Map<String, TypeParameter> typeParametersMap, ClassScope scope) {
+ char[][] typeName = typeReference.getTypeName();
+ String typeNameString = Eclipse.toQualifiedName(typeName);
+
+ TypeParameter typeParameter = typeParametersMap.get(typeNameString);
+ if (typeParameter != null) {
+ if (typeParameter.type != null) {
+ typeName = typeParameter.type.getTypeName();
+ } else {
+ typeName = TypeConstants.JAVA_LANG_OBJECT;
+ }
+ }
+
+ TypeBinding typeBinding = scope.getType(typeName, typeName.length);
+ if (typeReference.dimensions() > 0) {
+ typeBinding = scope.createArrayType(typeBinding, typeReference.dimensions());
+ }
+ return typeBinding;
+ }
+
private static String typeBindingToSignature(TypeBinding binding) {
binding = binding.erasure();
if (binding != null && binding.isBaseType()) {
diff --git a/test/transform/resource/after-delombok/DelegateAlreadyImplemented.java b/test/transform/resource/after-delombok/DelegateAlreadyImplemented.java
new file mode 100644
index 00000000..c876d8ce
--- /dev/null
+++ b/test/transform/resource/after-delombok/DelegateAlreadyImplemented.java
@@ -0,0 +1,43 @@
+public class DelegateAlreadyImplemented<T> {
+ private A<Integer, T> a;
+
+ public void a() {
+ }
+
+ public void b(java.util.List<String> l) {
+ }
+
+ public void c(java.util.List<Integer> l, String[] a, Integer... varargs) {
+ }
+
+ public void d(String[][][][] d) {
+ }
+
+ public <Y> void e(Y x) {
+ }
+
+ @SuppressWarnings("unchecked")
+ public void f(T s, java.util.List<T> l, T[] a, T... varargs) {
+ }
+
+ public void g(Number g) {
+ }
+}
+
+interface A<T, T2> {
+ void a();
+
+ void b(java.util.List<T> l);
+
+ @SuppressWarnings("unchecked")
+ void c(java.util.List<T> l, String[] a, T... varargs);
+
+ void d(String[][][][] d);
+
+ <X> X e(X x);
+
+ @SuppressWarnings("unchecked")
+ void f(T2 s, java.util.List<T2> l, T2[] a, T2... varargs);
+
+ <G extends Number> void g(G g);
+} \ No newline at end of file
diff --git a/test/transform/resource/after-ecj/DelegateAlreadyImplemented.java b/test/transform/resource/after-ecj/DelegateAlreadyImplemented.java
new file mode 100644
index 00000000..1e12f405
--- /dev/null
+++ b/test/transform/resource/after-ecj/DelegateAlreadyImplemented.java
@@ -0,0 +1,29 @@
+public class DelegateAlreadyImplemented<T> {
+ private @lombok.experimental.Delegate A<Integer, T> a;
+ public DelegateAlreadyImplemented() {
+ super();
+ }
+ public void a() {
+ }
+ public void b(java.util.List<String> l) {
+ }
+ public void c(java.util.List<Integer> l, String[] a, Integer... varargs) {
+ }
+ public void d(String[][][][] d) {
+ }
+ public <Y>void e(Y x) {
+ }
+ public @SuppressWarnings("unchecked") void f(T s, java.util.List<T> l, T[] a, T... varargs) {
+ }
+ public void g(Number g) {
+ }
+}
+interface A<T, T2> {
+ public void a();
+ public void b(java.util.List<T> l);
+ public @SuppressWarnings("unchecked") void c(java.util.List<T> l, String[] a, T... varargs);
+ public void d(String[][][][] d);
+ public <X>X e(X x);
+ public @SuppressWarnings("unchecked") void f(T2 s, java.util.List<T2> l, T2[] a, T2... varargs);
+ public <G extends Number>void g(G g);
+} \ No newline at end of file
diff --git a/test/transform/resource/before/DelegateAlreadyImplemented.java b/test/transform/resource/before/DelegateAlreadyImplemented.java
new file mode 100644
index 00000000..c43c1949
--- /dev/null
+++ b/test/transform/resource/before/DelegateAlreadyImplemented.java
@@ -0,0 +1,45 @@
+public class DelegateAlreadyImplemented<T> {
+
+ @lombok.experimental.Delegate
+ private A<Integer, T> a;
+
+ public void a() {
+ }
+
+ public void b(java.util.List<String> l) {
+ }
+
+ public void c(java.util.List<Integer> l, String[] a, Integer... varargs) {
+ }
+
+ public void d(String[][][][] d) {
+ }
+
+ public <Y> void e(Y x) {
+ }
+
+ @SuppressWarnings("unchecked")
+ public void f(T s, java.util.List<T> l, T[] a, T... varargs) {
+ }
+
+ public void g(Number g) {
+ }
+}
+
+interface A<T, T2> {
+ public void a();
+
+ public void b(java.util.List<T> l);
+
+ @SuppressWarnings("unchecked")
+ public void c(java.util.List<T> l, String[] a, T... varargs);
+
+ public void d(String[][][][] d);
+
+ public <X> X e(X x);
+
+ @SuppressWarnings("unchecked")
+ public void f(T2 s, java.util.List<T2> l, T2[] a, T2... varargs);
+
+ public <G extends Number> void g(G g);
+} \ No newline at end of file