-
Notifications
You must be signed in to change notification settings - Fork 300
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 support for static fields in contracts #1118
Add support for static fields in contracts #1118
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1118 +/- ##
============================================
+ Coverage 88.17% 88.26% +0.08%
- Complexity 2238 2259 +21
============================================
Files 85 85
Lines 7239 7302 +63
Branches 1439 1455 +16
============================================
+ Hits 6383 6445 +62
Misses 430 430
- Partials 426 427 +1 ☔ View full report in Codecov by Sentry. |
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.
Thanks a lot! I'm starting with a couple quick comments on the tests
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.
Looking good! A few more minor comments
return getReceiverFields(Nullness.NONNULL, false); | ||
} | ||
|
||
public Set<Element> getNonNullStaticReceiverFields() { |
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.
public Set<Element> getNonNullStaticReceiverFields() { | |
public Set<Element> getNonNullStaticFields() { |
No receiver for a static field
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.
Fixed!
@@ -278,7 +283,7 @@ public Set<Element> getNonNullReceiverFields() { | |||
* @param nullness The {@code Nullness} state | |||
* @return Set of fields (represented as {@code Element}s) with the given {@code nullness}. | |||
*/ | |||
public Set<Element> getReceiverFields(Nullness nullness) { | |||
public Set<Element> getReceiverFields(Nullness nullness, boolean staticOnly) { |
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.
I feel the code reuse here via adding the boolean parameter is not worth it; the method is no longer about receiver fields so it gets confusing. Maybe just implement the logic in getNonNullStaticFields()
, even though there will be a bit of code duplication.
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.
Fixed!
"Currently, @" | ||
+ annotName | ||
+ " does not support this. annotations for static fields. "; |
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.
The message can just be "Cannot reference to static field " + fieldName + " using this"
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.
Fixed!
@@ -85,11 +86,21 @@ protected boolean validateAnnotationSemantics( | |||
.stream() | |||
.map(e -> e.getSimpleName().toString()) | |||
.collect(Collectors.toSet()); | |||
Set<String> nonnullStaticFieldsOfReceiverAtExit = |
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.
Set<String> nonnullStaticFieldsOfReceiverAtExit = | |
Set<String> nonnullStaticFieldsAtExit = |
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.
Fixed!
.stream() | ||
.map(e -> e.getSimpleName().toString()) | ||
.collect(Collectors.toSet()); | ||
nonnullFieldsOfReceiverAtExit.addAll(nonnullStaticFieldsOfReceiverAtExit); |
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.
nonnullFieldsOfReceiverAtExit.addAll(nonnullStaticFieldsOfReceiverAtExit); | |
nonnullFieldsAtExit.addAll(nonnullStaticFieldsOfReceiverAtExit); |
They are not just on the receiver anymore
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.
Fixed!
AccessPath accessPath; | ||
if (field.getModifiers().contains(Modifier.STATIC)) { | ||
accessPath = AccessPath.fromStaticField(field); | ||
} else { | ||
accessPath = | ||
AccessPath.fromBaseAndElement(node.getTarget().getReceiver(), field, apContext); | ||
} |
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.
Might be simpler to just use a conditional expression, AccessPath accessPath = field.getModifiers().contains(Modifier.STATIC) ? ... : ...;
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.
Fixed!
AccessPath accessPath; | ||
|
||
if (field.getModifiers().contains(Modifier.STATIC)) { | ||
accessPath = AccessPath.fromStaticField(field); | ||
} else { | ||
accessPath = AccessPath.fromFieldElement(field); | ||
} |
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.
Again, use a conditional expression
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.
Fixed!
AccessPath accessPath; | ||
if (field.getModifiers().contains(Modifier.STATIC)) { | ||
accessPath = AccessPath.fromStaticField(field); | ||
} else { | ||
accessPath = AccessPath.fromFieldElement(field); | ||
} |
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.
conditional expression
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.
Fixed!
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.
Almost there; a few more comments
if (isStaticThisAnnotationField(classSymbol, fieldName)) { | ||
|
||
message = | ||
"Cannot reference to static field " |
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.
"Cannot reference to static field " | |
"Cannot refer to static field " |
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.
Fixed
} | ||
return null; | ||
} | ||
|
||
public boolean isStaticThisAnnotationField(Symbol.ClassSymbol classSymbol, String fieldName) { |
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.
Renames:
public boolean isStaticThisAnnotationField(Symbol.ClassSymbol classSymbol, String fieldName) { | |
public boolean isThisDotStaticField(Symbol.ClassSymbol classSymbol, String expression) { |
I suggest expression
since fieldName
might not be just a field name but could start with this.
.
Also can this method be private?
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.
@msridhar did the name change but we can't have this as private since we are using it RequiresNonNullHandler
to build the access path only if it is not this.
annotation. Otherwise we end up honoring this.
annotations through AP even though we raise a validation error (the issue you had raised in the first round of review).
Changed it to protected though.
Thanks for the contribution! |
This PR adds support for static fields in
@EnsureNonnull
,EnsureNonnullIf
,@RequiresNonnull
annotations. Currently the following code will throw validation errors (as well as the annotation handlers are unable to handle static fields). However, after this change, static fields for all three annotations are supportedFixes #431