Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove implicit bottom checks #46

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 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
52 changes: 1 addition & 51 deletions src/main/java/universe/UniverseAnnotatedTypeFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,18 @@

import checkers.inference.BaseInferenceRealTypeFactory;

import com.sun.source.tree.BinaryTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.TypeCastTree;

import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType;
import org.checkerframework.framework.type.ViewpointAdapter;
import org.checkerframework.framework.type.treeannotator.ListTreeAnnotator;
import org.checkerframework.framework.type.treeannotator.LiteralTreeAnnotator;
import org.checkerframework.framework.type.treeannotator.PropagationTreeAnnotator;
import org.checkerframework.framework.type.treeannotator.TreeAnnotator;
import org.checkerframework.framework.type.typeannotator.DefaultForTypeAnnotator;
import org.checkerframework.javacutil.TreeUtils;

import universe.qual.Any;
Expand Down Expand Up @@ -71,7 +67,7 @@ protected ViewpointAdapter createViewpointAdapter() {
@Override
protected TreeAnnotator createTreeAnnotator() {
return new ListTreeAnnotator(
new UniversePropagationTreeAnnotator(this),
new PropagationTreeAnnotator(this),
new LiteralTreeAnnotator(this),
new UniverseTreeAnnotator());
}
Expand Down Expand Up @@ -137,50 +133,4 @@ public Void visitMethod(MethodTree node, AnnotatedTypeMirror p) {
return super.visitMethod(node, p);
}
}

