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

Add a new fix to BoxedIdentityComparison #314

Closed
wants to merge 2 commits into from
Closed

Add a new fix to BoxedIdentityComparison #314

wants to merge 2 commits into from

Conversation

ghost
Copy link

@ghost ghost commented Dec 2, 2017

In cases where the LHS or RHS is definitely not null, the provided fix
should rewrite the == or != expression to a call to equals() on the
definitely-not-null side (negated if the original op is !=). This allows
a fix to be offered when the source level is 6 or earlier.

Also, NPECheck is enhanced with a "nullability of fields" user-configurable
preference which allows the user to customize whether certain fields
(specified by a fully-qualified name) are to be considered null, not
null, or possibly null by NPECheck. The BASE_NULLABILITY_OF_FIELDS map
can store such configuration for fields in the standard java.** and
javax.** packages.

This PR depends on #320 being merged first.

this.lhsIsReceiver = lhsIsReceiver;
BinaryTree bt = (BinaryTree) comparisonExprPath.getLeaf();
ExpressionTree receiver = (lhsIsReceiver ? bt.getLeftOperand() : bt.getRightOperand());
@SuppressWarnings("LocalVariableHidesMemberVariable")
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: unnecessary hide, makes the code less readable despite the @SuppressWarnings

Copy link
Author

Choose a reason for hiding this comment

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

