use of org.checkerframework.javacutil.Pair in project checker-framework by typetools.
the class CFAbstractTransfer method addFieldValues.
private void addFieldValues(S info, AnnotatedTypeFactory factory, ClassTree classTree, MethodTree methodTree) {
// Add knowledge about final fields, or values of non-final fields
// if we are inside a constructor (information about initializers)
TypeMirror classType = TreeUtils.typeOf(classTree);
List<Pair<VariableElement, V>> fieldValues = analysis.getFieldValues();
for (Pair<VariableElement, V> p : fieldValues) {
VariableElement element = p.first;
V value = p.second;
if (ElementUtils.isFinal(element) || TreeUtils.isConstructor(methodTree)) {
Receiver receiver;
if (ElementUtils.isStatic(element)) {
receiver = new ClassName(classType);
} else {
receiver = new ThisReference(classType);
}
TypeMirror fieldType = ElementUtils.getType(element);
Receiver field = new FieldAccess(receiver, fieldType, element);
info.insertValue(field, value);
}
}
// add properties about fields (static information from type)
boolean isNotFullyInitializedReceiver = isNotFullyInitializedReceiver(methodTree);
if (isNotFullyInitializedReceiver && !TreeUtils.isConstructor(methodTree)) {
// and the method isn't a constructor
return;
}
for (Tree member : classTree.getMembers()) {
if (member instanceof VariableTree) {
VariableTree vt = (VariableTree) member;
final VariableElement element = TreeUtils.elementFromDeclaration(vt);
AnnotatedTypeMirror type = ((GenericAnnotatedTypeFactory<?, ?, ?, ?>) factory).getAnnotatedTypeLhs(vt);
TypeMirror fieldType = ElementUtils.getType(element);
Receiver receiver;
if (ElementUtils.isStatic(element)) {
receiver = new ClassName(classType);
} else {
receiver = new ThisReference(classType);
}
V value = analysis.createAbstractValue(type);
if (value == null)
continue;
if (TreeUtils.isConstructor(methodTree)) {
// if we are in a constructor,
// then we can still use the static type, but only
// if there is also an initializer that already does
// some initialization.
boolean found = false;
for (Pair<VariableElement, V> fieldValue : fieldValues) {
if (fieldValue.first.equals(element)) {
value = value.leastUpperBound(fieldValue.second);
found = true;
break;
}
}
if (!found) {
// no initializer found, cannot use static type
continue;
}
}
Receiver field = new FieldAccess(receiver, fieldType, element);
info.insertValue(field, value);
}
}
}
use of org.checkerframework.javacutil.Pair in project checker-framework by typetools.
the class StubParser method getAllStubAnnotations.
/**
* Returns all annotations found in the stub file, as a value for {@link #allStubAnnotations}.
* Note that this also modifies {@link #importedConstants} and {@link #importedTypes}.
*
* @see #allStubAnnotations
*/
private Map<String, AnnotationMirror> getAllStubAnnotations() {
Map<String, AnnotationMirror> result = new HashMap<>();
assert !stubUnit.getCompilationUnits().isEmpty();
CompilationUnit cu = stubUnit.getCompilationUnits().get(0);
if (cu.getImports() == null) {
return result;
}
for (ImportDeclaration importDecl : cu.getImports()) {
String imported = importDecl.getNameAsString();
try {
if (importDecl.isAsterisk()) {
if (importDecl.isStatic()) {
// Wildcard import of members of a type (class or interface)
TypeElement element = getTypeElement(imported, "Imported type not found");
if (element != null) {
// Find nested annotations
// Find compile time constant fields, or values of an enum
putAllNew(result, annosInType(element));
importedConstants.addAll(getImportableMembers(element));
addEnclosingTypesToImportedTypes(element);
}
} else {
// Wildcard import of members of a package
PackageElement element = findPackage(imported);
if (element != null) {
putAllNew(result, annosInPackage(element));
addEnclosingTypesToImportedTypes(element);
}
}
} else {
// A single (non-wildcard) import
final TypeElement importType = elements.getTypeElement(imported);
if (importType == null && !importDecl.isStatic()) {
// Class or nested class (according to JSL), but we can't resolve
stubWarnNotFound("Imported type not found: " + imported);
} else if (importType == null) {
// Nested Field
Pair<String, String> typeParts = StubUtil.partitionQualifiedName(imported);
String type = typeParts.first;
String fieldName = typeParts.second;
TypeElement enclType = getTypeElement(type, String.format("Enclosing type of static field %s not found", fieldName));
if (enclType != null) {
if (findFieldElement(enclType, fieldName) != null) {
importedConstants.add(imported);
}
}
} else if (importType.getKind() == ElementKind.ANNOTATION_TYPE) {
// Single annotation or nested annotation
AnnotationMirror anno = AnnotationBuilder.fromName(elements, imported);
if (anno != null) {
Element annoElt = anno.getAnnotationType().asElement();
putNoOverride(result, annoElt.getSimpleName().toString(), anno);
importedTypes.put(annoElt.getSimpleName().toString(), (TypeElement) annoElt);
} else {
stubWarnNotFound("Could not load import: " + imported);
}
} else {
// Class or nested class
// TODO: Is this needed?
importedConstants.add(imported);
TypeElement element = getTypeElement(imported, "Imported type not found");
importedTypes.put(element.getSimpleName().toString(), element);
}
}
} catch (AssertionError error) {
stubWarnNotFound("" + error);
}
}
return result;
}
use of org.checkerframework.javacutil.Pair in project checker-framework by typetools.
the class GenericAnnotatedTypeFactory method createFlowAnalysis.
/**
* Returns the appropriate flow analysis class that is used for the
* org.checkerframework.dataflow analysis.
*
* <p>This implementation uses the checker naming convention to create the appropriate analysis.
* If no transfer function is found, it returns an instance of {@link CFAnalysis}.
*
* <p>Subclasses have to override this method to create the appropriate analysis if they do not
* follow the checker naming convention.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
protected FlowAnalysis createFlowAnalysis(List<Pair<VariableElement, Value>> fieldValues) {
// Try to reflectively load the visitor.
Class<?> checkerClass = checker.getClass();
while (checkerClass != BaseTypeChecker.class) {
final String classToLoad = checkerClass.getName().replace("Checker", "Analysis").replace("Subchecker", "Analysis");
FlowAnalysis result = BaseTypeChecker.invokeConstructorFor(classToLoad, new Class<?>[] { BaseTypeChecker.class, this.getClass(), List.class }, new Object[] { checker, this, fieldValues });
if (result != null) {
return result;
}
checkerClass = checkerClass.getSuperclass();
}
// If an analysis couldn't be loaded reflectively, return the
// default.
List<Pair<VariableElement, CFValue>> tmp = new ArrayList<>();
for (Pair<VariableElement, Value> fieldVal : fieldValues) {
assert fieldVal.second instanceof CFValue;
tmp.add(Pair.of(fieldVal.first, (CFValue) fieldVal.second));
}
return (FlowAnalysis) new CFAnalysis(checker, (GenericAnnotatedTypeFactory) this, tmp);
}
use of org.checkerframework.javacutil.Pair in project checker-framework by typetools.
the class ContractsUtils method getPreconditions.
/**
* Returns the set of preconditions on the element {@code element}.
*/
public Set<Precondition> getPreconditions(Element element) {
Set<Precondition> result = new LinkedHashSet<>();
// Check for a single contract.
AnnotationMirror requiresAnnotation = factory.getDeclAnnotation(element, RequiresQualifier.class);
result.addAll(getPrecondition(requiresAnnotation));
// Check for multiple contracts.
AnnotationMirror requiresAnnotations = factory.getDeclAnnotation(element, RequiresQualifiers.class);
if (requiresAnnotations != null) {
List<AnnotationMirror> annotations = AnnotationUtils.getElementValueArray(requiresAnnotations, "value", AnnotationMirror.class, false);
for (AnnotationMirror a : annotations) {
result.addAll(getPrecondition(a));
}
}
// Check type-system specific annotations.
Class<PreconditionAnnotation> metaAnnotation = PreconditionAnnotation.class;
List<Pair<AnnotationMirror, AnnotationMirror>> declAnnotations = factory.getDeclAnnotationWithMetaAnnotation(element, metaAnnotation);
for (Pair<AnnotationMirror, AnnotationMirror> r : declAnnotations) {
AnnotationMirror anno = r.first;
AnnotationMirror metaAnno = r.second;
List<String> expressions = AnnotationUtils.getElementValueArray(anno, "value", String.class, false);
AnnotationMirror precondtionAnno = getAnnotationMirrorOfMetaAnnotation(metaAnno, anno);
if (precondtionAnno == null) {
continue;
}
for (String expr : expressions) {
result.add(new Precondition(expr, precondtionAnno));
}
}
return result;
}
use of org.checkerframework.javacutil.Pair in project checker-framework by typetools.
the class FlowExpressionParseUtil method parseArray.
private static Receiver parseArray(String s, FlowExpressionContext context, TreePath path) throws FlowExpressionParseException {
Pair<Pair<String, String>, String> array = parseArray(s);
if (array == null) {
return null;
}
String receiverStr = array.first.first;
String indexStr = array.first.second;
Receiver receiver = parseHelper(receiverStr, context, path);
FlowExpressionContext contextForIndex = context.copyAndUseOuterReceiver();
Receiver index = parseHelper(indexStr, contextForIndex, path);
TypeMirror receiverType = receiver.getType();
if (!(receiverType instanceof ArrayType)) {
throw constructParserException(s, String.format("receiver not an array: %s : %s", receiver, receiverType));
}
TypeMirror componentType = ((ArrayType) receiverType).getComponentType();
ArrayAccess result = new ArrayAccess(componentType, receiver, index);
return result;
}
Aggregations