blob: 18b8d742c611566685b9a5ec277bdad3cbd55456 [file] [log] [blame]
package com.github.javaparser.symbolsolver.resolution.typeinference;
import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
import com.github.javaparser.resolution.types.ResolvedType;
import java.util.LinkedList;
import java.util.List;
/**
* Are meta-variables for types - that is, they are special names that allow abstract reasoning about types.
* To distinguish them from type variables, inference variables are represented with Greek letters, principally α.
*
* See JLS 18
*
* @author Federico Tomassetti
*/
public class InferenceVariable implements ResolvedType {
private static int unnamedInstantiated = 0;
private String name;
private ResolvedTypeParameterDeclaration typeParameterDeclaration;
public static List<InferenceVariable> instantiate(List<ResolvedTypeParameterDeclaration> typeParameterDeclarations) {
List<InferenceVariable> inferenceVariables = new LinkedList<>();
for (ResolvedTypeParameterDeclaration tp : typeParameterDeclarations) {
inferenceVariables.add(InferenceVariable.unnamed(tp));
}
return inferenceVariables;
}
public static InferenceVariable unnamed(ResolvedTypeParameterDeclaration typeParameterDeclaration) {
return new InferenceVariable("__unnamed__" + (unnamedInstantiated++), typeParameterDeclaration);
}
public InferenceVariable(String name, ResolvedTypeParameterDeclaration typeParameterDeclaration) {
this.name = name;
this.typeParameterDeclaration = typeParameterDeclaration;
}
@Override
public String describe() {
return name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InferenceVariable that = (InferenceVariable) o;
if (!name.equals(that.name)) return false;
return typeParameterDeclaration != null ? typeParameterDeclaration.equals(that.typeParameterDeclaration)
: that.typeParameterDeclaration == null;
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + (typeParameterDeclaration != null ? typeParameterDeclaration.hashCode() : 0);
return result;
}
@Override
public boolean isAssignableBy(ResolvedType other) {
if (other.equals(this)) {
return true;
}
throw new UnsupportedOperationException(
"We are unable to determine the assignability of an inference variable without knowing the bounds and"
+ " constraints");
}
public ResolvedTypeParameterDeclaration getTypeParameterDeclaration() {
if (typeParameterDeclaration == null) {
throw new IllegalStateException("The type parameter declaration was not specified");
}
return typeParameterDeclaration;
}
@Override
public String toString() {
return "InferenceVariable{" +
"name='" + name + '\'' +
", typeParameterDeclaration=" + typeParameterDeclaration +
'}';
}
@Override
public boolean mention(List<ResolvedTypeParameterDeclaration> typeParameters) {
return false;
}
}