This is an automated email from the ASF dual-hosted git repository. jlahoda pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-netbeans.git
The following commit(s) were added to refs/heads/master by this push: new 3bb6c73 [NETBEANS-407] Using a special State to model instanceof instead of NOT_NULL_HYPOTHETICAL, as instanceof is not an explicit null test and may be false also for non-null input parameters. 3bb6c73 is described below commit 3bb6c7396a58ef75930148c30a3bb05baf0c06e6 Author: Jan Lahoda <jlah...@netbeans.org> AuthorDate: Sun Feb 25 20:41:54 2018 +0100 [NETBEANS-407] Using a special State to model instanceof instead of NOT_NULL_HYPOTHETICAL, as instanceof is not an explicit null test and may be false also for non-null input parameters. --- .../netbeans/modules/java/hints/bugs/NPECheck.java | 46 +++++++++++-------- .../modules/java/hints/bugs/NPECheckTest.java | 51 ++++++++++++++++++++++ 2 files changed, 79 insertions(+), 18 deletions(-) diff --git a/java.hints/src/org/netbeans/modules/java/hints/bugs/NPECheck.java b/java.hints/src/org/netbeans/modules/java/hints/bugs/NPECheck.java index b7b5af8..993e3e3 100644 --- a/java.hints/src/org/netbeans/modules/java/hints/bugs/NPECheck.java +++ b/java.hints/src/org/netbeans/modules/java/hints/bugs/NPECheck.java @@ -209,11 +209,13 @@ public class NPECheck { break; case POSSIBLE_NULL_REPORT: case POSSIBLE_NULL: + case INSTANCE_OF_FALSE: k = "ERR_UnboxingPotentialNullValue"; // NOI18N break; case NOT_NULL_BE_NPE: case NOT_NULL: case NOT_NULL_HYPOTHETICAL: + case INSTANCE_OF_TRUE: return null; default: throw new AssertionError(s.name()); @@ -238,7 +240,7 @@ public class NPECheck { return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), displayName); } - if (r == State.POSSIBLE_NULL_REPORT) { + if (r == State.POSSIBLE_NULL_REPORT || r == INSTANCE_OF_FALSE) { String displayName = NbBundle.getMessage(NPECheck.class, "ERR_PossiblyDereferencingNull"); return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), displayName); @@ -259,7 +261,7 @@ public class NPECheck { return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), displayName); } - if (r == State.POSSIBLE_NULL_REPORT) { + if (r == State.POSSIBLE_NULL_REPORT || r == State.INSTANCE_OF_FALSE) { String displayName = NbBundle.getMessage(NPECheck.class, "ERR_PossiblyDereferencingNull"); return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), displayName); @@ -278,7 +280,7 @@ public class NPECheck { return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), displayName); } - if (r == State.POSSIBLE_NULL_REPORT) { + if (r == State.POSSIBLE_NULL_REPORT || r == State.INSTANCE_OF_FALSE) { String displayName = NbBundle.getMessage(NPECheck.class, "ERR_PossiblyDereferencingNull"); return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), displayName); @@ -327,6 +329,7 @@ public class NPECheck { result.add(ErrorDescriptionFactory.forTree(ctx, mit.getArguments().get(index), NbBundle.getMessage(NPECheck.class, "ERR_NULL_TO_NON_NULL_ARG"))); break; case POSSIBLE_NULL_REPORT: + case INSTANCE_OF_FALSE: result.add(ErrorDescriptionFactory.forTree(ctx, mit.getArguments().get(index), NbBundle.getMessage(NPECheck.class, "ERR_POSSIBLENULL_TO_NON_NULL_ARG"))); break; } @@ -455,6 +458,7 @@ public class NPECheck { if (expected.isNotNull()) key = "ERR_ReturningNullFromNonNull"; break; case POSSIBLE_NULL_REPORT: + case INSTANCE_OF_FALSE: if (expected.isNotNull()) key = "ERR_ReturningPossibleNullFromNonNull"; break; } @@ -717,7 +721,7 @@ public class NPECheck { State expr = scan(node.getExpression(), p); boolean wasNPE = false; - if (expr == State.NULL || expr == State.NULL_HYPOTHETICAL || expr == State.POSSIBLE_NULL || expr == State.POSSIBLE_NULL_REPORT) { + if (expr == State.NULL || expr == State.NULL_HYPOTHETICAL || expr == State.POSSIBLE_NULL || expr == State.POSSIBLE_NULL_REPORT || expr == State.INSTANCE_OF_FALSE) { wasNPE = true; } @@ -886,8 +890,17 @@ public class NPECheck { Element e = info.getTrees().getElement(new TreePath(getCurrentPath(), node.getExpression())); - if (isVariableElement(e) && (variable2State.get((VariableElement) e) == null || !variable2State.get((VariableElement) e).isNotNull()) && !not) { - variable2State.put((VariableElement) e, State.NOT_NULL_HYPOTHETICAL); + if (isVariableElement(e)) { + boolean setState = false; + State currentState = variable2State.get((VariableElement) e); + if (currentState == null) { + setState = !getStateFromAnnotations(info, e).isNotNull(); + } else { + setState = !variable2State.get((VariableElement) e).isNotNull(); + } + if (setState) { + variable2State.put((VariableElement) e, not ? State.INSTANCE_OF_FALSE : State.INSTANCE_OF_TRUE); + } } return null; @@ -1479,7 +1492,7 @@ public class NPECheck { for (Entry<VariableElement, State> e : backup.entrySet()) { State t = e.getValue(); - if (t != null && t != State.NOT_NULL_HYPOTHETICAL && t != NULL_HYPOTHETICAL) { + if (t != null && t != State.NOT_NULL_HYPOTHETICAL && t != NULL_HYPOTHETICAL && t != INSTANCE_OF_TRUE && t != INSTANCE_OF_FALSE) { variable2State.put(e.getKey(), t); } } @@ -1495,15 +1508,6 @@ public class NPECheck { return NPECheck.isVariableElement(ctx, ve); } - private void clearHypothetical() { - for (Iterator<Entry<VariableElement, State>> it = variable2State.entrySet().iterator(); it.hasNext();) { - Entry<VariableElement, State> e = it.next(); - - if (e.getValue() == State.NOT_NULL_HYPOTHETICAL || e.getValue() == State.NULL_HYPOTHETICAL) { - it.remove(); - } - } - } } static enum State { @@ -1511,8 +1515,10 @@ public class NPECheck { NULL_HYPOTHETICAL, POSSIBLE_NULL, POSSIBLE_NULL_REPORT, + INSTANCE_OF_FALSE, NOT_NULL, NOT_NULL_HYPOTHETICAL, + INSTANCE_OF_TRUE, NOT_NULL_BE_NPE; public @CheckForNull State reverse() { @@ -1521,6 +1527,8 @@ public class NPECheck { return NOT_NULL; case NULL_HYPOTHETICAL: return NOT_NULL_HYPOTHETICAL; + case INSTANCE_OF_FALSE: + return INSTANCE_OF_TRUE; case POSSIBLE_NULL: case POSSIBLE_NULL_REPORT: return this; @@ -1529,18 +1537,20 @@ public class NPECheck { return NULL; case NOT_NULL_HYPOTHETICAL: return NULL_HYPOTHETICAL; + case INSTANCE_OF_TRUE: + return INSTANCE_OF_FALSE; default: throw new IllegalStateException(); } } public boolean isNotNull() { - return this == NOT_NULL || this == NOT_NULL_BE_NPE || this == NOT_NULL_HYPOTHETICAL; + return this == NOT_NULL || this == NOT_NULL_BE_NPE || this == NOT_NULL_HYPOTHETICAL || this == INSTANCE_OF_TRUE; } public static State collect(State s1, State s2) { if (s1 == s2) return s1; if (s1 == NULL || s2 == NULL || s1 == NULL_HYPOTHETICAL || s2 == NULL_HYPOTHETICAL) return POSSIBLE_NULL_REPORT; - if (s1 == POSSIBLE_NULL_REPORT || s2 == POSSIBLE_NULL_REPORT) return POSSIBLE_NULL_REPORT; + if (s1 == POSSIBLE_NULL_REPORT || s2 == POSSIBLE_NULL_REPORT || s2 == INSTANCE_OF_FALSE) return POSSIBLE_NULL_REPORT; if (s1 != null && s2 != null && s1.isNotNull() && s2.isNotNull()) return NOT_NULL; return POSSIBLE_NULL; diff --git a/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/NPECheckTest.java b/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/NPECheckTest.java index 185f9e3..ae14345 100644 --- a/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/NPECheckTest.java +++ b/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/NPECheckTest.java @@ -1645,6 +1645,57 @@ public class NPECheckTest extends NbTestCase { .assertWarnings("17:19-17:23:verifier:ERR_ReturningNullFromNonNull"); } + public void testNETBEANS407a() throws Exception { + HintTest.create() + .input("package test;\n" + + "public class Test {\n" + + " public void test(Object o) {\n" + + " boolean b1 = o instanceof Integer;\n" + + " boolean b2 = o instanceof Integer && o != null;\n" + + " System.out.println(o.toString());\n" + + " }\n" + + "}") + .run(NPECheck.class) + .assertWarnings("4:41-4:50:verifier:ERR_NotNull"); + } + + public void testNETBEANS407b() throws Exception { + HintTest.create() + .input("package test;\n" + + "public class Test {\n" + + " public void test(Object o) {\n" + + " boolean b = !(o instanceof Integer) && o.toString() != null;\n" + + " }\n" + + "}") + .run(NPECheck.class) + .assertWarnings("3:45-3:53:verifier:Possibly Dereferencing null"); + } + + public void testNETBEANS407c() throws Exception { + HintTest.create() + .input("package test;\n" + + "public class Test {\n" + + " public void test(Object o) {\n" + + " boolean b = o != null;\n" + + " System.out.println(o.toString());\n" + + " }\n" + + "}") + .run(NPECheck.class) + .assertWarnings("4:25-4:33:verifier:Possibly Dereferencing null"); + } + + public void testNETBEANS407d() throws Exception { + HintTest.create() + .input("package test;\n" + + "public class Test {\n" + + " public void test(Object o) {\n" + + " boolean b = (o == null || o == \"\") && o.toString() != null;\n" + + " }\n" + + "}") + .run(NPECheck.class) + .assertWarnings("3:44-3:52:verifier:Possibly Dereferencing null"); + } + private void performAnalysisTest(String fileName, String code, String... golden) throws Exception { HintTest.create() .input(fileName, code) -- To stop receiving notification emails like this one, please contact jlah...@apache.org. --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists