Skip to content

Commit

Permalink
Problems determing when a type is or is not generic, and regressions
Browse files Browse the repository at this point in the history
Signed-off-by: Rob Stryker <stryker@redhat.com>
  • Loading branch information
Rob Stryker committed Aug 12, 2024
1 parent aeb3126 commit 901a147
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Attribute.Compound;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
Expand Down Expand Up @@ -98,57 +97,99 @@ public class JavacBindingResolver extends BindingResolver {
private JavacConverter converter;
boolean isRecoveringBindings = false;

public static class BindingKeyException extends Exception {
private static final long serialVersionUID = -4468681148041117634L;
public BindingKeyException(Throwable t) {
super(t);
}
public BindingKeyException(String message, Throwable cause) {
super(message, cause);
}
}

public class Bindings {
private Map<String, JavacAnnotationBinding> annotationBindings = new HashMap<>();
public JavacAnnotationBinding getAnnotationBinding(Compound ann, IBinding recipient) {
JavacAnnotationBinding newInstance = new JavacAnnotationBinding(ann, JavacBindingResolver.this, recipient) { };
annotationBindings.putIfAbsent(newInstance.getKey(), newInstance);
return annotationBindings.get(newInstance.getKey());
String k = newInstance.getKey();
if( k != null ) {
annotationBindings.putIfAbsent(k, newInstance);
return annotationBindings.get(k);
}
return null;
}
//
private Map<String, JavacMemberValuePairBinding> memberValuePairBindings = new HashMap<>();
public JavacMemberValuePairBinding getMemberValuePairBinding(MethodSymbol key, Attribute value) {
JavacMemberValuePairBinding newInstance = new JavacMemberValuePairBinding(key, value, JavacBindingResolver.this) { };
memberValuePairBindings.putIfAbsent(newInstance.getKey(), newInstance);
return memberValuePairBindings.get(newInstance.getKey());
String k = newInstance.getKey();
if( k != null ) {
memberValuePairBindings.putIfAbsent(k, newInstance);
return memberValuePairBindings.get(k);
}
return null;
}
//
private Map<String, JavacMethodBinding> methodBindings = new HashMap<>();
public JavacMethodBinding getMethodBinding(MethodType methodType, MethodSymbol methodSymbol) {
JavacMethodBinding newInstance = new JavacMethodBinding(methodType, methodSymbol, JavacBindingResolver.this) { };
methodBindings.putIfAbsent(newInstance.getKey(), newInstance);
return methodBindings.get(newInstance.getKey());
String k = newInstance.getKey();
if( k != null ) {
methodBindings.putIfAbsent(k, newInstance);
return methodBindings.get(k);
}
return null;
}
public JavacMethodBinding getErrorMethodBinding(MethodType methodType, Symbol originatingSymbol) {
JavacMethodBinding newInstance = new JavacErrorMethodBinding(originatingSymbol, methodType, JavacBindingResolver.this) { };
methodBindings.putIfAbsent(newInstance.getKey(), newInstance);
return methodBindings.get(newInstance.getKey());
String k = newInstance.getKey();
if( k != null ) {
methodBindings.putIfAbsent(k, newInstance);
return methodBindings.get(k);
}
return null;
}
//
private Map<String, JavacModuleBinding> moduleBindings = new HashMap<>();
public JavacModuleBinding getModuleBinding(ModuleType moduleType) {
JavacModuleBinding newInstance = new JavacModuleBinding(moduleType, JavacBindingResolver.this) { };
moduleBindings.putIfAbsent(newInstance.getKey(), newInstance);
return moduleBindings.get(newInstance.getKey());
String k = newInstance.getKey();
if( k != null ) {
moduleBindings.putIfAbsent(k, newInstance);
return moduleBindings.get(k);
}
return null;
}
public JavacModuleBinding getModuleBinding(ModuleSymbol moduleSymbol) {
JavacModuleBinding newInstance = new JavacModuleBinding(moduleSymbol, JavacBindingResolver.this) { };
moduleBindings.putIfAbsent(newInstance.getKey(), newInstance);
return moduleBindings.get(newInstance.getKey());
String k = newInstance.getKey();
if( k != null ) {
moduleBindings.putIfAbsent(k, newInstance);
return moduleBindings.get(k);
}
return null;
}
public JavacModuleBinding getModuleBinding(JCModuleDecl moduleDecl) {
JavacModuleBinding newInstance = new JavacModuleBinding(moduleDecl, JavacBindingResolver.this) { };
// Overwrite existing
moduleBindings.put(newInstance.getKey(), newInstance);
return moduleBindings.get(newInstance.getKey());
String k = newInstance.getKey();
if( k != null ) {
moduleBindings.put(k, newInstance);
return moduleBindings.get(k);
}
return null;
}

//
private Map<String, JavacPackageBinding> packageBindings = new HashMap<>();
public JavacPackageBinding getPackageBinding(PackageSymbol packageSymbol) {
JavacPackageBinding newInstance = new JavacPackageBinding(packageSymbol, JavacBindingResolver.this) { };
packageBindings.putIfAbsent(newInstance.getKey(), newInstance);
return packageBindings.get(newInstance.getKey());
String k = newInstance.getKey();
if( k != null ) {
packageBindings.putIfAbsent(k, newInstance);
return packageBindings.get(k);
}
return null;
}
//
private Map<String, JavacTypeBinding> typeBinding = new HashMap<>();
Expand Down Expand Up @@ -178,29 +219,44 @@ public JavacTypeBinding getTypeBinding(com.sun.tools.javac.code.Type type, boole
}
JavacTypeBinding newInstance = new JavacTypeBinding(type, type.tsym, isDeclaration, JavacBindingResolver.this) { };
String k = newInstance.getKey();
typeBinding.putIfAbsent(k, newInstance);
return typeBinding.get(k);
if( k != null ) {
typeBinding.putIfAbsent(k, newInstance);
return typeBinding.get(k);
}
return null;
}
//
private Map<String, JavacTypeVariableBinding> typeVariableBindings = new HashMap<>();
public JavacTypeVariableBinding getTypeVariableBinding(TypeVar typeVar) {
JavacTypeVariableBinding newInstance = new JavacTypeVariableBinding(typeVar, (TypeVariableSymbol)typeVar.tsym, JavacBindingResolver.this) { };
typeVariableBindings.putIfAbsent(newInstance.getKey(), newInstance);
return typeVariableBindings.get(newInstance.getKey());
String k = newInstance.getKey();
if( k != null ) {
typeVariableBindings.putIfAbsent(k, newInstance);
return typeVariableBindings.get(k);
}
return null;
}
//
private Map<String, JavacVariableBinding> variableBindings = new HashMap<>();
public JavacVariableBinding getVariableBinding(VarSymbol varSymbol) {
JavacVariableBinding newInstance = new JavacVariableBinding(varSymbol, JavacBindingResolver.this) { };
variableBindings.putIfAbsent(newInstance.getKey(), newInstance);
return variableBindings.get(newInstance.getKey());
String k = newInstance.getKey();
if( k != null ) {
variableBindings.putIfAbsent(k, newInstance);
return variableBindings.get(k);
}
return null;
}
//
private Map<String, JavacLambdaBinding> lambdaBindings = new HashMap<>();
public JavacLambdaBinding getLambdaBinding(JavacMethodBinding javacMethodBinding) {
JavacLambdaBinding newInstance = new JavacLambdaBinding(javacMethodBinding);
lambdaBindings.putIfAbsent(newInstance.getKey(), newInstance);
return lambdaBindings.get(newInstance.getKey());
String k = newInstance.getKey();
if( k != null ) {
lambdaBindings.putIfAbsent(k, newInstance);
return lambdaBindings.get(k);
}
return null;
}

public IBinding getBinding(final Symbol owner, final com.sun.tools.javac.code.Type type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public boolean isEqualTo(IBinding binding) {
public IMemberValuePairBinding[] getAllMemberValuePairs() {
return this.annotation.getElementValues().entrySet().stream()
.map(entry -> this.resolver.bindings.getMemberValuePairBinding(entry.getKey(), entry.getValue()))
.filter(Objects::nonNull)
.toArray(IMemberValuePairBinding[]::new);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.JavacBindingResolver;
import org.eclipse.jdt.core.dom.JavacBindingResolver.BindingKeyException;

import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
Expand All @@ -35,6 +36,13 @@ public JavacErrorMethodBinding(Symbol originatingSymbol, MethodType methodType,

@Override
public String getKey() {
try {
return getKeyImpl();
} catch(BindingKeyException bke) {
return null;
}
}
private String getKeyImpl() throws BindingKeyException {
StringBuilder builder = new StringBuilder();
if (this.originatingSymbol instanceof TypeSymbol typeSymbol) {
JavacTypeBinding.getKey(builder, resolver.getTypes().erasure(typeSymbol.type), false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.JavacBindingResolver;
import org.eclipse.jdt.core.dom.JavacBindingResolver.BindingKeyException;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
Expand Down Expand Up @@ -254,20 +255,24 @@ private String resolveTypeName(com.sun.tools.javac.code.Type type, boolean binar

@Override
public String getKey() {
StringBuilder builder = new StringBuilder();
getKey(builder, this.methodSymbol, this.methodType, this.resolver);
return builder.toString();
try {
StringBuilder builder = new StringBuilder();
getKey(builder, this.methodSymbol, this.methodType, this.resolver);
return builder.toString();
} catch(BindingKeyException bke) {
return null;
}
}

static void getKey(StringBuilder builder, MethodSymbol methodSymbol, MethodType methodType, JavacBindingResolver resolver) {
static void getKey(StringBuilder builder, MethodSymbol methodSymbol, MethodType methodType, JavacBindingResolver resolver) throws BindingKeyException {
Symbol ownerSymbol = methodSymbol.owner;
while (ownerSymbol != null && !(ownerSymbol instanceof TypeSymbol)) {
ownerSymbol = ownerSymbol.owner;
}
if (ownerSymbol instanceof TypeSymbol ownerTypeSymbol) {
JavacTypeBinding.getKey(builder, resolver.getTypes().erasure(ownerTypeSymbol.type), false);
} else {
throw new IllegalArgumentException("Method has no owning class");
throw new BindingKeyException(new IllegalArgumentException("Method has no owning class"));
}
builder.append('.');
if (!methodSymbol.isConstructor()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.JavacBindingResolver;
import org.eclipse.jdt.core.dom.JavacBindingResolver.BindingKeyException;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
Expand All @@ -58,6 +59,7 @@
import com.sun.tools.javac.code.Kinds.KindSelector;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symbol.RootPackageSymbol;
Expand Down Expand Up @@ -252,20 +254,24 @@ public String getKey(Type t) {
return getKey(t, this.typeSymbol.flatName());
}
public String getKey(Type t, Name n) {
StringBuilder builder = new StringBuilder();
getKey(builder, t, n, false, true);
return builder.toString();
try {
StringBuilder builder = new StringBuilder();
getKey(builder, t, n, false, true);
return builder.toString();
} catch(BindingKeyException bke) {
return null;
}
}

static void getKey(StringBuilder builder, Type typeToBuild, boolean isLeaf) {
static void getKey(StringBuilder builder, Type typeToBuild, boolean isLeaf) throws BindingKeyException {
getKey(builder, typeToBuild, typeToBuild.asElement().flatName(), isLeaf, false);
}

static void getKey(StringBuilder builder, Type typeToBuild, boolean isLeaf, boolean includeParameters) {
static void getKey(StringBuilder builder, Type typeToBuild, boolean isLeaf, boolean includeParameters) throws BindingKeyException {
getKey(builder, typeToBuild, typeToBuild.asElement().flatName(), isLeaf, includeParameters);
}

static void getKey(StringBuilder builder, Type typeToBuild, Name n, boolean isLeaf, boolean includeParameters) {
static void getKey(StringBuilder builder, Type typeToBuild, Name n, boolean isLeaf, boolean includeParameters) throws BindingKeyException {
if (typeToBuild instanceof Type.JCNoType) {
return;
}
Expand Down Expand Up @@ -299,7 +305,14 @@ static void getKey(StringBuilder builder, Type typeToBuild, Name n, boolean isLe
}
}
builder.append(n.toString().replace('.', '/'));
if (typeToBuild.isParameterized() && includeParameters) {
boolean b1 = typeToBuild.isParameterized();
boolean b2 = false;
try {
b2 = typeToBuild.tsym != null && typeToBuild.tsym.type != null && typeToBuild.tsym.type.isParameterized();
} catch( CompletionFailure cf1) {
throw new BindingKeyException(cf1);
}
if ((b1 || b2) && includeParameters) {
builder.append('<');
for (var typeArgument : typeToBuild.getTypeArguments()) {
getKey(builder, typeArgument, false, includeParameters);
Expand Down Expand Up @@ -435,6 +448,7 @@ public IMethodBinding[] getDeclaredMethods() {
Type.MethodType methodType = this.types.memberType(this.type, sym).asMethodType();
return this.resolver.bindings.getMethodBinding(methodType, sym);
})
.filter(Objects::nonNull)
.toArray(IMethodBinding[]::new);
}

Expand Down Expand Up @@ -572,9 +586,11 @@ public String getName() {
return builder.toString();
}
StringBuilder builder = new StringBuilder(this.typeSymbol.getSimpleName().toString());
if (this.getTypeArguments().length > 0) {
ITypeBinding[] types = this.getUncheckedTypeArguments(this.type, this.typeSymbol);

if (types != null && types.length > 0) {
builder.append("<");
for (var typeArgument : this.getTypeArguments()) {
for (var typeArgument : types) {
builder.append(typeArgument.getName());
}
builder.append(">");
Expand Down Expand Up @@ -725,7 +741,7 @@ public ITypeBinding[] getTypeArguments() {
}

private ITypeBinding[] getTypeArguments(Type t, TypeSymbol ts) {
if (t.getTypeArguments().isEmpty() || t == ts.type || isTargettingPreGenerics()) {
if (t == ts.type || t.getTypeArguments().isEmpty() || isTargettingPreGenerics()) {
return NO_TYPE_ARGUMENTS;
}
return getUncheckedTypeArguments(t, ts);
Expand Down Expand Up @@ -791,11 +807,12 @@ public ITypeBinding getTypeDeclaration() {

@Override
public ITypeBinding[] getTypeParameters() {
return !isRawType() && this.type instanceof ClassType classType
? classType.getTypeArguments()
if( isRawType() || getTypeArguments() == NO_TYPE_ARGUMENTS || !(this.type instanceof ClassType)) {
return new ITypeBinding[0];
}
return ((ClassType)this.type).getTypeArguments()
.map(this.resolver.bindings::getTypeBinding)
.toArray(ITypeBinding[]::new)
: new ITypeBinding[0];
.toArray(ITypeBinding[]::new);
}

@Override
Expand Down Expand Up @@ -869,7 +886,7 @@ public boolean isFromSource() {

@Override
public boolean isGenericType() {
return this.type.isParameterized() && this.type.getTypeArguments().stream().anyMatch(TypeVar.class::isInstance);
return this.type.isParameterized() && getTypeArguments() != NO_TYPE_ARGUMENTS && this.type.getTypeArguments().stream().anyMatch(TypeVar.class::isInstance);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.JavacBindingResolver;
import org.eclipse.jdt.core.dom.JavacBindingResolver.BindingKeyException;

import com.sun.tools.javac.code.Symbol.TypeVariableSymbol;
import com.sun.tools.javac.code.Type.TypeVar;
Expand Down Expand Up @@ -57,8 +58,9 @@ public String getQualifiedName() {
* this is the one that's used in method params and such, not the one that's actually used as it's final resting place (RIP)
* @param sym
* @return
* @throws BindingKeyException
*/
static String getTypeVariableKey(TypeVariableSymbol sym) {
static String getTypeVariableKey(TypeVariableSymbol sym) throws BindingKeyException {
StringBuilder builder = new StringBuilder();
builder.append(sym.getSimpleName());
builder.append(':');
Expand Down
Loading

0 comments on commit 901a147

Please sign in to comment.