private static class UniversePropagationTreeAnnotator extends PropagationTreeAnnotator {
/**
* Creates a {@link DefaultForTypeAnnotator} from the given checker, using that checker's
* type hierarchy.
*
* @param atypeFactory type factory to use
*/
public UniversePropagationTreeAnnotator(AnnotatedTypeFactory atypeFactory) {
super(atypeFactory);
}

/**
* Add immutable to the result type of a binary operation if the result type is implicitly
* immutable
*/
@Override
public Void visitBinary(BinaryTree node, AnnotatedTypeMirror type) {
applyImmutableIfImplicitlyBottom(
type); // Usually there isn't existing annotation on binary trees, but to be
// safe, run it first
super.visitBinary(node, type);
return null;
}

/** Add immutable to the result type of a cast if the result type is implicitly immutable */
@Override
public Void visitTypeCast(TypeCastTree node, AnnotatedTypeMirror type) {
applyImmutableIfImplicitlyBottom(
type); // Must run before calling super method to respect existing annotation
return super.visitTypeCast(node, type);
}

/**
* Because TreeAnnotator runs before DefaultForTypeAnnotator, implicitly immutable types are
* not guaranteed to always have immutable annotation. If this happens, we manually add
* immutable to type. We use addMissingAnnotations because we want to respect existing
* annotation on type
*/
private void applyImmutableIfImplicitlyBottom(AnnotatedTypeMirror type) {
if (UniverseTypeUtil.isImplicitlyBottomType(type)) {
type.addMissingAnnotations(
new HashSet<>(Arrays.asList(UniverseAnnotationMirrorHolder.BOTTOM)));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package universe;

import static universe.UniverseAnnotationMirrorHolder.ANY;
import static universe.UniverseAnnotationMirrorHolder.BOTTOM;
import static universe.UniverseAnnotationMirrorHolder.PEER;
import static universe.UniverseAnnotationMirrorHolder.REP;
import static universe.UniverseAnnotationMirrorHolder.SELF;
Expand All @@ -18,7 +17,6 @@

import com.sun.source.tree.BinaryTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.TypeCastTree;

import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
Expand Down Expand Up @@ -58,7 +56,7 @@ public UniverseInferenceAnnotatedTypeFactory(
public TreeAnnotator createTreeAnnotator() {
return new ListTreeAnnotator(
new LiteralTreeAnnotator(this),
new UniverseInferencePropagationTreeAnnotater(this),
new PropagationTreeAnnotator(this),
new InferenceTreeAnnotator(
this, realChecker, realTypeFactory, variableAnnotator, slotManager));
}
Expand Down Expand Up @@ -117,45 +115,6 @@ public void handleBinaryTree(AnnotatedTypeMirror atm, BinaryTree binaryTree) {
}
}

private static class UniverseInferencePropagationTreeAnnotater
extends PropagationTreeAnnotator {
public UniverseInferencePropagationTreeAnnotater(AnnotatedTypeFactory atypeFactory) {
super(atypeFactory);
}

@Override
public Void visitBinary(BinaryTree node, AnnotatedTypeMirror type) {
applyBottomIfImplicitlyBottom(
type); // Usually there isn't existing annotation on binary trees, but to be
// safe, run it first
return super.visitBinary(node, type);
}

@Override
public Void visitTypeCast(TypeCastTree node, AnnotatedTypeMirror type) {
applyBottomIfImplicitlyBottom(
type); // Must run before calling super method to respect existing annotation
if (type.isAnnotatedInHierarchy(ANY)) {
// VarAnnot is guarenteed to not exist on type, because PropagationTreeAnnotator has
// the highest previledge
// So VarAnnot hasn't been inserted to cast type yet.
UniverseTypeUtil.applyConstant(type, type.getAnnotationInHierarchy(ANY));
}
return super.visitTypeCast(node, type);
}

/**
* Because TreeAnnotator runs before ImplicitsTypeAnnotator, implicitly immutable types are
* not guaranteed to always have immutable annotation. If this happens, we manually add
* immutable to type.
*/
private void applyBottomIfImplicitlyBottom(AnnotatedTypeMirror type) {
if (UniverseTypeUtil.isImplicitlyBottomType(type)) {
UniverseTypeUtil.applyConstant(type, BOTTOM);
}
}
}

public static class UniverseInferenceViewpointAdapter extends InferenceViewpointAdapter {

public UniverseInferenceViewpointAdapter(AnnotatedTypeFactory atypeFactory) {
Expand Down
19 changes: 0 additions & 19 deletions src/main/java/universe/UniverseInferenceValidator.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package universe;

import static universe.UniverseAnnotationMirrorHolder.BOTTOM;
import static universe.UniverseAnnotationMirrorHolder.LOST;
import static universe.UniverseAnnotationMirrorHolder.REP;

Expand Down Expand Up @@ -39,9 +38,6 @@ public UniverseInferenceValidator(
*/
@Override
public Void visitDeclared(AnnotatedTypeMirror.AnnotatedDeclaredType type, Tree p) {
if (checkTopLevelDeclaredOrPrimitiveType) {
checkImplicitlyBottomTypeError(type, p);
}
checkStaticRepError(type, p);
// @Peer is allowed in static context

Expand Down Expand Up @@ -79,25 +75,10 @@ public Void visitArray(AnnotatedTypeMirror.AnnotatedArrayType type, Tree tree) {
return super.visitArray(type, tree);
}

@Override
public Void visitPrimitive(AnnotatedTypeMirror.AnnotatedPrimitiveType type, Tree tree) {
if (checkTopLevelDeclaredOrPrimitiveType) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check if inference validator has the proper logic

checkImplicitlyBottomTypeError(type, tree);
}
return super.visitPrimitive(type, tree);
}

private void checkStaticRepError(AnnotatedTypeMirror type, Tree tree) {
if (UniverseTypeUtil.inStaticScope(visitor.getCurrentPath())) {
((UniverseInferenceVisitor) visitor)
.doesNotContain(type, REP, "uts.static.rep.forbidden", tree);
}
}

private void checkImplicitlyBottomTypeError(AnnotatedTypeMirror type, Tree tree) {
if (UniverseTypeUtil.isImplicitlyBottomType(type)) {
((UniverseInferenceVisitor) visitor)
.effectiveIs(type, BOTTOM, "type.invalid.annotations.on.use", tree);
}
}
}
6 changes: 0 additions & 6 deletions src/main/java/universe/UniverseInferenceVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,6 @@ protected UniverseInferenceValidator createTypeValidator() {
return new UniverseInferenceValidator(checker, this, atypeFactory);
}

@Override
public boolean isValidUse(
AnnotatedDeclaredType declarationType, AnnotatedDeclaredType useType, Tree tree) {
return true;
}

/**
* Ignore constructor receiver annotations as result type of the constructor is always SELF for
* universe.
Expand Down
20 changes: 0 additions & 20 deletions src/main/java/universe/UniverseTypeValidator.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package universe;

import static universe.UniverseAnnotationMirrorHolder.BOTTOM;
import static universe.UniverseAnnotationMirrorHolder.LOST;
import static universe.UniverseAnnotationMirrorHolder.REP;

Expand Down Expand Up @@ -36,9 +35,6 @@ public UniverseTypeValidator(
*/
@Override
public Void visitDeclared(AnnotatedTypeMirror.AnnotatedDeclaredType type, Tree p) {
if (checkTopLevelDeclaredOrPrimitiveType) {
checkImplicitlyBottomTypeError(type, p);
}
checkStaticRepError(type, p);
// @Peer is allowed in static context

Expand Down Expand Up @@ -77,14 +73,6 @@ public Void visitArray(AnnotatedTypeMirror.AnnotatedArrayType type, Tree tree) {
return super.visitArray(type, tree);
}

@Override
public Void visitPrimitive(AnnotatedTypeMirror.AnnotatedPrimitiveType type, Tree tree) {
if (checkTopLevelDeclaredOrPrimitiveType) {
checkImplicitlyBottomTypeError(type, tree);
}
return super.visitPrimitive(type, tree);
}

private void checkStaticRepError(AnnotatedTypeMirror type, Tree tree) {
if (UniverseTypeUtil.inStaticScope(visitor.getCurrentPath())) {
if (AnnotatedTypes.containsModifier(type, REP)) {
Expand All @@ -93,12 +81,4 @@ private void checkStaticRepError(AnnotatedTypeMirror type, Tree tree) {
}
}
}

private void checkImplicitlyBottomTypeError(AnnotatedTypeMirror type, Tree tree) {
if (UniverseTypeUtil.isImplicitlyBottomType(type)) {
if (!type.hasAnnotation(BOTTOM)) {
reportInvalidAnnotationsOnUse(type, tree);
}
}
}
}
6 changes: 0 additions & 6 deletions src/main/java/universe/UniverseVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@ protected UniverseTypeValidator createTypeValidator() {
return new UniverseTypeValidator(checker, this, atypeFactory);
}

@Override
public boolean isValidUse(
AnnotatedDeclaredType declarationType, AnnotatedDeclaredType useType, Tree tree) {
return true;
}

/** Ignore method receiver annotations. */
@Override
protected void checkMethodInvocability(
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/universe/qual/Bottom.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.checkerframework.framework.qual.TargetLocations;
import org.checkerframework.framework.qual.TypeKind;
import org.checkerframework.framework.qual.TypeUseLocation;
import org.checkerframework.framework.qual.UpperBoundFor;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
Expand All @@ -25,6 +26,28 @@
@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND})
@SubtypeOf({Self.class, Rep.class})
@QualifierForLiterals({LiteralKind.ALL})
@UpperBoundFor(
typeKinds = {
TypeKind.INT,
TypeKind.BYTE,
TypeKind.SHORT,
TypeKind.BOOLEAN,
TypeKind.LONG,
TypeKind.CHAR,
TypeKind.FLOAT,
TypeKind.DOUBLE
},
types = {
String.class,
Double.class,
Boolean.class,
Byte.class,
Character.class,
Float.class,
Integer.class,
Long.class,
Short.class
})
@DefaultFor(
value = {TypeUseLocation.LOWER_BOUND},
typeKinds = {
Expand Down
3 changes: 2 additions & 1 deletion tests/inference/InvalidString.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

public class InvalidString {
void foo() {
throwException("" + Arrays.asList("", ""));
throwException("" + Arrays.asList("", "") + "");
throwException(3 + "");
}

void throwException(String s) {}
Expand Down