Changed the local var name to baseReceiverString.

}
ExpressionTree ms = mk.MemberSelect(receiver, "equals");
ExpressionTree replace = mk.MethodInvocation(Collections.emptyList(), ms, Arrays.asList(lhsIsReceiver ? bt.getRightOperand() : bt.getLeftOperand()));
if (bt.getKind() == Tree.Kind.NOT_EQUAL_TO) {
Copy link
Member

Choose a reason for hiding this comment

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

this.invert ?

Copy link
Author

Choose a reason for hiding this comment

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

Done

if (!JavaFixUtilities.isPrimary(receiver)) {
receiver = mk.Parenthesized(receiver);
}
ExpressionTree ms = mk.MemberSelect(receiver, "equals");
Copy link
Member

Choose a reason for hiding this comment

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

// NOI18N mark comment missing

Copy link
Author

Choose a reason for hiding this comment

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

Done

ExpressionTree receiver = (lhsIsReceiver ? bt.getLeftOperand() : bt.getRightOperand());
@SuppressWarnings("LocalVariableHidesMemberVariable")
String receiverString = receiver.toString();
this.receiverString = (JavaFixUtilities.isPrimary(receiver) ? receiverString : "(" + receiverString + ")");
Copy link
Member

Choose a reason for hiding this comment

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

add // NOI18N

Copy link
Author

Choose a reason for hiding this comment

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

Done

* @return {@code true} iff {@code tree} can be used where a Primary is
* required.
*/
public static boolean isPrimary(@NonNull Tree tree) {
Copy link
Member

Choose a reason for hiding this comment

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

API is being changed, so I think that old good API change procedure should happen. See http://wiki.netbeans.org/API_Development; http://wiki.netbeans.org/VersioningPolicy
You need to bump up Specification version of the spi.java.hints, write relevant apichanges.xml entry. Add proper "since" javadoc tag to this added method.
You need to increase the required spi.java.hints spec version In module java.hints which uses this new API.

It's often better to separate API change(s) into their own PR, which should come first

Copy link
Author

Choose a reason for hiding this comment

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

I created PR #320 for the API change.

// This is specifically to make sure that the state of
// TRUE and FALSE static imports from java.lang.Boolean
// is NOT_NULL.
if (modifiers != null && modifiers.contains(Modifier.STATIC) && modifiers.contains(Modifier.FINAL)) {
Copy link
Member

Choose a reason for hiding this comment

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

I would be cautious to add rather broad-scope heuristics like this. It is rather necessary for the fix to work OK, but consider if some more restrictive condition would not be acceptable - e.g. just static final fields of primitive wrappers, or java.lang.* package.

With such rather broad scope, I'd like to see an UI option introduced - something like list of REs the FQN is matched against.

@jlahoda may have an opinion on this, too

@sdedic sdedic added the API Change [ci] enable extra API related tests label Dec 5, 2017
<change id="JavaFixUtilities.isPrimary">
<api name="JavaHintsSPI"/>
<summary>Added JavaFixUtilities.isPrimary() utility</summary>
<version major="1" minor="29"/>
Copy link
Contributor

@jtulach jtulach Jan 10, 2018

Choose a reason for hiding this comment

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

Nice to see the API change here! Shouldn't you guys also increase version in manifest.mf and reference it here? E.g. use 1.30?

Copy link
Author

Choose a reason for hiding this comment

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

Hello @jtulach. Thank you for your review.

I was a little confused by this; I figured that I needed to bump some sort of version number, but I found that the "spec.version.base" in spi.java.hints/nbproject/project.properties was already set to "1.30.0" in the project properties:

https://github.com/apache/incubator-netbeans/blob/dd5eb868ec5e8037c77118dbd5e2c53103f1c30e/spi.java.hints/nbproject/project.properties#L20

By the way, I have opened PR #320 to track this API change separately from the "Add a new fix to BoxedIdentityComparison" changes.

@sdedic sdedic removed the API Change [ci] enable extra API related tests label Jan 12, 2018
@vieiro
Copy link
Contributor

vieiro commented Jan 13, 2018

If these changes require #320, why not add these to #320? Having different interdependent PRs makes reviewing changes more complicated.

@ghost
Copy link
Author

ghost commented Jan 13, 2018

Hello @vieiro,

The "Code cleanup" label is not appropriate for this PR. This PR implements an enhancement to the BoxedIdentityComparison hint. Is there an "enhancement" label that could be used instead?

@ghost
Copy link
Author

ghost commented Jan 16, 2018

I have significantly overhauled the modifications to NPECheck, based on @sdedic's concern about the broad-scope heuristic that I was using in the previous iteration of this patch.

There is now a user-configurable "nullability of fields" preference, which allows the user to customize which fields (identified by their fully-qualified name) would be considered null, non-null, or possibly null by NPECheck. This mechanism also allows for a set of base mappings, stored in BASE_NULLABILITY_OF_FIELDS, that are referred to if the user has not specifically configured a field. Right now, I have only added mappings for java.lang.Boolean.TRUE and java.lang.Boolean.FALSE, but I will add a lot more if you all like this new approach.

I was also thinking about "nullability of method return values" which would allow the user to customize whether specifically-identified methods return null, non-null, or possibly null values. This will be slightly more complex to support than "nullability of fields", so I have not done this, but if you all like the "nullability of fields" idea, then I will certainly work on this extension.

@ghost
Copy link
Author

ghost commented Jan 16, 2018

By the way, to see the new UI for editing the "nullability of fields" preference, go to NetBeans > Preferences…. Click on the Editor tab, and then the Hints subtab. In the tree on the left, navigate to and click Probable Bugs > Null Pointer Dereference:
screen shot 2018-01-16 at 9 00 19 am

This utility method determines whether a Tree can be used in places
where a Primary is required (for instance, as the receiver expression of
a method invocation).
In cases where the LHS or RHS is definitely not null, the provided fix
should rewrite the == or != expression to a call to equals() on the
definitely-not-null side (negated if the original op is !=). This allows
a fix to be offered when the source level is 6 or earlier.

Also, NPECheck is enhanced with a "nullability of fields" user-configurable
preference which allows the user to customize whether certain fields
(specified by a fully-qualified name) are to be considered null, not
null, or possibly null by NPECheck. The BASE_NULLABILITY_OF_FIELDS map
can store such configuration for fields in the standard java.** and
javax.** packages.
@vieiro
Copy link
Contributor

vieiro commented Jan 19, 2018

Hi @dtrebbien is this ready for review?

@ghost
Copy link
Author

ghost commented Jan 19, 2018

Yes

@cowwoc
Copy link
Contributor

cowwoc commented Mar 16, 2018

@geertjanw Ready for review.

PS: Can you please look into granting everyone permission to request a review? Right now only a small number of people have permissions.

@matthiasblaesing
Copy link
Contributor

Closing this, as the requesting account was removed and the PR is stalled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants