All Downloads are FREE. Search and download functionalities are using the official Maven repository.

framework.src.org.checkerframework.qualframework.base.DefaultQualifiedTypeFactory Maven / Gradle / Ivy

Go to download

The Checker Framework enhances Java’s type system to make it more powerful and useful. This lets software developers detect and prevent errors in their Java programs. The Checker Framework includes compiler plug-ins ("checkers") that find bugs or verify their absence. It also permits you to write your own compiler plug-ins.

There is a newer version: 3.42.0
Show newest version
package org.checkerframework.qualframework.base;

import org.checkerframework.javacutil.Pair;
import org.checkerframework.qualframework.base.QualifiedTypeMirror.QualifiedExecutableType;
import org.checkerframework.qualframework.base.dataflow.QualAnalysis;
import org.checkerframework.qualframework.base.dataflow.QualValue;
import org.checkerframework.qualframework.util.ExtendedParameterDeclaration;
import org.checkerframework.qualframework.util.ExtendedTypeMirror;
import org.checkerframework.qualframework.util.QualifierContext;
import org.checkerframework.qualframework.util.WrappedAnnotatedTypeMirror;
import org.checkerframework.qualframework.util.WrappedAnnotatedTypeMirror.WrappedAnnotatedTypeVariable;

import java.util.IdentityHashMap;
import java.util.List;
import java.util.Set;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.VariableElement;

import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreePath;

