use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable in project checker-framework by typetools.
the class TypeArgInferenceUtil method containsUninferredTypeParameter.
/**
* @return true if the type contains a use of a type variable from methodType
*/
private static boolean containsUninferredTypeParameter(AnnotatedTypeMirror type, AnnotatedExecutableType methodType) {
final List<AnnotatedTypeVariable> annotatedTypeVars = methodType.getTypeVariables();
final List<TypeVariable> typeVars = new ArrayList<>(annotatedTypeVars.size());
for (AnnotatedTypeVariable annotatedTypeVar : annotatedTypeVars) {
typeVars.add((TypeVariable) TypeAnnotationUtils.unannotatedType(annotatedTypeVar.getUnderlyingType()));
}
return containsTypeParameter(type, typeVars);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable in project checker-framework by typetools.
the class AnnotatedTypeCopier method visitTypeVariable.
@Override
public AnnotatedTypeMirror visitTypeVariable(AnnotatedTypeVariable original, IdentityHashMap<AnnotatedTypeMirror, AnnotatedTypeMirror> originalToCopy) {
if (originalToCopy.containsKey(original)) {
return originalToCopy.get(original);
}
final AnnotatedTypeVariable copy = (AnnotatedTypeVariable) AnnotatedTypeMirror.createType(original.getUnderlyingType(), original.atypeFactory, original.isDeclaration());
maybeCopyPrimaryAnnotations(original, copy);
originalToCopy.put(original, copy);
if (original.getUpperBoundField() != null) {
// TODO: figure out why asUse is needed here and remove it.
copy.setUpperBound(visit(original.getUpperBoundField(), originalToCopy).asUse());
}
if (original.getLowerBoundField() != null) {
// TODO: figure out why asUse is needed here and remove it.
copy.setLowerBound(visit(original.getLowerBoundField(), originalToCopy).asUse());
}
return copy;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable in project checker-framework by typetools.
the class AnnotatedTypeFactory method methodFromUse.
public Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> methodFromUse(ExpressionTree tree, ExecutableElement methodElt, AnnotatedTypeMirror receiverType) {
AnnotatedExecutableType methodType = AnnotatedTypes.asMemberOf(types, this, receiverType, methodElt);
List<AnnotatedTypeMirror> typeargs = new ArrayList<>(methodType.getTypeVariables().size());
Map<TypeVariable, AnnotatedTypeMirror> typeVarMapping = AnnotatedTypes.findTypeArguments(processingEnv, this, tree, methodElt, methodType);
if (!typeVarMapping.isEmpty()) {
for (AnnotatedTypeVariable tv : methodType.getTypeVariables()) {
if (typeVarMapping.get(tv.getUnderlyingType()) == null) {
ErrorReporter.errorAbort("AnnotatedTypeFactory.methodFromUse:" + "mismatch between declared method type variables and the inferred method type arguments! " + "Method type variables: " + methodType.getTypeVariables() + "; " + "Inferred method type arguments: " + typeVarMapping);
}
typeargs.add(typeVarMapping.get(tv.getUnderlyingType()));
}
methodType = (AnnotatedExecutableType) typeVarSubstitutor.substitute(typeVarMapping, methodType);
}
if (tree.getKind() == Tree.Kind.METHOD_INVOCATION && TreeUtils.isGetClassInvocation((MethodInvocationTree) tree)) {
adaptGetClassReturnTypeToReceiver(methodType, receiverType);
}
return Pair.of(methodType, typeargs);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable in project checker-framework by typetools.
the class AnnotatedTypeFactory method constructorFromUse.
/**
* Determines the type of the invoked constructor based on the passed new class tree.
*
* <p>The returned method type has all type variables resolved, whether based on receiver type,
* passed type parameters if any, and constructor invocation parameter.
*
* <p>Subclasses may override this method to customize inference of types or qualifiers based on
* constructor invocation parameters.
*
* <p>As an implementation detail, this method depends on {@link
* AnnotatedTypes#asMemberOf(Types, AnnotatedTypeFactory, AnnotatedTypeMirror, Element)}, and
* customization based on receiver type should be in accordance with its specification.
*
* <p>The return type is a pair of the type of the invoked constructor and the (inferred) type
* arguments. Note that neither the explicitly passed nor the inferred type arguments are
* guaranteed to be subtypes of the corresponding upper bounds. See method {@link
* org.checkerframework.common.basetype.BaseTypeVisitor#checkTypeArguments(Tree, List, List,
* List)} for the checks of type argument well-formedness.
*
* <p>Note that "this" and "super" constructor invocations are handled by method {@link
* #methodFromUse}. This method only handles constructor invocations in a "new" expression.
*
* @param tree the constructor invocation tree
* @return the annotated type of the invoked constructor (as an executable type) and the
* (inferred) type arguments
*/
public Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> constructorFromUse(NewClassTree tree) {
ExecutableElement ctor = TreeUtils.constructor(tree);
AnnotatedTypeMirror type = fromNewClass(tree);
addComputedTypeAnnotations(tree.getIdentifier(), type);
AnnotatedExecutableType con = AnnotatedTypes.asMemberOf(types, this, type, ctor);
if (tree.getArguments().size() == con.getParameterTypes().size() + 1 && isSyntheticArgument(tree.getArguments().get(0))) {
// happens for anonymous constructors of inner classes
List<AnnotatedTypeMirror> actualParams = new ArrayList<>();
actualParams.add(getAnnotatedType(tree.getArguments().get(0)));
actualParams.addAll(con.getParameterTypes());
con.setParameterTypes(actualParams);
}
List<AnnotatedTypeMirror> typeargs = new ArrayList<>(con.getTypeVariables().size());
Map<TypeVariable, AnnotatedTypeMirror> typeVarMapping = AnnotatedTypes.findTypeArguments(processingEnv, this, tree, ctor, con);
if (!typeVarMapping.isEmpty()) {
for (AnnotatedTypeVariable tv : con.getTypeVariables()) {
typeargs.add(typeVarMapping.get(tv.getUnderlyingType()));
}
con = (AnnotatedExecutableType) typeVarSubstitutor.substitute(typeVarMapping, con);
}
return Pair.of(con, typeargs);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable in project checker-framework by typetools.
the class AnnotatedTypeFactory method makeGroundTargetType.
/**
* Create the ground target type of the functional interface.
*
* <p>Basically, it replaces the wildcards with their bounds doing a capture conversion like glb
* for extends bounds.
*
* @see "JLS 9.9"
* @param functionalType the functional interface type
* @param groundTargetJavaType the Java type as found by javac
*/
private void makeGroundTargetType(AnnotatedDeclaredType functionalType, DeclaredType groundTargetJavaType) {
if (functionalType.getTypeArguments().isEmpty()) {
return;
}
List<AnnotatedTypeParameterBounds> bounds = this.typeVariablesFromUse(functionalType, (TypeElement) functionalType.getUnderlyingType().asElement());
List<AnnotatedTypeMirror> newTypeArguments = new ArrayList<>(functionalType.getTypeArguments());
boolean sizesDiffer = functionalType.getTypeArguments().size() != groundTargetJavaType.getTypeArguments().size();
for (int i = 0; i < functionalType.getTypeArguments().size(); i++) {
AnnotatedTypeMirror argType = functionalType.getTypeArguments().get(i);
if (argType.getKind() == TypeKind.WILDCARD) {
AnnotatedWildcardType wildcardType = (AnnotatedWildcardType) argType;
TypeMirror wildcardUbType = wildcardType.getExtendsBound().getUnderlyingType();
if (wildcardType.isUninferredTypeArgument()) {
// Keep the uninferred type so that it is ignored by later subtyping and
// containment checks.
newTypeArguments.set(i, wildcardType);
} else if (isExtendsWildcard(wildcardType)) {
TypeMirror correctArgType;
if (sizesDiffer) {
// The java type is raw.
TypeMirror typeParamUbType = bounds.get(i).getUpperBound().getUnderlyingType();
correctArgType = TypesUtils.greatestLowerBound(typeParamUbType, wildcardUbType, this.checker.getProcessingEnvironment());
} else {
correctArgType = groundTargetJavaType.getTypeArguments().get(i);
}
final AnnotatedTypeMirror newArg;
if (types.isSameType(wildcardUbType, correctArgType)) {
newArg = wildcardType.getExtendsBound().deepCopy();
} else if (correctArgType.getKind() == TypeKind.TYPEVAR) {
newArg = this.toAnnotatedType(correctArgType, false);
AnnotatedTypeVariable newArgAsTypeVar = (AnnotatedTypeVariable) newArg;
newArgAsTypeVar.getUpperBound().replaceAnnotations(wildcardType.getExtendsBound().getAnnotations());
newArgAsTypeVar.getLowerBound().replaceAnnotations(wildcardType.getSuperBound().getAnnotations());
} else {
newArg = this.toAnnotatedType(correctArgType, false);
newArg.replaceAnnotations(wildcardType.getExtendsBound().getAnnotations());
}
newTypeArguments.set(i, newArg);
} else {
newTypeArguments.set(i, wildcardType.getSuperBound());
}
}
}
functionalType.setTypeArguments(newTypeArguments);
// When the groundTargetJavaType is different from the underlying type of functionalType,
// only the main annotations are copied. Add default annotations in places without
// annotations.
addDefaultAnnotations(functionalType);
}
Aggregations