Skip to content

Commit

Permalink
Fix for #920: create binding key not type signature for wildcard bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Jul 3, 2019
1 parent d2d8145 commit 07f03f4
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -198,29 +198,33 @@ public static ClassNode[] getTypeParameterBounds(ClassNode typeParam) {
* @see org.eclipse.jdt.core.Signature
*/
public static String getTypeSignature(ClassNode node, boolean qualified, boolean resolved) {
StringBuilder builder = new StringBuilder(getTypeSignatureWithoutGenerics(node, qualified, resolved));
String signature = getTypeSignatureWithoutGenerics(node, qualified, resolved);

if (getBaseType(node).isUsingGenerics() && !getBaseType(node).isGenericsPlaceHolder()) {
GenericsType[] generics = getGenericsTypes(node);
if (generics.length > 0) {
StringBuilder builder = new StringBuilder(signature);

builder.setCharAt(builder.length() - 1, Signature.C_GENERIC_START);
for (GenericsType gen : generics) {
if (gen.isPlaceholder() || !gen.isWildcard()) {
for (GenericsType gt : generics) {
if (gt.isPlaceholder() || !gt.isWildcard()) {
// TODO: Can lower bound or upper bounds exist in this case?
builder.append(getTypeSignature(gen.getType(), qualified, resolved));
} else if (gen.getLowerBound() != null) {
builder.append(Signature.C_SUPER).append(getTypeSignature(gen.getLowerBound(), qualified, resolved));
} else if (gen.getUpperBounds() != null && gen.getUpperBounds().length > 0) { // TODO: handle more than one
builder.append(Signature.C_EXTENDS).append(getTypeSignature(gen.getUpperBounds()[0], qualified, resolved));
builder.append(getTypeSignature(gt.getType(), qualified, resolved));
} else if (gt.getLowerBound() != null) {
builder.append(Signature.C_SUPER).append(getTypeSignature(gt.getLowerBound(), qualified, resolved));
} else if (gt.getUpperBounds() != null && gt.getUpperBounds().length == 1) {
builder.append(Signature.C_EXTENDS).append(getTypeSignature(gt.getUpperBounds()[0], qualified, resolved));
} else {
builder.append(Signature.C_STAR);
}
}
builder.append(Signature.C_GENERIC_END).append(Signature.C_NAME_END);

return builder.toString();
}
}

return builder.toString();
return signature;
}

public static String getTypeSignatureWithoutGenerics(ClassNode node, boolean qualified, boolean resolved) {
Expand All @@ -244,7 +248,8 @@ public static String getTypeSignatureWithoutGenerics(ClassNode node, boolean qua

final int pos = builder.length();
builder.append(Signature.createTypeSignature(name, resolved));
if (resolved && node.isGenericsPlaceHolder()) builder.setCharAt(pos, 'T');
if (resolved && node.isGenericsPlaceHolder())
builder.setCharAt(pos, Signature.C_TYPE_VARIABLE);

return builder.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
Expand Down Expand Up @@ -62,8 +62,6 @@
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.groovy.core.util.ArrayUtils;
import org.eclipse.jdt.groovy.core.util.GroovyUtils;
import org.eclipse.jdt.groovy.search.AccessorSupport;
import org.eclipse.jdt.groovy.search.GenericsMapper;
Expand Down Expand Up @@ -620,14 +618,11 @@ private String createUniqueKey(AnnotatedNode node, ClassNode resolvedType, Class

private void appendUniqueKeyForField(StringBuilder sb, FieldNode node, ClassNode resolvedType, ClassNode resolvedDeclaringType) {
appendUniqueKeyForClass(sb, node.getDeclaringClass(), resolvedDeclaringType);
sb.append('.').append(node.getName()).append(')');
sb.append(Signature.C_DOT).append(node.getName()).append(')');
appendUniqueKeyForResolvedClass(sb, resolvedType);
}

private void appendUniqueKeyForMethod(StringBuilder sb, MethodNode node, ClassNode resolvedType, ClassNode resolvedDeclaringType) {
// TODO: This method does not handle capture types like Java does; example for Plain.class.newInstance():
// LPlain;&Ljava/lang/Class<!Ljava/lang/Class;{0}+LPlain;152;>;.newInstance()!+LPlain;|Ljava/lang/InstantiationException;|Ljava/lang/IllegalAccessException;

// declaring type
appendUniqueKeyForClass(sb, node.getDeclaringClass(), resolvedDeclaringType);

Expand All @@ -645,8 +640,21 @@ private void appendUniqueKeyForMethod(StringBuilder sb, MethodNode node, ClassNo
GenericsType[] generics = GroovyUtils.getGenericsTypes(node);
if (generics.length > 0) {
sb.append(Signature.C_GENERIC_START);
// see org.eclipse.jdt.core.Signature#createTypeParameterSignature(char[],char[][])
for (GenericsType gt : generics) {
appendUniqueKeyForGenericsType(sb, gt);
ClassNode lower = gt.getLowerBound();
ClassNode[] upper = gt.getUpperBounds();

sb.append(gt.getName());
sb.append(Signature.C_COLON);
if (lower != null) {
appendUniqueKeyForResolvedClass(sb, lower);
} else if (upper != null && upper.length > 0) {
for (int i = 0; i < upper.length; i += 1) {
if (i > 0) sb.append(Signature.C_COLON);
appendUniqueKeyForResolvedClass(sb, upper[i]);
}
}
}
sb.append(Signature.C_GENERIC_END);
}
Expand All @@ -662,7 +670,7 @@ private void appendUniqueKeyForMethod(StringBuilder sb, MethodNode node, ClassNo
sb.append(Signature.C_PARAM_END);

// return type
appendUniqueKeyForClass(sb, node.getReturnType(), resolvedDeclaringType);
appendUniqueKeyForClass(sb, node.getOriginal().getReturnType(), resolvedDeclaringType);

// generic type resolution
if (generics.length > 0) {
Expand All @@ -689,8 +697,8 @@ private void appendUniqueKeyForMethod(StringBuilder sb, MethodNode node, ClassNo

private void appendUniqueKeyForGeneratedAccessor(StringBuilder sb, MethodNode node, ClassNode resolvedType, ClassNode resolvedDeclaringType, IField actualField) {
appendUniqueKeyForClass(sb, node.getDeclaringClass(), resolvedDeclaringType);
sb.append('.').append(actualField.getElementName()).append(')');
ClassNode typeOfField = node.getName().startsWith("set") && node.getParameters() != null && node.getParameters().length > 0 ? node.getParameters()[0].getType() : resolvedType;
sb.append(Signature.C_DOT).append(actualField.getElementName()).append(')');
ClassNode typeOfField = node.getName().startsWith("set") && node.getParameters() != null && node.getParameters().length > 0 ? node.getParameters()[0].getType() : resolvedType;
appendUniqueKeyForResolvedClass(sb, typeOfField);
}

Expand All @@ -707,24 +715,39 @@ private void appendUniqueKeyForClass(StringBuilder sb, ClassNode unresolvedType,
}

private void appendUniqueKeyForResolvedClass(StringBuilder sb, ClassNode resolvedType) {
String signature = GroovyUtils.getTypeSignature(resolvedType, true, true);
String signature = GroovyUtils.getTypeSignatureWithoutGenerics(resolvedType, true, true).replace('.', '/');

sb.append(signature.replace('.', '/'));
}
sb.append(signature);

ClassNode baseType = GroovyUtils.getBaseType(resolvedType);
if (baseType.isUsingGenerics() && !baseType.isGenericsPlaceHolder()) {
GenericsType[] generics = baseType.getGenericsTypes();
if (generics != null && generics.length > 0) {
sb.setCharAt(sb.length() - 1, Signature.C_GENERIC_START);

for (int i = 0, n = generics.length; i < n; i += 1) {
GenericsType gt = generics[i];
if (gt.isPlaceholder() || !gt.isWildcard()) {
appendUniqueKeyForResolvedClass(sb, gt.getType());
} else {
// see org.eclipse.jdt.core.BindingKey#createWildcardTypeBindingKey(String,char,String,int)
sb.append(signature).append('{').append(i).append('}');

if (gt.getLowerBound() != null) {
sb.append(Signature.C_SUPER);
appendUniqueKeyForResolvedClass(sb, gt.getLowerBound());
} else if (gt.getUpperBounds() != null && gt.getUpperBounds().length == 1) {
sb.append(Signature.C_EXTENDS);
appendUniqueKeyForResolvedClass(sb, gt.getUpperBounds()[0]);
} else {
sb.append(Signature.C_STAR);
}
}
}

private void appendUniqueKeyForGenericsType(StringBuilder sb, GenericsType gt) {
String[] bounds = CharOperation.NO_STRINGS;
if (gt.getLowerBound() != null) {
ClassNode lb = gt.getLowerBound();
bounds = (String[]) ArrayUtils.add(bounds, GroovyUtils.getTypeSignature(lb, true, true));
} else if (gt.getUpperBounds() != null) {
for (ClassNode ub : gt.getUpperBounds()) {
bounds = (String[]) ArrayUtils.add(bounds, GroovyUtils.getTypeSignature(ub, true, true));
sb.append(Signature.C_GENERIC_END).append(Signature.C_NAME_END);
}
}
String signature = Signature.createTypeParameterSignature(gt.getName(), bounds);

sb.append(signature.replace('.', '/'));
}

private IJavaElement findElement(IType type, String text, Parameter[] parameters) throws JavaModelException {
Expand Down

0 comments on commit 07f03f4

Please sign in to comment.