Updating NPECheck hint to current hint SPI.
1.1 --- a/javahints/src/org/netbeans/modules/javahints/Bundle.properties Thu Apr 19 21:04:16 2012 +0200
1.2 +++ b/javahints/src/org/netbeans/modules/javahints/Bundle.properties Thu Apr 19 22:19:53 2012 +0200
1.3 @@ -130,6 +130,8 @@
1.4 FIX_ConvertAnonymousToInner=Convert Anonymous to Inner
1.5
1.6
1.7 +DN_NPECheck=Null Dereference
1.8 +DESC_NPECheck=Checks various problems related to dereferencing nulls
1.9 ERR_DereferencingNull=Dereferencing null
1.10 ERR_PossiblyDereferencingNull=Possibly Dereferencing null
1.11 ERR_AssigningNullToNotNull=Assigning Null to NotNull Variable
2.1 --- a/javahints/src/org/netbeans/modules/javahints/NPECheck.java Thu Apr 19 21:04:16 2012 +0200
2.2 +++ b/javahints/src/org/netbeans/modules/javahints/NPECheck.java Thu Apr 19 22:19:53 2012 +0200
2.3 @@ -1,7 +1,7 @@
2.4 /*
2.5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2.6 *
2.7 - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
2.8 + * Copyright 1997-2012 Sun Microsystems, Inc. All rights reserved.
2.9 *
2.10 * The contents of this file are subject to the terms of either the GNU
2.11 * General Public License Version 2 only ("GPL") or the Common
2.12 @@ -23,36 +23,20 @@
2.13 *
2.14 * Contributor(s):
2.15 *
2.16 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
2.17 + * Portions Copyrighted 2007-2012 Sun Microsystems, Inc.
2.18 */
2.19
2.20 package org.netbeans.modules.javahints;
2.21
2.22 -import com.sun.source.tree.AssignmentTree;
2.23 -import com.sun.source.tree.BinaryTree;
2.24 -import com.sun.source.tree.BreakTree;
2.25 -import com.sun.source.tree.ClassTree;
2.26 -import com.sun.source.tree.ConditionalExpressionTree;
2.27 -import com.sun.source.tree.ContinueTree;
2.28 -import com.sun.source.tree.IdentifierTree;
2.29 -import com.sun.source.tree.IfTree;
2.30 -import com.sun.source.tree.LiteralTree;
2.31 -import com.sun.source.tree.MemberSelectTree;
2.32 -import com.sun.source.tree.MethodInvocationTree;
2.33 -import com.sun.source.tree.NewClassTree;
2.34 -import com.sun.source.tree.ReturnTree;
2.35 -import com.sun.source.tree.ThrowTree;
2.36 -import com.sun.source.tree.Tree;
2.37 +import com.sun.source.tree.*;
2.38 import com.sun.source.tree.Tree.Kind;
2.39 -import com.sun.source.tree.VariableTree;
2.40 -import com.sun.source.tree.WhileLoopTree;
2.41 import com.sun.source.util.TreePath;
2.42 import com.sun.source.util.TreePathScanner;
2.43 import java.util.ArrayList;
2.44 import java.util.EnumSet;
2.45 import java.util.HashMap;
2.46 import java.util.HashSet;
2.47 -import java.util.LinkedList;
2.48 +import java.util.IdentityHashMap;
2.49 import java.util.List;
2.50 import java.util.Map;
2.51 import java.util.Map.Entry;
2.52 @@ -64,75 +48,172 @@
2.53 import javax.lang.model.element.TypeElement;
2.54 import javax.lang.model.element.VariableElement;
2.55 import org.netbeans.api.java.source.CompilationInfo;
2.56 -import org.netbeans.modules.java.hints.spi.AbstractHint;
2.57 -import org.netbeans.modules.java.hints.spi.support.FixFactory;
2.58 import org.netbeans.spi.editor.hints.ErrorDescription;
2.59 -import org.netbeans.spi.editor.hints.ErrorDescriptionFactory;
2.60 -import org.netbeans.spi.editor.hints.Fix;
2.61 import org.openide.util.NbBundle;
2.62
2.63 import static org.netbeans.modules.javahints.NPECheck.State.*;
2.64 +import org.netbeans.spi.java.hints.*;
2.65
2.66 -/**
2.67 +/**XXX: null initializer to a non-null variable!
2.68 *
2.69 * @author lahvac
2.70 */
2.71 -public class NPECheck extends AbstractHint {
2.72 +@Hint(displayName="#DN_NPECheck", description="#DESC_NPECheck", category="bugs", enabled=false)
2.73 +public class NPECheck {
2.74
2.75 - public NPECheck() {
2.76 - super(false, true, HintSeverity.WARNING, "null");
2.77 + @TriggerPattern("$var = $expr")
2.78 + public static ErrorDescription assignment(HintContext ctx) {
2.79 + Element e = ctx.getInfo().getTrees().getElement(ctx.getVariables().get("$var"));
2.80 +
2.81 + if (e == null || !VARIABLE_ELEMENT.contains(e.getKind())) {
2.82 + return null;
2.83 + }
2.84 +
2.85 + TreePath expr = ctx.getVariables().get("$expr");
2.86 + State r = computeExpressionsState(ctx.getInfo()).get(expr.getLeaf());
2.87 +
2.88 + State elementState = getStateFromAnnotations(e);
2.89 +
2.90 + if (elementState != null && elementState.isNotNull()) {
2.91 + String key = null;
2.92 +
2.93 + if (r == NULL) {
2.94 + key = "ERR_AssigningNullToNotNull";
2.95 + }
2.96 +
2.97 + if (r == POSSIBLE_NULL_REPORT) {
2.98 + key = "ERR_PossibleAssigingNullToNotNull";
2.99 + }
2.100 +
2.101 + if (key != null) {
2.102 + return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), NbBundle.getMessage(NPECheck.class, key));
2.103 + }
2.104 + }
2.105 +
2.106 + return null;
2.107 + }
2.108 +
2.109 + @TriggerPattern("$select.$variable")
2.110 + public static ErrorDescription memberSelect(HintContext ctx) {
2.111 + TreePath select = ctx.getVariables().get("$select");
2.112 + State r = computeExpressionsState(ctx.getInfo()).get(select.getLeaf());
2.113 +
2.114 + if (r == State.NULL) {
2.115 + String displayName = NbBundle.getMessage(NPECheck.class, "ERR_DereferencingNull");
2.116 +
2.117 + return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), displayName);
2.118 + }
2.119 +
2.120 + if (r == State.POSSIBLE_NULL_REPORT) {
2.121 + String displayName = NbBundle.getMessage(NPECheck.class, "ERR_PossiblyDereferencingNull");
2.122 +
2.123 + return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), displayName);
2.124 + }
2.125 +
2.126 + return null;
2.127 + }
2.128 +
2.129 + @TriggerTreeKind(Kind.METHOD_INVOCATION)
2.130 + public static List<ErrorDescription> methodInvocation(HintContext ctx) {
2.131 + MethodInvocationTree mit = (MethodInvocationTree) ctx.getPath().getLeaf();
2.132 + List<State> paramStates = new ArrayList<State>(mit.getArguments().size());
2.133 + Map<Tree, State> expressionsState = computeExpressionsState(ctx.getInfo());
2.134 +
2.135 + for (Tree param : mit.getArguments()) {
2.136 + State r = expressionsState.get(param);
2.137 + paramStates.add(r != null ? r : State.POSSIBLE_NULL);
2.138 + }
2.139 +
2.140 + Element e = ctx.getInfo().getTrees().getElement(ctx.getPath());
2.141 +
2.142 + if (e == null || e.getKind() != ElementKind.METHOD) {
2.143 + return null;
2.144 + }
2.145 +
2.146 + ExecutableElement ee = (ExecutableElement) e;
2.147 + int index = 0;
2.148 + List<ErrorDescription> result = new ArrayList<ErrorDescription>();
2.149 +
2.150 + for (VariableElement param : ee.getParameters()) {
2.151 + if (getStateFromAnnotations(param) == NOT_NULL) {
2.152 + switch (paramStates.get(index)) {
2.153 + case NULL:
2.154 + result.add(ErrorDescriptionFactory.forTree(ctx, mit.getArguments().get(index), NbBundle.getMessage(NPECheck.class, "ERR_NULL_TO_NON_NULL_ARG")));
2.155 + break;
2.156 + case POSSIBLE_NULL_REPORT:
2.157 + result.add(ErrorDescriptionFactory.forTree(ctx, mit.getArguments().get(index), NbBundle.getMessage(NPECheck.class, "ERR_POSSIBLENULL_TO_NON_NULL_ARG")));
2.158 + break;
2.159 + }
2.160 + }
2.161 + }
2.162 +
2.163 + return result;
2.164 + }
2.165 +
2.166 + private static final Object KEY_EXPRESSION_STATE = new Object();
2.167 + //Cancelling:
2.168 + private static Map<Tree, State> computeExpressionsState(CompilationInfo info) {
2.169 + Map<Tree, State> result = (Map<Tree, State>) info.getCachedValue(KEY_EXPRESSION_STATE);
2.170 +
2.171 + if (result != null) {
2.172 + return result;
2.173 + }
2.174 +
2.175 + VisitorImpl v = new VisitorImpl(info);
2.176 +
2.177 + v.scan(info.getCompilationUnit(), null);
2.178 +
2.179 + info.putCachedValue(KEY_EXPRESSION_STATE, result = v.expressionState, CompilationInfo.CacheClearPolicy.ON_TASK_END);
2.180 +
2.181 + return result;
2.182 + }
2.183 +
2.184 + private static State getStateFromAnnotations(Element e) {
2.185 + return getStateFromAnnotations(e, State.POSSIBLE_NULL);
2.186 }
2.187
2.188 - @Override
2.189 - public String getDescription() {
2.190 - return "NPE";
2.191 + private static State getStateFromAnnotations(Element e, State def) {
2.192 + for (AnnotationMirror am : e.getAnnotationMirrors()) {
2.193 + String simpleName = ((TypeElement) am.getAnnotationType().asElement()).getSimpleName().toString();
2.194 +
2.195 + if ("Nullable".equals(simpleName) || "NullAllowed".equals(simpleName)) {
2.196 + return State.POSSIBLE_NULL_REPORT;
2.197 + }
2.198 +
2.199 + if ("CheckForNull".equals(simpleName)) {
2.200 + return State.POSSIBLE_NULL_REPORT;
2.201 + }
2.202 +
2.203 + if ("NotNull".equals(simpleName) || "NonNull".equals(simpleName)) {
2.204 + return State.NOT_NULL;
2.205 + }
2.206 + }
2.207 +
2.208 + return def;
2.209 }
2.210 -
2.211 - public Set<Kind> getTreeKinds() {
2.212 - return EnumSet.of(Kind.METHOD);
2.213 - }
2.214 -
2.215 - public List<ErrorDescription> run(CompilationInfo compilationInfo, TreePath treePath) {
2.216 - VisitorImpl v = new VisitorImpl(compilationInfo);
2.217
2.218 - v.scan(treePath, null);
2.219 + private static final class VisitorImpl extends TreePathScanner<State, Void> {
2.220
2.221 - return v.warnings;
2.222 - }
2.223 -
2.224 - public String getId() {
2.225 - return NPECheck.class.getName();
2.226 - }
2.227 -
2.228 - public String getDisplayName() {
2.229 - return "NPE";
2.230 - }
2.231 -
2.232 - public void cancel() {
2.233 - }
2.234 -
2.235 - private final class VisitorImpl extends TreePathScanner<State, Void> {
2.236 -
2.237 - private CompilationInfo info;
2.238 - private List<ErrorDescription> warnings;
2.239 -
2.240 + private final CompilationInfo info;
2.241 private Map<VariableElement, State> variable2State = new HashMap<VariableElement, NPECheck.State>();
2.242 private Map<VariableElement, State> testedTo = new HashMap<VariableElement, NPECheck.State>();
2.243 + private final Map<Tree, State> expressionState = new IdentityHashMap<Tree, State>();
2.244
2.245 public VisitorImpl(CompilationInfo info) {
2.246 this.info = info;
2.247 - this.warnings = new LinkedList<ErrorDescription>();
2.248 }
2.249
2.250 - private void report(TreePath path, String key) {
2.251 - long start = info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), path.getLeaf());
2.252 - long end = info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), path.getLeaf());
2.253 + @Override
2.254 + public State scan(Tree tree, Void p) {
2.255 + State r = super.scan(tree, p);
2.256 +
2.257 + if (r != null) {
2.258 + expressionState.put(tree, r);
2.259 + }
2.260 +
2.261 + return r;
2.262 + }
2.263
2.264 - String displayName = NbBundle.getMessage(NPECheck.class, key);
2.265 - List<Fix> fixes = FixFactory.createSuppressWarnings(info, path, "null");
2.266 - warnings.add(ErrorDescriptionFactory.createErrorDescription(getSeverity().toEditorSeverity(), displayName, fixes, info.getFileObject(), (int) start, (int) end));
2.267 - }
2.268 -
2.269 @Override
2.270 public State visitAssignment(AssignmentTree node, Void p) {
2.271 Element e = info.getTrees().getElement(new TreePath(getCurrentPath(), node.getVariable()));
2.272 @@ -147,24 +228,6 @@
2.273
2.274 scan(node.getVariable(), p);
2.275
2.276 - State elementState = getStateFromAnnotations(e);
2.277 -
2.278 - if (elementState != null && elementState.isNotNull()) {
2.279 - String key = null;
2.280 -
2.281 - if (r == NULL) {
2.282 - key = "ERR_AssigningNullToNotNull";
2.283 - }
2.284 -
2.285 - if (r == POSSIBLE_NULL_REPORT) {
2.286 - key = "ERR_PossibleAssigingNullToNotNull";
2.287 - }
2.288 -
2.289 - if (key != null) {
2.290 - report(getCurrentPath(), key);
2.291 - }
2.292 - }
2.293 -
2.294 return r;
2.295 }
2.296
2.297 @@ -186,37 +249,29 @@
2.298 @Override
2.299 public State visitMemberSelect(MemberSelectTree node, Void p) {
2.300 State expr = scan(node.getExpression(), p);
2.301 -
2.302 - long start = info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), node);
2.303 - long end = info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), node);
2.304 -
2.305 boolean wasNPE = false;
2.306
2.307 if (expr == State.NULL) {
2.308 - String displayName = NbBundle.getMessage(NPECheck.class, "ERR_DereferencingNull");
2.309 - List<Fix> fixes = FixFactory.createSuppressWarnings(info, getCurrentPath(), "null");
2.310 - warnings.add(ErrorDescriptionFactory.createErrorDescription(getSeverity().toEditorSeverity(), displayName, fixes, info.getFileObject(), (int) start, (int) end));
2.311 -
2.312 wasNPE = true;
2.313 }
2.314
2.315 if (expr == State.POSSIBLE_NULL_REPORT) {
2.316 - String displayName = NbBundle.getMessage(NPECheck.class, "ERR_PossiblyDereferencingNull");
2.317 - List<Fix> fixes = FixFactory.createSuppressWarnings(info, getCurrentPath(), "null");
2.318 - warnings.add(ErrorDescriptionFactory.createErrorDescription(getSeverity().toEditorSeverity(), displayName, fixes, info.getFileObject(), (int) start, (int) end));
2.319 -
2.320 wasNPE = true;
2.321 }
2.322
2.323 - if (wasNPE) {
2.324 - Element e = info.getTrees().getElement(new TreePath(getCurrentPath(), node.getExpression()));
2.325 + Element e = info.getTrees().getElement(new TreePath(getCurrentPath(), node.getExpression()));
2.326 +
2.327 + if (isVariableElement(e)) {
2.328 + State r = getStateFromAnnotations(e);
2.329
2.330 - if (isVariableElement(e)) {
2.331 + if (wasNPE) {
2.332 variable2State.put((VariableElement) e, NOT_NULL_BE_NPE);
2.333 }
2.334 +
2.335 + return r;
2.336 }
2.337
2.338 - return super.visitMemberSelect(node, p);
2.339 + return State.POSSIBLE_NULL;
2.340 }
2.341
2.342 @Override
2.343 @@ -474,12 +529,10 @@
2.344 @Override
2.345 public State visitMethodInvocation(MethodInvocationTree node, Void p) {
2.346 scan(node.getTypeArguments(), p);
2.347 -
2.348 - State methodSelectState = scan(node.getMethodSelect(), p);
2.349 - List<State> paramStates = new ArrayList<State>(node.getArguments().size());
2.350 + scan(node.getMethodSelect(), p);
2.351
2.352 for (Tree param : node.getArguments()) {
2.353 - paramStates.add(scan(param, p));
2.354 + scan(param, p);
2.355 }
2.356
2.357 Element e = info.getTrees().getElement(getCurrentPath());
2.358 @@ -488,22 +541,6 @@
2.359 return State.POSSIBLE_NULL;
2.360 }
2.361
2.362 - ExecutableElement ee = (ExecutableElement) e;
2.363 - int index = 0;
2.364 -
2.365 - for (VariableElement param : ee.getParameters()) {
2.366 - if (getStateFromAnnotations(param) == NOT_NULL) {
2.367 - switch (paramStates.get(index)) {
2.368 - case NULL:
2.369 - report(new TreePath(getCurrentPath(), node.getArguments().get(index)), "ERR_NULL_TO_NON_NULL_ARG");
2.370 - break;
2.371 - case POSSIBLE_NULL_REPORT:
2.372 - report(new TreePath(getCurrentPath(), node.getArguments().get(index)), "ERR_POSSIBLENULL_TO_NON_NULL_ARG");
2.373 - break;
2.374 - }
2.375 - }
2.376 - }
2.377 -
2.378 return getStateFromAnnotations(e);
2.379 }
2.380
2.381 @@ -559,29 +596,6 @@
2.382 return null;
2.383 }
2.384
2.385 - private State getStateFromAnnotations(Element e) {
2.386 - return getStateFromAnnotations(e, State.POSSIBLE_NULL);
2.387 - }
2.388 -
2.389 - private State getStateFromAnnotations(Element e, State def) {
2.390 - for (AnnotationMirror am : e.getAnnotationMirrors()) {
2.391 - String simpleName = ((TypeElement) am.getAnnotationType().asElement()).getSimpleName().toString();
2.392 -
2.393 - if ("Nullable".equals(simpleName) || "NullAllowed".equals(simpleName)) {
2.394 - return State.POSSIBLE_NULL_REPORT;
2.395 - }
2.396 -
2.397 - if ("CheckForNull".equals(simpleName)) {
2.398 - return State.POSSIBLE_NULL_REPORT;
2.399 - }
2.400 -
2.401 - if ("NotNull".equals(simpleName) || "NonNull".equals(simpleName)) {
2.402 - return State.NOT_NULL;
2.403 - }
2.404 - }
2.405 -
2.406 - return def;
2.407 - }
2.408 }
2.409
2.410 static enum State {
3.1 --- a/javahints/test/unit/src/org/netbeans/modules/javahints/NPECheckTest.java Thu Apr 19 21:04:16 2012 +0200
3.2 +++ b/javahints/test/unit/src/org/netbeans/modules/javahints/NPECheckTest.java Thu Apr 19 22:19:53 2012 +0200
3.3 @@ -1,7 +1,7 @@
3.4 /*
3.5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3.6 *
3.7 - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
3.8 + * Copyright 1997-2012 Sun Microsystems, Inc. All rights reserved.
3.9 *
3.10 * The contents of this file are subject to the terms of either the GNU
3.11 * General Public License Version 2 only ("GPL") or the Common
3.12 @@ -23,88 +23,92 @@
3.13 *
3.14 * Contributor(s):
3.15 *
3.16 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
3.17 + * Portions Copyrighted 2007-2012 Sun Microsystems, Inc.
3.18 */
3.19
3.20 package org.netbeans.modules.javahints;
3.21
3.22 -import com.sun.source.util.TreePath;
3.23 -import java.util.List;
3.24 -import org.netbeans.api.java.source.CompilationInfo;
3.25 -import org.netbeans.modules.java.hints.infrastructure.TreeRuleTestBase;
3.26 -import org.netbeans.spi.editor.hints.ErrorDescription;
3.27 -import org.openide.util.NbBundle;
3.28 +import org.netbeans.junit.NbTestCase;
3.29 +import org.netbeans.modules.java.hints.test.api.HintTest;
3.30
3.31 /**
3.32 *
3.33 * @author lahvac
3.34 */
3.35 -public class NPECheckTest extends TreeRuleTestBase {
3.36 +public class NPECheckTest extends NbTestCase {
3.37
3.38 public NPECheckTest(String testName) {
3.39 super(testName);
3.40 }
3.41
3.42 public void testSimpleNull1() throws Exception {
3.43 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {Object o; o = null; o.toString();}}", "0:67-0:77:verifier:DN");
3.44 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {Object o; o = null; o.toString();}}", "0:69-0:77:verifier:DN");
3.45 }
3.46
3.47 public void testSimpleNull2() throws Exception {
3.48 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {Object o = null; o.toString();}}", "0:64-0:74:verifier:DN");
3.49 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {Object o = null; o.toString();}}", "0:66-0:74:verifier:DN");
3.50 }
3.51
3.52 public void testIf1() throws Exception {
3.53 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st(Object o) {if (o == null) {o.toString();}}}", "0:71-0:81:verifier:DN");
3.54 + performAnalysisTest("test/Test.java", "package test; class Test {private void test(Object o) {if (o == null) {o.toString();}}}", "0:73-0:81:verifier:DN");
3.55 }
3.56
3.57 public void testIf2() throws Exception {
3.58 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st(Object o) {if (o == null) {o = \"\";} o.length();}}");
3.59 + HintTest.create()
3.60 + .input("package test; class Test {private void test(Object o) {if (o == null) {o = \"\";} o.length();}}", false)
3.61 + .run(NPECheck.class)
3.62 + .assertWarnings();
3.63 }
3.64
3.65 public void testIf3() throws Exception {
3.66 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {String s = null; if (s == null) {s = \"\";} s.length();}}");
3.67 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String s = null; if (s == null) {s = \"\";} s.length();}}");
3.68 }
3.69
3.70 public void testIf4() throws Exception {
3.71 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {String s = null; if (s == null) {s = \"\";} else {s = \"\";} s.length();}}");
3.72 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String s = null; if (s == null) {s = \"\";} else {s = \"\";} s.length();}}");
3.73 }
3.74
3.75 public void testIf5() throws Exception {
3.76 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {String s = null; if (s == null) {s = \"\";} else {s = null;} s.length();}}", "0:106-0:114:verifier:Possibly Dereferencing null");
3.77 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String s = null; if (s == null) {s = \"\";} else {s = null;} s.length();}}", "0:108-0:114:verifier:Possibly Dereferencing null");
3.78 }
3.79
3.80 public void testIf6() throws Exception {
3.81 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st(Object o) {if (null == o) {o.toString();}}}", "0:71-0:81:verifier:DN");
3.82 + performAnalysisTest("test/Test.java", "package test; class Test {private void test(Object o) {if (null == o) {o.toString();}}}", "0:73-0:81:verifier:DN");
3.83 }
3.84
3.85 public void testIf7() throws Exception {
3.86 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {String o = null; if (o != null) {o.toString();}}}");
3.87 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String o = null; if (o != null) {o.toString();}}}");
3.88 }
3.89
3.90 public void testIf8() throws Exception {
3.91 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {String o = null; if (null != o) {o.toString();}}}");
3.92 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String o = null; if (null != o) {o.toString();}}}");
3.93 }
3.94
3.95 public void testIf9() throws Exception {
3.96 - performAnalysisTest("test/Test.java",
3.97 - "package test; class Test {private void te|st(String s) {if (s == null) {} s.length();}}}",
3.98 - "0:73-0:81:verifier:Possibly Dereferencing null");
3.99 + HintTest.create()
3.100 + .input("package test; class Test {private void test(String s) {if (s == null) {} s.length();}}")
3.101 + .run(NPECheck.class)
3.102 + .assertWarnings("0:75-0:81:verifier:Possibly Dereferencing null");
3.103 }
3.104
3.105 public void testIfa() throws Exception {
3.106 - performAnalysisTest("test/Test.java",
3.107 - "package test; class Test {private void te|st(String s1, String s2) {if (s1 == null) {s1 = s2;} s1.length();}}}");
3.108 + HintTest.create()
3.109 + .input("package test; class Test {private void test(String s1, String s2) {if (s1 == null) {s1 = s2;} s1.length();}}")
3.110 + .run(NPECheck.class)
3.111 + .assertWarnings();
3.112 }
3.113
3.114 public void testIfb() throws Exception {
3.115 - performAnalysisTest("test/Test.java",
3.116 - "package test; class Test {private void te|st(@Null String s) {if (s == null) {throw new UnsupportedOperationException();} s.length();}} @interface Null {}}");
3.117 + HintTest.create()
3.118 + .input("package test; class Test {private void test(@Null String s) {if (s == null) {throw new UnsupportedOperationException();} s.length();}} @interface Null {}")
3.119 + .run(NPECheck.class)
3.120 + .assertWarnings();
3.121 }
3.122
3.123 public void testIfc() throws Exception {
3.124 performAnalysisTest("test/Test.java",
3.125 "package test; class Test {\n"+
3.126 - " private void te|st(int i, @CheckForNull String o) {\n" +
3.127 + " private void test(int i, @CheckForNull String o) {\n" +
3.128 " if (i > 2 && o != null && o.length() > 2) {\n" +
3.129 " }\n" +
3.130 " }\n" +
3.131 @@ -119,24 +123,24 @@
3.132 " }\n" +
3.133 " }\n" +
3.134 " @interface CheckForNull{}\n" +
3.135 - "}\n", 42);
3.136 + "}\n");
3.137 }
3.138
3.139 public void testTernary1() throws Exception {
3.140 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st(int i) {String s = i == 0 ? \"\" : null; s.length();}}");
3.141 + performAnalysisTest("test/Test.java", "package test; class Test {private void test(int i) {String s = i == 0 ? \"\" : null; s.length();}}");
3.142 }
3.143
3.144 public void testTernary2() throws Exception {
3.145 performAnalysisTest("test/Test.java",
3.146 - "package test; class Test {private void te|st(String s) {Object o = s == null ? \"\" : s; s = s.toString();}}",
3.147 - "0:90-0:100:verifier:Possibly Dereferencing null");
3.148 + "package test; class Test {private void test(String s) {Object o = s == null ? \"\" : s; s = s.toString();}}",
3.149 + "0:92-0:100:verifier:Possibly Dereferencing null");
3.150 }
3.151
3.152 public void testTernary3() throws Exception {
3.153 performAnalysisTest("test/Test.java",
3.154 "package test;\n" +
3.155 "class Test {\n" +
3.156 - " public void te|st() {" +
3.157 + " public void test() {" +
3.158 " String e = null;" +
3.159 " String f = e == null ? \"\" : e.trim();" +
3.160 " }" +
3.161 @@ -144,66 +148,66 @@
3.162 }
3.163
3.164 public void testNewClass() throws Exception {
3.165 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {String s = null; if (s == null) {s = new String(\"\");} s.length();}}");
3.166 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String s = null; if (s == null) {s = new String(\"\");} s.length();}}");
3.167 }
3.168
3.169 public void testCheckForNull1() throws Exception {
3.170 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {String s = get(); s.length();} @Nullable private String get() {return \"\";} @interface Nullable {}}", "0:65-0:73:verifier:Possibly Dereferencing null");
3.171 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String s = get(); s.length();} @Nullable private String get() {return \"\";} @interface Nullable {}}", "0:67-0:73:verifier:Possibly Dereferencing null");
3.172 }
3.173
3.174 public void testCheckForNull2() throws Exception {
3.175 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {s.length();} @Nullable private String s; @interface Nullable {}}", "0:47-0:55:verifier:Possibly Dereferencing null");
3.176 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {s.length();} @Nullable private String s; @interface Nullable {}}", "0:49-0:55:verifier:Possibly Dereferencing null");
3.177 }
3.178
3.179 public void testAssignNullToNotNull() throws Exception {
3.180 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {s = null;} @NotNull private String s; @interface NotNull {}}", "0:47-0:55:verifier:ANNNV");
3.181 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {s = null;} @NotNull private String s; @interface NotNull {}}", "0:47-0:55:verifier:ANNNV");
3.182 }
3.183
3.184 public void testPossibleAssignNullToNotNull() throws Exception {
3.185 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st(int i) {String s2 = null; if (i == 0) {s2 = \"\";} s = s2;} @NotNull private String s; @interface NotNull {}}", "0:93-0:99:verifier:PANNNV");
3.186 + performAnalysisTest("test/Test.java", "package test; class Test {private void test(int i) {String s2 = null; if (i == 0) {s2 = \"\";} s = s2;} @NotNull private String s; @interface NotNull {}}", "0:93-0:99:verifier:PANNNV");
3.187 }
3.188
3.189 public void testNullCheckAnd1() throws Exception {
3.190 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {String s = null; if (s != null && s.length() > 0) {}}}");
3.191 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String s = null; if (s != null && s.length() > 0) {}}}");
3.192 }
3.193
3.194 public void testNullCheckAnd2() throws Exception {
3.195 - performAnalysisTest("test/Test.java", "package test; class Test {private void te|st() {String s = null; if (s == null && s.length() > 0) {}}}", "0:81-0:89:verifier:DN");
3.196 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String s = null; if (s == null && s.length() > 0) {}}}", "0:83-0:89:verifier:DN");
3.197 }
3.198
3.199 public void testNullCheckOr1() throws Exception {
3.200 - performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String s = null; if (s != null || s.length() > 0) {}}}", 89 - 48, "0:81-0:89:verifier:DN");
3.201 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String s = null; if (s != null || s.length() > 0) {}}}", "0:83-0:89:verifier:DN");
3.202 }
3.203
3.204 public void testNullCheckOr2() throws Exception {
3.205 - performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String s = null; if (s == null || s.length() > 0) {}}}", 89 - 48);
3.206 + performAnalysisTest("test/Test.java", "package test; class Test {private void test() {String s = null; if (s == null || s.length() > 0) {}}}");
3.207 }
3.208
3.209 public void testContinue1() throws Exception {
3.210 performAnalysisTest("test/Test.java",
3.211 - "package test; class Test {private void te|st(String[] sa) {for (String s : sa) {if (s == null) continue; s.length();}}}");
3.212 + "package test; class Test {private void test(String[] sa) {for (String s : sa) {if (s == null) continue; s.length();}}}");
3.213 }
3.214
3.215 public void testCondition1() throws Exception {
3.216 performAnalysisTest("test/Test.java",
3.217 - "package test; class Test {private void test(String sa) {boolean b = sa != null && (sa.length() == 0 || sa.length() == 1);}}", 71 - 30);
3.218 + "package test; class Test {private void test(String sa) {boolean b = sa != null && (sa.length() == 0 || sa.length() == 1);}}");
3.219 }
3.220
3.221 public void testCondition2() throws Exception {
3.222 performAnalysisTest("test/Test.java",
3.223 - "package test; class Test {private void test(String sa) {boolean b = sa == null || (sa.length() == 0 && sa.length() == 1);}}", 71 - 30);
3.224 + "package test; class Test {private void test(String sa) {boolean b = sa == null || (sa.length() == 0 && sa.length() == 1);}}");
3.225 }
3.226
3.227 public void testCondition3() throws Exception {
3.228 performAnalysisTest("test/Test.java",
3.229 - "package test; class Test {private void te|st(int i) {Object o2 = i < 1 ? null : \"\"; boolean b = true && o2 != null && o2.toString() != \"\";}}");
3.230 + "package test; class Test {private void test(int i) {Object o2 = i < 1 ? null : \"\"; boolean b = true && o2 != null && o2.toString() != \"\";}}");
3.231 }
3.232
3.233 public void testWhileAndIf() throws Exception {
3.234 performAnalysisTest("test/Test.java",
3.235 "package test;\n" +
3.236 "class Test {\n" +
3.237 - " private void tes|t(int i, boolean b, Object o2) {\n" +
3.238 + " private void test(int i, boolean b, Object o2) {\n" +
3.239 " Object o = null;\n" +
3.240 " while (--i > 0) {\n" +
3.241 " if (b) {\n" +
3.242 @@ -213,28 +217,28 @@
3.243 " o.toString();\n" +
3.244 " }" +
3.245 "}",
3.246 - "9:8-9:18:verifier:DN");
3.247 + "9:10-9:18:verifier:DN");
3.248 }
3.249
3.250 public void testWhile1() throws Exception {
3.251 performAnalysisTest("test/Test.java",
3.252 "package test;\n" +
3.253 "class Test {\n" +
3.254 - " private void tes|t(String o) {\n" +
3.255 + " private void test(String o) {\n" +
3.256 " while (o != null && o.length() > 1) {\n" +
3.257 " o = o.substring(1);\n" +
3.258 " }\n" +
3.259 " o.toString();\n" +
3.260 " }" +
3.261 "}",
3.262 - "6:8-6:18:verifier:Possibly Dereferencing null");
3.263 + "6:10-6:18:verifier:Possibly Dereferencing null");
3.264 }
3.265
3.266 public void testWhile2() throws Exception {
3.267 performAnalysisTest("test/Test.java",
3.268 "package test;\n" +
3.269 "class Test {\n" +
3.270 - " private void tes|t(@CheckForNull String o) {\n" +
3.271 + " private void test(@CheckForNull String o) {\n" +
3.272 " while (o != null) {\n" +
3.273 " o = o.substring(1);\n" +
3.274 " }\n" +
3.275 @@ -245,13 +249,13 @@
3.276
3.277 public void testParameter1() throws Exception {
3.278 performAnalysisTest("test/Test.java",
3.279 - "package test; class Test {private void te|st(int i) {String s = null; ttt(s);} private void ttt(@NotNull String s){}} @interface NotNull {}",
3.280 + "package test; class Test {private void test(int i) {String s = null; ttt(s);} private void ttt(@NotNull String s){}} @interface NotNull {}",
3.281 "0:73-0:74:verifier:ERR_NULL_TO_NON_NULL_ARG");
3.282 }
3.283
3.284 public void testParameter2() throws Exception {
3.285 performAnalysisTest("test/Test.java",
3.286 - "package test; class Test {private void te|st(int i) {ttt(t());} private void ttt(@NotNull String s){} private @CheckForNull String t() {return \"\";} } @interface NotNull {} @interface CheckForNull {}",
3.287 + "package test; class Test {private void test(int i) {ttt(t());} private void ttt(@NotNull String s){} private @CheckForNull String t() {return \"\";} } @interface NotNull {} @interface CheckForNull {}",
3.288 "0:56-0:59:verifier:ERR_POSSIBLENULL_TO_NON_NULL_ARG");
3.289 }
3.290
3.291 @@ -259,64 +263,64 @@
3.292 performAnalysisTest("test/Test.java",
3.293 "package test;\n" +
3.294 "class Test {\n" +
3.295 - " private void tes|t(@CheckForNull String o) {\n" +
3.296 + " private void test(@CheckForNull String o) {\n" +
3.297 " o.toString();\n" +
3.298 " o.toString();\n" +
3.299 " o.toString();\n" +
3.300 " }" +
3.301 " @interface CheckForNull {}\n" +
3.302 - "}", "3:8-3:18:verifier:Possibly Dereferencing null");
3.303 + "}", "3:10-3:18:verifier:Possibly Dereferencing null");
3.304 }
3.305
3.306 public void testNoMultipleReports2() throws Exception {
3.307 performAnalysisTest("test/Test.java",
3.308 "package test;\n" +
3.309 "class Test {\n" +
3.310 - " private void tes|t(@CheckForNull String o) {\n" +
3.311 + " private void test(@CheckForNull String o) {\n" +
3.312 " if (o.length() > 1 && o.length() > 2);\n" +
3.313 " }" +
3.314 " @interface CheckForNull {}\n" +
3.315 - "}", "3:12-3:20:verifier:Possibly Dereferencing null");
3.316 + "}", "3:14-3:20:verifier:Possibly Dereferencing null");
3.317 }
3.318
3.319 public void testNoMultipleReports3() throws Exception {
3.320 performAnalysisTest("test/Test.java",
3.321 "package test;\n" +
3.322 "class Test {\n" +
3.323 - " private void tes|t(@CheckForNull String o) {\n" +
3.324 + " private void test(@CheckForNull String o) {\n" +
3.325 " boolean b = o.length() > 1 && o.length() > 2;\n" +
3.326 " }" +
3.327 " @interface CheckForNull {}\n" +
3.328 - "}", "3:20-3:28:verifier:Possibly Dereferencing null");
3.329 + "}", "3:22-3:28:verifier:Possibly Dereferencing null");
3.330 }
3.331
3.332 public void testNoMultipleReports4() throws Exception {
3.333 performAnalysisTest("test/Test.java",
3.334 "package test;\n" +
3.335 "class Test {\n" +
3.336 - " private void tes|t(@CheckForNull String o) {\n" +
3.337 + " private void test(@CheckForNull String o) {\n" +
3.338 " boolean b = o.length() > 1 && o.length() > 2 ? false : true;\n" +
3.339 " }" +
3.340 " @interface CheckForNull {}\n" +
3.341 - "}", "3:20-3:28:verifier:Possibly Dereferencing null");
3.342 + "}", "3:22-3:28:verifier:Possibly Dereferencing null");
3.343 }
3.344
3.345 public void testCCE() throws Exception {
3.346 - performAnalysisTest("test/Test.java",
3.347 - "package test;\n" +
3.348 - "class Test {\n" +
3.349 - " private void tes|t() {\n" +
3.350 - " c.s Object method = new Object();\n" +
3.351 - " }" +
3.352 - "}"/*, "3:20-3:28:verifier:Possibly Dereferencing null"*/);
3.353 + HintTest.create()
3.354 + .input("package test;\n" +
3.355 + "class Test {\n" +
3.356 + " private void test() {\n" +
3.357 + " c.s Object method = new Object();\n" +
3.358 + " }" +
3.359 + "}", false)
3.360 + .run(NPECheck.class)
3.361 + .assertWarnings(/*"3:20-3:28:verifier:Possibly Dereferencing null"*/);
3.362 }
3.363
3.364 - @Override
3.365 - protected List<ErrorDescription> computeErrors(CompilationInfo info, TreePath path) {
3.366 - return new NPECheck().run(info, path);
3.367 - }
3.368 -
3.369 - static {
3.370 - NbBundle.setBranding("test");
3.371 + private void performAnalysisTest(String fileName, String code, String... golden) throws Exception {
3.372 + HintTest.create()
3.373 + .input(fileName, code)
3.374 + .run(NPECheck.class)
3.375 + .assertWarnings(golden);
3.376 }
3.377 }