@Override public void visitEnd() { if (!typeArguments.isEmpty()) { JavaSymbol.TypeJavaSymbol readSymbol = typeRead.symbol; readSymbol.complete(); //Mismatch between type variable and type arguments means we are lacking some pieces of bytecode to resolve substitution properly. if (typeArguments.size() == readSymbol.typeVariableTypes.size()) { TypeSubstitution substitution = new TypeSubstitution(); int i = 0; for (JavaType typeArgument : typeArguments) { substitution.add(readSymbol.typeVariableTypes.get(i), typeArgument); i++; } typeRead = parametrizedTypeCache.getParametrizedTypeType(readSymbol, substitution); } } } }
private JavaType lctaOneWildcard(JavaType rawType, WildCardType wildcardType) { if (wildcardType.boundType == WildCardType.BoundType.SUPER) { JavaType glb = (JavaType) greatestLowerBound(Lists.newArrayList(rawType, wildcardType.bound)); return parametrizedTypeCache.getWildcardType(glb, WildCardType.BoundType.SUPER); } JavaType lub = (JavaType) cachedLeastUpperBound(Sets.newHashSet(rawType, wildcardType.bound)); return parametrizedTypeCache.getWildcardType(lub, WildCardType.BoundType.EXTENDS); }
public JavaType getParametrizedTypeType(JavaSymbol.TypeJavaSymbol symbol, TypeSubstitution typeSubstitution) { if (symbol.getType().isUnknown()) { return symbol.getType(); } if (typeCache.get(symbol) == null) { Map<TypeSubstitution, ParametrizedTypeJavaType> map = Maps.newHashMap(); typeCache.put(symbol, map); } TypeSubstitution newSubstitution = typeSubstitution; if (newSubstitution.size() == 0) { newSubstitution = identitySubstitution(symbol.typeVariableTypes); } if (typeCache.get(symbol).get(newSubstitution) == null) { typeCache.get(symbol).put(newSubstitution, new ParametrizedTypeJavaType(symbol, newSubstitution, typeSubstitutionSolver)); } return typeCache.get(symbol).get(newSubstitution); }
JavaType getReturnType(@Nullable JavaType returnType, JavaType defSite, JavaType callSite, TypeSubstitution substitution, JavaSymbol.MethodJavaSymbol method) { JavaType resultType = returnType; if (method.isConstructor()) { if (constructParametrizedTypeWithoutSubstitution(method, defSite)) { resultType = applySubstitution(defSite, substitution); } else { return defSite; } } // As per getClass javadoc: // The actual result type [of getClass] is Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass is called. if(defSite == symbols.objectType && "getClass".equals(method.name())) { TypeJavaSymbol classSymbol = symbols.classType.symbol; JavaType wildcardType = parametrizedTypeCache.getWildcardType(callSite.erasure(), WildCardType.BoundType.EXTENDS); resultType = parametrizedTypeCache.getParametrizedTypeType(classSymbol, new TypeSubstitution().add(classSymbol.typeVariableTypes.get(0), wildcardType)); } resultType = applySiteSubstitution(resultType, defSite); if (callSite != defSite) { resultType = applySiteSubstitution(resultType, callSite); } resultType = applySubstitution(resultType, substitution); if (!isReturnTypeCompletelySubstituted(resultType, method.typeVariableTypes) || (method.isConstructor() && !isReturnTypeCompletelySubstituted(resultType, defSite.symbol.typeVariableTypes))) { resultType = symbols.deferedType(resultType); } return resultType; }
public static SemanticModel createFor(CompilationUnitTree tree, SquidClassLoader classLoader) { ParametrizedTypeCache parametrizedTypeCache = new ParametrizedTypeCache(); BytecodeCompleter bytecodeCompleter = new BytecodeCompleter(classLoader, parametrizedTypeCache); Symbols symbols = new Symbols(bytecodeCompleter); SemanticModel semanticModel = new SemanticModel(bytecodeCompleter); try { Resolve resolve = new Resolve(symbols, bytecodeCompleter, parametrizedTypeCache); TypeAndReferenceSolver typeAndReferenceSolver = new TypeAndReferenceSolver(semanticModel, symbols, resolve, parametrizedTypeCache); new FirstPass(semanticModel, symbols, resolve, parametrizedTypeCache, typeAndReferenceSolver).visitCompilationUnit(tree); typeAndReferenceSolver.visitCompilationUnit(tree); new LabelsVisitor(semanticModel).visitCompilationUnit(tree); } finally { handleMissingTypes(tree); } return semanticModel; }
public TypeSubstitutionSolver(ParametrizedTypeCache parametrizedTypeCache, Symbols symbols) { this.parametrizedTypeCache = parametrizedTypeCache; this.symbols = symbols; this.leastUpperBound = new LeastUpperBound(this, parametrizedTypeCache, symbols); this.typeInferenceSolver = new TypeInferenceSolver(leastUpperBound, symbols, this); parametrizedTypeCache.setTypeSubstitutionSolver(this); }
JavaType getReturnType(@Nullable JavaType returnType, JavaType defSite, JavaType callSite, TypeSubstitution substitution, JavaSymbol.MethodJavaSymbol method) { JavaType resultType = returnType; if (method.isConstructor()) { if (constructParametrizedTypeWithoutSubstitution(method, defSite)) { resultType = applySubstitution(defSite, substitution); } else { return defSite; } } // As per getClass javadoc: // The actual result type [of getClass] is Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass is called. if(defSite == symbols.objectType && "getClass".equals(method.name())) { TypeJavaSymbol classSymbol = symbols.classType.symbol; JavaType wildcardType = parametrizedTypeCache.getWildcardType(callSite.erasure(), WildCardType.BoundType.EXTENDS); resultType = parametrizedTypeCache.getParametrizedTypeType(classSymbol, new TypeSubstitution().add(classSymbol.typeVariableTypes.get(0), wildcardType)); } resultType = applySiteSubstitution(resultType, defSite); if (callSite != defSite) { resultType = applySiteSubstitution(resultType, callSite); } resultType = applySubstitution(resultType, substitution); if (!isReturnTypeCompletelySubstituted(resultType, method.typeVariableTypes) || (method.isConstructor() && !isReturnTypeCompletelySubstituted(resultType, defSite.symbol.typeVariableTypes))) { resultType = symbols.deferedType(resultType); } return resultType; }
public static SemanticModel createFor(CompilationUnitTree tree, SquidClassLoader classLoader) { ParametrizedTypeCache parametrizedTypeCache = new ParametrizedTypeCache(); BytecodeCompleter bytecodeCompleter = new BytecodeCompleter(classLoader, parametrizedTypeCache); Symbols symbols = new Symbols(bytecodeCompleter); SemanticModel semanticModel = new SemanticModel(bytecodeCompleter); try { Resolve resolve = new Resolve(symbols, bytecodeCompleter, parametrizedTypeCache); TypeAndReferenceSolver typeAndReferenceSolver = new TypeAndReferenceSolver(semanticModel, symbols, resolve, parametrizedTypeCache); new FirstPass(semanticModel, symbols, resolve, parametrizedTypeCache, typeAndReferenceSolver).visitCompilationUnit(tree); typeAndReferenceSolver.visitCompilationUnit(tree); new LabelsVisitor(semanticModel).visitCompilationUnit(tree); } finally { handleMissingTypes(tree); } return semanticModel; }
public TypeSubstitutionSolver(ParametrizedTypeCache parametrizedTypeCache, Symbols symbols) { this.parametrizedTypeCache = parametrizedTypeCache; this.symbols = symbols; this.leastUpperBound = new LeastUpperBound(this, parametrizedTypeCache, symbols); this.typeInferenceSolver = new TypeInferenceSolver(leastUpperBound, symbols, this); parametrizedTypeCache.setTypeSubstitutionSolver(this); }
@Override public void visitEnd() { if (!typeArguments.isEmpty()) { JavaSymbol.TypeJavaSymbol readSymbol = typeRead.symbol; readSymbol.complete(); //Mismatch between type variable and type arguments means we are lacking some pieces of bytecode to resolve substitution properly. if (typeArguments.size() == readSymbol.typeVariableTypes.size()) { TypeSubstitution substitution = new TypeSubstitution(); int i = 0; for (JavaType typeArgument : typeArguments) { substitution.add(readSymbol.typeVariableTypes.get(i), typeArgument); i++; } typeRead = parametrizedTypeCache.getParametrizedTypeType(readSymbol, substitution); } } } }
@Override public void visitEnd() { super.visitEnd(); JavaType typeArgument; switch (wildcard) { case EXTENDS: typeArgument = parametrizedTypeCache.getWildcardType(this.typeRead, WildCardType.BoundType.EXTENDS); break; case SUPER: typeArgument = parametrizedTypeCache.getWildcardType(this.typeRead, WildCardType.BoundType.SUPER); break; case INSTANCEOF: default: typeArgument = this.typeRead; break; } ReadType.this.typeArguments.add(typeArgument); } };
public static SemanticModel createFor(CompilationUnitTree tree, List<File> projectClasspath) { ParametrizedTypeCache parametrizedTypeCache = new ParametrizedTypeCache(); BytecodeCompleter bytecodeCompleter = new BytecodeCompleter(projectClasspath, parametrizedTypeCache); Symbols symbols = new Symbols(bytecodeCompleter); SemanticModel semanticModel = new SemanticModel(); semanticModel.bytecodeCompleter = bytecodeCompleter; try { Resolve resolve = new Resolve(symbols, bytecodeCompleter, parametrizedTypeCache); TypeAndReferenceSolver typeAndReferenceSolver = new TypeAndReferenceSolver(semanticModel, symbols, resolve, parametrizedTypeCache); new FirstPass(semanticModel, symbols, resolve, parametrizedTypeCache, typeAndReferenceSolver).visitCompilationUnit(tree); typeAndReferenceSolver.visitCompilationUnit(tree); new LabelsVisitor(semanticModel).visitCompilationUnit(tree); } finally { handleMissingTypes(tree); } return semanticModel; }
public JavaType getParametrizedTypeType(JavaSymbol.TypeJavaSymbol symbol, TypeSubstitution typeSubstitution) { if (symbol.getType().isUnknown()) { return symbol.getType(); } if (typeCache.get(symbol) == null) { Map<TypeSubstitution, ParametrizedTypeJavaType> map = Maps.newHashMap(); typeCache.put(symbol, map); } TypeSubstitution newSubstitution = typeSubstitution; if (newSubstitution.size() == 0) { newSubstitution = identitySubstitution(symbol.typeVariableTypes); } if (typeCache.get(symbol).get(newSubstitution) == null) { typeCache.get(symbol).put(newSubstitution, new ParametrizedTypeJavaType(symbol, newSubstitution, typeSubstitutionSolver)); } return typeCache.get(symbol).get(newSubstitution); }
@Override public void visitEnd() { if (!typeArguments.isEmpty()) { JavaSymbol.TypeJavaSymbol readSymbol = typeRead.symbol; readSymbol.complete(); //Mismatch between type variable and type arguments means we are lacking some pieces of bytecode to resolve substitution properly. if (typeArguments.size() == readSymbol.typeVariableTypes.size()) { TypeSubstitution substitution = new TypeSubstitution(); int i = 0; for (JavaType typeArgument : typeArguments) { substitution.add(readSymbol.typeVariableTypes.get(i), typeArgument); i++; } typeRead = parametrizedTypeCache.getParametrizedTypeType(readSymbol, substitution); } } } }
@Override public void visitEnd() { super.visitEnd(); JavaType typeArgument; switch (wildcard) { case EXTENDS: typeArgument = parametrizedTypeCache.getWildcardType(this.typeRead, JavaType.WildCardType.BoundType.EXTENDS); break; case SUPER: typeArgument = parametrizedTypeCache.getWildcardType(this.typeRead, JavaType.WildCardType.BoundType.SUPER); break; case INSTANCEOF: default: typeArgument = this.typeRead; break; } ReadType.this.typeArguments.add(typeArgument); } };
public static SemanticModel createFor(CompilationUnitTree tree, List<File> projectClasspath) { ParametrizedTypeCache parametrizedTypeCache = new ParametrizedTypeCache(); BytecodeCompleter bytecodeCompleter = new BytecodeCompleter(projectClasspath, parametrizedTypeCache); Symbols symbols = new Symbols(bytecodeCompleter); SemanticModel semanticModel = new SemanticModel(); semanticModel.bytecodeCompleter = bytecodeCompleter; semanticModel.createParentLink((JavaTree) tree); try { Resolve resolve = new Resolve(symbols, bytecodeCompleter, parametrizedTypeCache); TypeAndReferenceSolver typeAndReferenceSolver = new TypeAndReferenceSolver(semanticModel, symbols, resolve, parametrizedTypeCache); new FirstPass(semanticModel, symbols, resolve, parametrizedTypeCache, typeAndReferenceSolver).visitCompilationUnit(tree); typeAndReferenceSolver.visitCompilationUnit(tree); new LabelsVisitor(semanticModel).visitCompilationUnit(tree); } finally { handleMissingTypes(tree); } return semanticModel; }
@Override public void visitEnd() { if (!typeArguments.isEmpty()) { JavaSymbol.TypeJavaSymbol readSymbol = typeRead.symbol; readSymbol.complete(); //Mismatch between type variable and type arguments means we are lacking some pieces of bytecode to resolve substitution properly. if (typeArguments.size() == readSymbol.typeVariableTypes.size()) { TypeSubstitution substitution = new TypeSubstitution(); int i = 0; for (JavaType typeArgument : typeArguments) { substitution.add(readSymbol.typeVariableTypes.get(i), typeArgument); i++; } typeRead = parametrizedTypeCache.getParametrizedTypeType(readSymbol, substitution); } } } }
private JavaType substituteInWildCardType(WildCardType wildcard, TypeSubstitution substitution) { JavaType substitutedType = applySubstitution(wildcard.bound, substitution); if (substitutedType != wildcard.bound) { return parametrizedTypeCache.getWildcardType(substitutedType, wildcard.boundType); } return wildcard; }
JavaType erasureSubstitution(ParametrizedTypeJavaType type) { TypeSubstitution substitution = new TypeSubstitution(); for (Map.Entry<TypeVariableJavaType, JavaType> entry : type.typeSubstitution.substitutionEntries()) { TypeVariableJavaType typeVar = entry.getKey(); JavaType subs = entry.getValue(); if (typeVar == subs) { subs = subs.erasure(); } substitution.add(typeVar, subs); } return parametrizedTypeCache.getParametrizedTypeType(type.symbol, substitution); }
private JavaType lctaOneWildcard(JavaType rawType, WildCardType wildcardType) { if (wildcardType.boundType == WildCardType.BoundType.SUPER) { JavaType glb = (JavaType) greatestLowerBound(Lists.newArrayList(rawType, wildcardType.bound)); return parametrizedTypeCache.getWildcardType(glb, WildCardType.BoundType.SUPER); } JavaType lub = (JavaType) cachedLeastUpperBound(Sets.newHashSet(rawType, wildcardType.bound)); return parametrizedTypeCache.getWildcardType(lub, WildCardType.BoundType.EXTENDS); }