/** Default implementation of {@link QualifiedTypeFactory}.  Most type systems
 * should extend this class (or a subclass) instead of implementing {@link
 * QualifiedTypeFactory} directly.
 *
 * This implementation decomposes the problem of type checking using several
 * helper classes:
 *
 * 
    *
  • {@link AnnotationConverter}: Converts annotations written in the source * code into type qualifiers for use in type checking.
  • *
  • {@link TypeAnnotator}: A visitor for * {@link org.checkerframework.qualframework.util.ExtendedTypeMirror}s that * adds a qualifier to each component of the type, producing a {@link * QualifiedTypeMirror}.
  • *
  • {@link TreeAnnotator}: A visitor for {@link Tree}s that computes the * qualified type of each AST node based on the qualified types of its * subnodes.
  • *
  • {@link QualifierHierarchy}: Used to perform subtyping checks between * two type qualifiers (independent of any Java types).
  • *
  • {@link TypeHierarchy}: Used to perform subtyping checks between two * {@link QualifiedTypeMirror}s.
  • *
* * Default implementations are available for {@link TypeAnnotator}, {@link * TreeAnnotator}, and {@link TypeHierarchy}. The type system must provide * implementations for {@link AnnotationConverter} and {@link * QualifierHierarchy}. */ public abstract class DefaultQualifiedTypeFactory implements QualifiedTypeFactory { private final IdentityHashMap> paramBoundsMap = new IdentityHashMap<>(); private QualifiedTypes qualifiedTypes; private QualifierHierarchy qualifierHierarchy; private TypeHierarchy typeHierarchy; private AnnotationConverter annotationConverter; private TreeAnnotator treeAnnotator; private TypeAnnotator typeAnnotator; private QualifiedTypeFactoryAdapter adapter; private final QualifierContext context; public DefaultQualifiedTypeFactory(QualifierContext context) { this.context = context; } @Override public final QualifiedTypeMirror getQualifiedType(Element element) { return adapter.superGetAnnotatedType(element); } @Override public final QualifiedTypeMirror getQualifiedType(Tree tree) { return adapter.superGetAnnotatedType(tree); } @Override public final QualifiedTypeMirror getQualifiedTypeFromTypeTree(Tree typeTree) { return adapter.superGetAnnotatedTypeFromTypeTree(typeTree); } @Override public final QualifiedTypeParameterBounds getQualifiedTypeParameterBounds(ExtendedParameterDeclaration etm) { if (!paramBoundsMap.containsKey(etm)) { QualifiedTypeParameterBounds bounds = computeQualifiedTypeParameterBounds(etm); paramBoundsMap.put(etm, bounds); } return paramBoundsMap.get(etm); } /** * Computes the bounds of a type parameter. The default implementation * processes the type annotations of the upper and lower bounds using the * {@link TypeAnnotator}. */ protected QualifiedTypeParameterBounds computeQualifiedTypeParameterBounds(ExtendedParameterDeclaration etm) { TypeAnnotator annotator = getTypeAnnotator(); WrappedAnnotatedTypeVariable watv = (WrappedAnnotatedTypeVariable)etm; WrappedAnnotatedTypeMirror rawUpper = WrappedAnnotatedTypeMirror.wrap(watv.unwrap().getUpperBound()); WrappedAnnotatedTypeMirror rawLower = WrappedAnnotatedTypeMirror.wrap(watv.unwrap().getLowerBound()); QualifiedTypeMirror upper = annotator.visit(rawUpper, null); QualifiedTypeMirror lower = annotator.visit(rawLower, null); return new QualifiedTypeParameterBounds(upper, lower); } // This method has package access so it can be called from QTFAdapter. It // should be made private once the adapter is no longer needed. TreeAnnotator getTreeAnnotator() { if (this.treeAnnotator == null) { this.treeAnnotator = createTreeAnnotator(); } return this.treeAnnotator; } /** * Constructs the {@link TreeAnnotator} to be used by this type factory. * Checkers that need custom {@link TreeAnnotator} behavior should * override this method to return an instance of their custom {@link * TreeAnnotator} subclass. */ protected TreeAnnotator createTreeAnnotator() { return new TreeAnnotator(); } // This method has package access so it can be called from QTFAdapter. It // should be made private once the adapter is no longer needed. TypeAnnotator getTypeAnnotator() { if (this.typeAnnotator == null) { this.typeAnnotator = createTypeAnnotator(); } return this.typeAnnotator; } /** * Constructs the {@link TypeAnnotator} to be used by this type factory. * Checkers that need custom {@link TypeAnnotator} behavior should * override this method to return an instance of their custom {@link * TypeAnnotator} subclass. */ protected TypeAnnotator createTypeAnnotator() { // Construct a new TypeAnnotator using the TOP qualifier as the // default. return new TypeAnnotator(context, getAnnotationConverter(), getQualifierHierarchy().getTop()); } @Override public final QualifiedTypes getQualifiedTypes() { if (this.qualifiedTypes == null) { this.qualifiedTypes = createQualifiedTypes(); } return this.qualifiedTypes; } protected QualifiedTypes createQualifiedTypes() { return new AdapterQualifiedTypes(adapter); } @Override public QualifierHierarchy getQualifierHierarchy() { if (this.qualifierHierarchy == null) { this.qualifierHierarchy = createQualifierHierarchy(); } return this.qualifierHierarchy; } /** * Constructs a {@link QualifierHierarchy} for the current type system. * Every checker must override this method to return an appropriate {@link * QualifierHierarchy} subclass for that checker. */ protected abstract QualifierHierarchy createQualifierHierarchy(); @Override public TypeHierarchy getTypeHierarchy() { if (this.typeHierarchy == null) { this.typeHierarchy = createTypeHierarchy(getQualifierHierarchy()); } return this.typeHierarchy; } /** * Constructs a {@link TypeHierarchy} for the current type system. The * default implementation constructs a {@link DefaultTypeHierarchy}. * * @param qualifierHierarchy * a reference to the {@link QualifierHierarchy} used by this type system */ protected TypeHierarchy createTypeHierarchy(QualifierHierarchy qualifierHierarchy) { return new DefaultTypeHierarchy(); } /** * Gets the {@link AnnotationConverter} for the current type system. */ public AnnotationConverter getAnnotationConverter() { if (this.annotationConverter == null) { this.annotationConverter = createAnnotationConverter(); } return this.annotationConverter; } /** * Constructs an {@link AnnotationConverter} for the current type system. * Every checker must override this method to return an appropriate {@link * AnnotationConverter} subclass for that checker. */ protected abstract AnnotationConverter createAnnotationConverter(); @Override public List> postDirectSuperTypes(QualifiedTypeMirror subtype, List> supertypes) { return adapter.superPostDirectSuperTypes(subtype, supertypes); } @Override public QualifiedTypeMirror postAsMemberOf(QualifiedTypeMirror memberType, QualifiedTypeMirror receiverType, Element memberElement) { return adapter.superPostAsMemberOf(memberType, receiverType, memberElement); } @Override public Pair, List>> methodFromUse(MethodInvocationTree tree) { return adapter.superMethodFromUse(tree); } @Override public Pair, List>> methodFromUse(ExpressionTree tree, ExecutableElement methodElt, QualifiedTypeMirror receiverType) { return adapter.superMethodFromUse(tree, methodElt, receiverType); } @Override public Pair, List>> constructorFromUse(NewClassTree tree) { throw new UnsupportedOperationException(); } @Override public QualAnalysis createFlowAnalysis(List>> fieldValues) { return new QualAnalysis(this.getContext()); } public QualifierContext getContext() { return context; } void setAdapter(QualifiedTypeFactoryAdapter adapter) { this.adapter = adapter; } @Override public TreePath getPath(Tree node) { return adapter.getPath(node); } @Override public QualifiedTypeMirror getReceiverType(ExpressionTree expression) { return adapter.getCheckerAdapter().getTypeMirrorConverter().getQualifiedType(adapter.getReceiverType(expression)); } @Override public ExtendedTypeMirror getDecoratedElement(Element element) { return WrappedAnnotatedTypeMirror.wrap(adapter.fromElement(element)); } @Override public TypeVariableSubstitutor createTypeVariableSubstitutor() { return new TypeVariableSubstitutor<>(); } @Override public Set getDeclAnnotations(Element elt) { return adapter.getDeclAnnotations(elt); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy