1 package com.github.javaparser.symbolsolver.resolution.typeinference; 2 3 import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; 4 import com.github.javaparser.resolution.types.ResolvedType; 5 6 import java.util.LinkedList; 7 import java.util.List; 8 9 /** 10 * Are meta-variables for types - that is, they are special names that allow abstract reasoning about types. 11 * To distinguish them from type variables, inference variables are represented with Greek letters, principally α. 12 * 13 * See JLS 18 14 * 15 * @author Federico Tomassetti 16 */ 17 public class InferenceVariable implements ResolvedType { 18 private static int unnamedInstantiated = 0; 19 20 private String name; 21 private ResolvedTypeParameterDeclaration typeParameterDeclaration; 22 instantiate(List<ResolvedTypeParameterDeclaration> typeParameterDeclarations)23 public static List<InferenceVariable> instantiate(List<ResolvedTypeParameterDeclaration> typeParameterDeclarations) { 24 List<InferenceVariable> inferenceVariables = new LinkedList<>(); 25 for (ResolvedTypeParameterDeclaration tp : typeParameterDeclarations) { 26 inferenceVariables.add(InferenceVariable.unnamed(tp)); 27 } 28 return inferenceVariables; 29 } 30 unnamed(ResolvedTypeParameterDeclaration typeParameterDeclaration)31 public static InferenceVariable unnamed(ResolvedTypeParameterDeclaration typeParameterDeclaration) { 32 return new InferenceVariable("__unnamed__" + (unnamedInstantiated++), typeParameterDeclaration); 33 } 34 InferenceVariable(String name, ResolvedTypeParameterDeclaration typeParameterDeclaration)35 public InferenceVariable(String name, ResolvedTypeParameterDeclaration typeParameterDeclaration) { 36 this.name = name; 37 this.typeParameterDeclaration = typeParameterDeclaration; 38 } 39 40 @Override describe()41 public String describe() { 42 return name; 43 } 44 45 @Override equals(Object o)46 public boolean equals(Object o) { 47 if (this == o) return true; 48 if (o == null || getClass() != o.getClass()) return false; 49 50 InferenceVariable that = (InferenceVariable) o; 51 52 if (!name.equals(that.name)) return false; 53 return typeParameterDeclaration != null ? typeParameterDeclaration.equals(that.typeParameterDeclaration) 54 : that.typeParameterDeclaration == null; 55 } 56 57 @Override hashCode()58 public int hashCode() { 59 int result = name.hashCode(); 60 result = 31 * result + (typeParameterDeclaration != null ? typeParameterDeclaration.hashCode() : 0); 61 return result; 62 } 63 64 @Override isAssignableBy(ResolvedType other)65 public boolean isAssignableBy(ResolvedType other) { 66 if (other.equals(this)) { 67 return true; 68 } 69 throw new UnsupportedOperationException( 70 "We are unable to determine the assignability of an inference variable without knowing the bounds and" 71 + " constraints"); 72 } 73 getTypeParameterDeclaration()74 public ResolvedTypeParameterDeclaration getTypeParameterDeclaration() { 75 if (typeParameterDeclaration == null) { 76 throw new IllegalStateException("The type parameter declaration was not specified"); 77 } 78 return typeParameterDeclaration; 79 } 80 81 @Override toString()82 public String toString() { 83 return "InferenceVariable{" + 84 "name='" + name + '\'' + 85 ", typeParameterDeclaration=" + typeParameterDeclaration + 86 '}'; 87 } 88 89 @Override mention(List<ResolvedTypeParameterDeclaration> typeParameters)90 public boolean mention(List<ResolvedTypeParameterDeclaration> typeParameters) { 91 return false; 92 } 93 } 94