-
Notifications
You must be signed in to change notification settings - Fork 19
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
Add lost qualifier to viewpointtest type checker #827
Changes from 31 commits
13e1697
0364e47
7ec7125
c859999
76a9f40
36905fb
7ea05ed
c31815d
3789eab
270c933
4151fce
c21d26f
744acc6
92ce1c5
5252e54
c879d46
5e8f6ff
2a1f9a2
1be71d0
ed98bf0
b9cf1db
a070489
bf37ee9
c27c02d
696c160
c56f67f
c541606
8fd3433
b0db749
7ba1549
71069b3
3970bbc
0fd471e
060894b
7b12191
1d1f938
249272b
4326a19
bbc07c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package viewpointtest; | ||
|
||
import org.checkerframework.framework.type.GenericAnnotatedTypeFactory; | ||
import org.checkerframework.framework.type.NoElementQualifierHierarchy; | ||
import org.checkerframework.framework.type.QualifierHierarchy; | ||
|
||
import java.lang.annotation.Annotation; | ||
import java.util.Collection; | ||
|
||
import javax.lang.model.element.AnnotationMirror; | ||
import javax.lang.model.util.Elements; | ||
|
||
import viewpointtest.quals.Bottom; | ||
import viewpointtest.quals.Lost; | ||
|
||
/** The {@link QualifierHierarchy} for the Viewpoint Test Checker. */ | ||
public class ViewpointTestQualifierHierarchy extends NoElementQualifierHierarchy { | ||
/** | ||
* Creates a ViewpointTestQualifierHierarchy from the given classes. | ||
* | ||
* @param qualifierClasses classes of annotations that are the qualifiers | ||
* @param elements element utils | ||
* @param atypeFactory the associated type factory | ||
*/ | ||
public ViewpointTestQualifierHierarchy( | ||
Collection<Class<? extends Annotation>> qualifierClasses, | ||
Elements elements, | ||
GenericAnnotatedTypeFactory<?, ?, ?, ?> atypeFactory) { | ||
super(qualifierClasses, elements, atypeFactory); | ||
} | ||
|
||
@Override | ||
public boolean isSubtypeQualifiers(AnnotationMirror subAnno, AnnotationMirror superAnno) { | ||
// Lost is not reflexive and the only subtype is Bottom | ||
Ao-senXiong marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (atypeFactory.areSameByClass(superAnno, Lost.class) | ||
&& !atypeFactory.areSameByClass(subAnno, Bottom.class)) { | ||
return false; | ||
} | ||
return super.isSubtypeQualifiers(subAnno, superAnno); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package viewpointtest; | ||
|
||
import com.sun.source.tree.NewClassTree; | ||
|
||
import org.checkerframework.common.basetype.BaseTypeChecker; | ||
import org.checkerframework.common.basetype.BaseTypeVisitor; | ||
import org.checkerframework.framework.type.AnnotatedTypeMirror; | ||
|
||
/** The visitor for the viewpointtest type-system. */ | ||
Ao-senXiong marked this conversation as resolved.
Show resolved
Hide resolved
|
||
public class ViewpointTestVisitor extends BaseTypeVisitor<ViewpointTestAnnotatedTypeFactory> { | ||
/** | ||
* Create a new ViewpointTestVisitor. | ||
* | ||
* @param checker the checker to which this visitor belongs | ||
*/ | ||
public ViewpointTestVisitor(BaseTypeChecker checker) { | ||
super(checker); | ||
} | ||
|
||
@Override | ||
public Void visitNewClass(NewClassTree tree, Void p) { | ||
AnnotatedTypeMirror Type = atypeFactory.getAnnotatedType(tree); | ||
if (Type.hasAnnotation(atypeFactory.TOP)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, how about |
||
checker.reportError(tree, "new.class.type.invalid", Type.getAnnotations()); | ||
} | ||
return super.visitNewClass(tree, p); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package viewpointtest.quals; | ||
|
||
import org.checkerframework.framework.qual.SubtypeOf; | ||
|
||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* The {@link Lost} qualifier indicates that a relationship cannot be expressed. It is the result of | ||
* viewpoint adaptation that combines {@link Top} and {@link ReceiverDependentQual}. | ||
* | ||
* <p>It is not reflexive in the subtyping relationship and the only subtype for {@link Lost} is | ||
* {@link Bottom}. | ||
*/ | ||
@Documented | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) | ||
@SubtypeOf({Top.class}) | ||
public @interface Lost {} | ||
Ao-senXiong marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import viewpointtest.quals.*; | ||
|
||
public class LostNonReflexive { | ||
@ReceiverDependentQual Object f; | ||
|
||
@SuppressWarnings({"inconsistent.constructor.type", "super.invocation.invalid"}) | ||
@ReceiverDependentQual LostNonReflexive(@ReceiverDependentQual Object args) {} | ||
|
||
@ReceiverDependentQual Object get() { | ||
return null; | ||
} | ||
|
||
void set(@ReceiverDependentQual Object o) {} | ||
|
||
void test(@Top LostNonReflexive obj, @Bottom Object bottomObj) { | ||
// :: error: (assignment.type.incompatible) | ||
this.f = obj.f; | ||
this.f = bottomObj; | ||
|
||
// :: error: (assignment.type.incompatible) | ||
@A Object aObj = obj.get(); | ||
// :: error: (assignment.type.incompatible) | ||
@B Object bObj = obj.get(); | ||
// :: error: (assignment.type.incompatible) | ||
@Bottom Object botObj = obj.get(); | ||
|
||
// :: error: (argument.type.incompatible) | ||
new LostNonReflexive(obj.f); | ||
new LostNonReflexive(bottomObj); | ||
|
||
// :: error: (argument.type.incompatible) | ||
this.set(obj.f); | ||
this.set(bottomObj); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,9 +3,10 @@ | |
public class PolyConstructor { | ||
|
||
static class MyClass { | ||
@SuppressWarnings({"inconsistent.constructor.type", "super.invocation.invalid"}) | ||
// :: error: (super.invocation.invalid) :: warning: (inconsistent.constructor.type) | ||
@PolyVP MyClass(@PolyVP Object o) { | ||
throw new RuntimeException(" * You are filled with DETERMINATION."); // stub | ||
// :: warning: (cast.unsafe.constructor.invocation) | ||
throw new @A RuntimeException(" * You are filled with DETERMINATION."); // stub | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the point of this change? Should there be multiple versions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I expand the test suite in here. |
||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,12 +10,14 @@ public class VarargsConstructor { | |
@ReceiverDependentQual VarargsConstructor(@ReceiverDependentQual Object... args) {} | ||
|
||
void foo() { | ||
VarargsConstructor a = new VarargsConstructor("testStr", new Object()); | ||
// :: warning: (cast.unsafe.constructor.invocation) | ||
VarargsConstructor a = new @A VarargsConstructor("testStr", new @A Object()); | ||
} | ||
|
||
void invokeConstructor(@A Object aObj, @B Object bObj, @Top Object topObj) { | ||
@A Object a = new @A VarargsConstructor(aObj); | ||
@B Object b = new @B VarargsConstructor(bObj); | ||
// :: error: (argument.type.incompatible) :: error: (new.class.type.invalid) | ||
@Top Object top = new @Top VarargsConstructor(topObj); | ||
Ao-senXiong marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// :: error: (argument.type.incompatible) | ||
new @A VarargsConstructor(bObj); | ||
|
@@ -29,14 +31,19 @@ class Inner { | |
|
||
void foo() { | ||
Inner a = new Inner(); | ||
Inner b = new Inner(new Object()); | ||
// :: error: (argument.type.incompatible) :: warning: | ||
// (cast.unsafe.constructor.invocation) | ||
Inner b = new Inner(new @A Object()); | ||
Inner c = VarargsConstructor.this.new Inner(); | ||
Inner d = VarargsConstructor.this.new Inner(new Object()); | ||
// :: error: (argument.type.incompatible) :: warning: | ||
// (cast.unsafe.constructor.invocation) | ||
Inner d = VarargsConstructor.this.new Inner(new @A Object()); | ||
} | ||
|
||
void invokeConstructor(@A Object aObj, @B Object bObj, @Top Object topObj) { | ||
@A Object a = new @A Inner(aObj); | ||
@B Object b = new @B Inner(bObj); | ||
// :: error: (argument.type.incompatible) :: error: (new.class.type.invalid) | ||
@Top Object top = new @Top Inner(topObj); | ||
// :: error: (argument.type.incompatible) | ||
new @A Inner(bObj); | ||
|
@@ -47,13 +54,17 @@ void invokeConstructor(@A Object aObj, @B Object bObj, @Top Object topObj) { | |
|
||
void testAnonymousClass(@A Object aObj, @B Object bObj, @Top Object topObj) { | ||
Object o = | ||
new VarargsConstructor("testStr", new Object()) { | ||
// :: warning: (cast.unsafe.constructor.invocation) | ||
new @A VarargsConstructor("testStr", new @A Object()) { | ||
void foo() { | ||
VarargsConstructor a = new VarargsConstructor("testStr", new Object()); | ||
VarargsConstructor a = | ||
// :: warning: (cast.unsafe.constructor.invocation) | ||
new @A VarargsConstructor("testStr", new @A Object()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this change illustrating something about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change is not about lost, I update this test case because I want those invalid invocation because previous we allow |
||
} | ||
}; | ||
@A Object a = new @A VarargsConstructor(aObj) {}; | ||
@B Object b = new @B VarargsConstructor(bObj) {}; | ||
// :: error: (argument.type.incompatible) :: error: (new.class.type.invalid) | ||
@Top Object top = new @Top VarargsConstructor(topObj) {}; | ||
// :: error: (argument.type.incompatible) | ||
new @A VarargsConstructor(bObj) {}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move this further down to other
type.invalid
error messages.While we're at it, can you improve the grammar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!