-
Notifications
You must be signed in to change notification settings - Fork 357
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
Issue error if top is used in a contract annotation #6429
Open
mernst
wants to merge
7
commits into
typetools:master
Choose a base branch
from
mernst:warn-contract-refinement-to-top-2
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
0fc6a61
Issue error if top is used in a contract annotation
mernst 4f5e623
Add tests
mernst 0e1c6bb
Remove MethodTree argument
mernst 4155568
Undo changes
mernst f95f5a5
Undo changes
mernst 84dfc62
Add Javadoc
mernst 50bfa01
Merge ../checker-framework-branch-master into warn-contract-refinemen…
mernst File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ | |
import org.checkerframework.javacutil.AnnotationBuilder; | ||
import org.checkerframework.javacutil.AnnotationUtils; | ||
import org.checkerframework.javacutil.TreeUtils; | ||
import org.checkerframework.javacutil.TypeSystemError; | ||
import org.plumelib.util.IPair; | ||
|
||
/** | ||
|
@@ -121,6 +122,7 @@ public Set<Contract.ConditionalPostcondition> getConditionalPostconditions( | |
private <T extends Contract> Set<T> getContractsOfKind( | ||
ExecutableElement executableElement, Contract.Kind kind, Class<T> clazz) { | ||
Set<T> result = new LinkedHashSet<>(); | ||
|
||
// Check for a single framework-defined contract annotation. | ||
// The result is RequiresQualifier, EnsuresQualifier, EnsuresQualifierIf, or null. | ||
AnnotationMirror frameworkContractAnno = | ||
|
@@ -140,6 +142,27 @@ private <T extends Contract> Set<T> getContractsOfKind( | |
} | ||
} | ||
|
||
// At this point, `result` contains only framework-defined contract annotations. | ||
Set<AnnotationMirror> tops = factory.getQualifierHierarchy().getTopAnnotations(); | ||
for (T contract : result) { | ||
AnnotationMirror anno = contract.annotation; | ||
if (AnnotationUtils.containsSame(tops, anno)) { | ||
// TODO: issue a warning on the annotation itself rather than on the method declaration. | ||
// This requires iterating over the annotation trees on the method declaration to determine | ||
// which one led tho the given AnnotationMirror. | ||
if (executableElement != null) { | ||
String methodString = " on method " + executableElement.getSimpleName(); | ||
factory | ||
.getChecker() | ||
.reportWarning( | ||
executableElement, | ||
"contracts.toptype", | ||
anno, | ||
contract.contractAnnotation + methodString); | ||
} | ||
} | ||
} | ||
|
||
// Check for type-system specific annotations. These are the annotations that are | ||
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. It's strange that this code is reading the meta-annotations every time it encounters a declaration annotation rather than just when the checker is initialized. I want to rewrite this. |
||
// meta-annotated by `kind.metaAnnotation`, which is PreconditionAnnotation, | ||
// PostconditionAnnotation, or ConditionalPostconditionAnnotation. | ||
|
@@ -155,6 +178,17 @@ private <T extends Contract> Set<T> getContractsOfKind( | |
if (enforcedQualifier == null) { | ||
continue; | ||
} | ||
if (AnnotationUtils.containsSame(tops, enforcedQualifier)) { | ||
// TODO: Unfortunately, TypeSystemError does not permit giving a tree at which to issue the | ||
// error. Obtain the file and line number from the tree, and print them here. | ||
// TODO: Issue a warning on the annotation itself rather than on the method declaration. | ||
// This requires iterating over the annotation trees on the method declaration to determine | ||
// which one led tho the given AnnotationMirror. | ||
throw new TypeSystemError( | ||
"Contract annotation %s on method %s uses the top qualifier %s, which has no effect.", | ||
contractAnno, executableElement.getSimpleName(), enforcedQualifier); | ||
} | ||
|
||
List<String> expressions = factory.getContractExpressions(kind, anno); | ||
Collections.sort(expressions); | ||
Boolean ensuresQualifierIfResult = factory.getEnsuresQualifierIfResult(kind, anno); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Warnings should only be issued in the BaseTypeVisitor. Specifically, this code belongs in
BaseTypeVisitor#checkContractsAtMethodDeclaration
.