Skip to content
Open
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 78 additions & 34 deletions src/checkers/inference/VariableAnnotator.java
Original file line number Diff line number Diff line change
Expand Up @@ -748,32 +748,91 @@ private boolean handleWasRawDeclaredTypes(AnnotatedDeclaredType adt) {
/**
* Visit the extends, implements, and type parameters of the given class type and tree.
*/
private void handleClassDeclaration(AnnotatedDeclaredType classType, ClassTree classTree) {
protected void handleClassDeclaration(AnnotatedDeclaredType classType, ClassTree classTree) {
handleExtendsAndImplementsClause(classType, classTree);

if (InferenceMain.isHackMode(
(classType.getTypeArguments().size() != classTree.getTypeParameters().size()))) {
return;
}

visitTogether(classType.getTypeArguments(), classTree.getTypeParameters());

VariableSlot varSlot = getOrCreateDeclBound(classType);
classType.addAnnotation(slotManager.getAnnotation(varSlot));

// before we were relying on trees but the ClassTree has it's type args erased
// when the compiler moves on to the next class
Element classElement = classType.getUnderlyingType().asElement();
storeElementType(classElement, classType);

}

/**
* Defines how extends and implicit clause is visited during {@code handleClassDeclaration}
* @param classType the type of the class
* @param classTree the tree of the class
*/
protected void handleExtendsAndImplementsClause(AnnotatedDeclaredType classType, ClassTree classTree) {
handleExtendsClause(classType, classTree);
handleImplementsClause(classType, classTree);
}

/**
* Defines how extends clause is visited during {@code handleClassDeclaration}
* @param classType the type of the class
* @param classTree the tree of the class
*/
protected void handleExtendsClause(AnnotatedDeclaredType classType, ClassTree classTree) {
final Tree extendsTree = classTree.getExtendsClause();
if (extendsTree == null) {
// Annotated the implicit extends.
Element classElement = classType.getUnderlyingType().asElement();
VariableSlot extendsSlot;
if (!extendsMissingTrees.containsKey(classElement)) {
// TODO: SEE COMMENT ON createImpliedExtendsLocation
AnnotationLocation location = createImpliedExtendsLocation(classTree);
extendsSlot = createVariable(location);
extendsMissingTrees.put(classElement, extendsSlot);
logger.fine("Created variable for implicit extends on class:\n" +
extendsSlot.getId() + " => " + classElement + " (extends Object)");
handleImplicitExtends(classType, classTree);

} else {
// Add annotation
extendsSlot = extendsMissingTrees.get(classElement);
}
List<AnnotatedDeclaredType> superTypes = classType.directSuperTypes();
superTypes.get(0).replaceAnnotation(slotManager.getAnnotation(extendsSlot));
} else {
handleExplicitExtends(extendsTree);
}
}

/**
* Defines how implicit extends clause ({@code extends Object}) is visited during {@code handleClassDeclaration}
* @param classType the type of the class
* @param classTree the tree of the class
*/
protected void handleImplicitExtends(AnnotatedDeclaredType classType, ClassTree classTree) {
// Annotated the implicit extends.
Element classElement = classType.getUnderlyingType().asElement();
VariableSlot extendsSlot;
if (!extendsMissingTrees.containsKey(classElement)) {
// TODO: SEE COMMENT ON createImpliedExtendsLocation
AnnotationLocation location = createImpliedExtendsLocation(classTree);
extendsSlot = createVariable(location);
extendsMissingTrees.put(classElement, extendsSlot);
logger.fine("Created variable for implicit extends on class:\n" +
extendsSlot.getId() + " => " + classElement + " (extends Object)");

} else {
final AnnotatedTypeMirror extendsType = inferenceTypeFactory.getAnnotatedTypeFromTypeTree(extendsTree);
visit(extendsType, extendsTree);
// Add annotation
extendsSlot = extendsMissingTrees.get(classElement);
}
List<AnnotatedDeclaredType> superTypes = classType.directSuperTypes();
superTypes.get(0).replaceAnnotation(slotManager.getAnnotation(extendsSlot));
}

/**
* Defines how explicit extends clause is visited during {@code handleClassDeclaration}
* @param extendsTree the extends tree from the class declaration
*/
protected void handleExplicitExtends(Tree extendsTree) {
final AnnotatedTypeMirror extendsType = inferenceTypeFactory.getAnnotatedTypeFromTypeTree(extendsTree);
visit(extendsType, extendsTree);
}

/**
* Defines how implements clause is visited during {@code handleClassDeclaration}
* @param classType the type of the class
* @param classTree the tree of the class
*/
protected void handleImplementsClause(AnnotatedDeclaredType classType, ClassTree classTree) {
// // TODO: NOT SURE THIS HANDLES MEMBER SELECT CORRECTLY
// int interfaceIndex = 1;
// for(Tree implementsTree : classTree.getImplementsClause()) {
Expand All @@ -783,21 +842,6 @@ private void handleClassDeclaration(AnnotatedDeclaredType classType, ClassTree c
// visit(supertype, implementsTree);
// interfaceIndex++;
// }
//
if (InferenceMain.isHackMode(
(classType.getTypeArguments().size() != classTree.getTypeParameters().size()))) {
return;
}

visitTogether(classType.getTypeArguments(), classTree.getTypeParameters());

VariableSlot varSlot = getOrCreateDeclBound(classType);
classType.addAnnotation(slotManager.getAnnotation(varSlot));

// before we were relying on trees but the ClassTree has it's type args erased
// when the compiler moves on to the next class
Element classElement = classType.getUnderlyingType().asElement();
storeElementType(classElement, classType);

}

Expand Down