mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-13 10:15:53 +00:00
[fixes #2006] Delegate now excludes already implemented methods
This commit is contained in:
1 parent
7d08af7d85
commit
a2a194f32d
5 files changed
+194
-9
No files matched your search
@@ -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) {
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
Reference in new issue
Block a user