Starting CheckReturnValueHint.
authorJan Lahoda <jlahoda@netbeans.org>
Sun, 30 Oct 2011 22:14:10 +0100
changeset 17660576257df2a4c
parent 17659 917566f2a1d5
child 17661 85103b897e7c
child 17665 42c4e8d8d99d
Starting CheckReturnValueHint.
javahints/nbproject/project.properties
javahints/src/org/netbeans/modules/javahints/Bundle.properties
javahints/src/org/netbeans/modules/javahints/CheckReturnValueHint.java
javahints/test/unit/src/org/netbeans/modules/javahints/Bundle_test.properties
javahints/test/unit/src/org/netbeans/modules/javahints/CheckReturnValueHintTest.java
     1.1 --- a/javahints/nbproject/project.properties	Fri Oct 28 19:35:47 2011 +0200
     1.2 +++ b/javahints/nbproject/project.properties	Sun Oct 30 22:14:10 2011 +0100
     1.3 @@ -50,7 +50,7 @@
     1.4  auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-limit-width=80
     1.5  javac.compilerargs=-Xlint:unchecked
     1.6  javac.source=1.5
     1.7 -spec.version.base=2.47.0
     1.8 +spec.version.base=2.48.0
     1.9  
    1.10  nbm.needs.restart=true
    1.11  requires.nb.javac=true
     2.1 --- a/javahints/src/org/netbeans/modules/javahints/Bundle.properties	Fri Oct 28 19:35:47 2011 +0200
     2.2 +++ b/javahints/src/org/netbeans/modules/javahints/Bundle.properties	Sun Oct 30 22:14:10 2011 +0100
     2.3 @@ -155,3 +155,7 @@
     2.4  
     2.5  DN_org.netbeans.modules.javahints.RPD=RequestProcessor.getDefault()
     2.6  DESC_org.netbeans.modules.javahints.RPD=RequestProcessor.getDefault()
     2.7 +
     2.8 +DN_org.netbeans.modules.javahints.CheckReturnValueHint=@CheckReturnValue
     2.9 +DESC_org.netbeans.modules.javahints.CheckReturnValueHint=Verifies that a result of method marked with @CheckReturnValue is really checked.
    2.10 +ERR_org.netbeans.modules.javahints.CheckReturnValueHint=Should check the method return value
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/javahints/src/org/netbeans/modules/javahints/CheckReturnValueHint.java	Sun Oct 30 22:14:10 2011 +0100
     3.3 @@ -0,0 +1,100 @@
     3.4 +/*
     3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 + *
     3.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
     3.8 + *
     3.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    3.10 + * Other names may be trademarks of their respective owners.
    3.11 + *
    3.12 + * The contents of this file are subject to the terms of either the GNU
    3.13 + * General Public License Version 2 only ("GPL") or the Common
    3.14 + * Development and Distribution License("CDDL") (collectively, the
    3.15 + * "License"). You may not use this file except in compliance with the
    3.16 + * License. You can obtain a copy of the License at
    3.17 + * http://www.netbeans.org/cddl-gplv2.html
    3.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    3.19 + * specific language governing permissions and limitations under the
    3.20 + * License.  When distributing the software, include this License Header
    3.21 + * Notice in each file and include the License file at
    3.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    3.23 + * particular file as subject to the "Classpath" exception as provided
    3.24 + * by Oracle in the GPL Version 2 section of the License file that
    3.25 + * accompanied this code. If applicable, add the following below the
    3.26 + * License Header, with the fields enclosed by brackets [] replaced by
    3.27 + * your own identifying information:
    3.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    3.29 + *
    3.30 + * If you wish your version of this file to be governed by only the CDDL
    3.31 + * or only the GPL Version 2, indicate your decision by adding
    3.32 + * "[Contributor] elects to include this software in this distribution
    3.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    3.34 + * single choice of license, a recipient has the option to distribute
    3.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    3.36 + * to extend the choice of license to its licensees as provided above.
    3.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    3.38 + * Version 2 license, then the option applies only if the new code is
    3.39 + * made subject to such option by the copyright holder.
    3.40 + *
    3.41 + * Contributor(s):
    3.42 + *
    3.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
    3.44 + */
    3.45 +package org.netbeans.modules.javahints;
    3.46 +
    3.47 +import com.sun.source.tree.ExpressionStatementTree;
    3.48 +import com.sun.source.util.TreePath;
    3.49 +import java.util.Arrays;
    3.50 +import java.util.HashSet;
    3.51 +import java.util.Set;
    3.52 +import javax.lang.model.element.*;
    3.53 +import javax.lang.model.type.TypeKind;
    3.54 +import org.netbeans.modules.java.hints.jackpot.code.spi.Hint;
    3.55 +import org.netbeans.modules.java.hints.jackpot.code.spi.TriggerPattern;
    3.56 +import org.netbeans.modules.java.hints.jackpot.spi.HintContext;
    3.57 +import org.netbeans.modules.java.hints.jackpot.spi.support.ErrorDescriptionFactory;
    3.58 +import org.netbeans.spi.editor.hints.ErrorDescription;
    3.59 +import org.openide.util.NbBundle;
    3.60 +
    3.61 +/**
    3.62 + *
    3.63 + * @author lahvac
    3.64 + */
    3.65 +@Hint(category="bugs", suppressWarnings="ResultOfMethodCallIgnored")
    3.66 +public class CheckReturnValueHint {
    3.67 +
    3.68 +    @TriggerPattern("$method($params$);")
    3.69 +    public static ErrorDescription hint(HintContext ctx) {
    3.70 +        Element invoked = ctx.getInfo().getTrees().getElement(new TreePath(ctx.getPath(), ((ExpressionStatementTree) ctx.getPath().getLeaf()).getExpression()));
    3.71 +
    3.72 +        if (invoked == null || invoked.getKind() != ElementKind.METHOD || ((ExecutableElement) invoked).getReturnType().getKind() == TypeKind.VOID) return null;
    3.73 +
    3.74 +        boolean found = false;
    3.75 +
    3.76 +        for (AnnotationMirror am : invoked.getAnnotationMirrors()) {
    3.77 +            String simpleName = am.getAnnotationType().asElement().getSimpleName().toString();
    3.78 +
    3.79 +            if ("CheckReturnValue".equals(simpleName)) {
    3.80 +                found = true;
    3.81 +                break;
    3.82 +            }
    3.83 +        }
    3.84 +
    3.85 +        if (!found && !checkReturnValueForJDKMethods((ExecutableElement) invoked)) return null;
    3.86 +
    3.87 +        String displayName = NbBundle.getMessage(CheckReturnValueHint.class, "ERR_org.netbeans.modules.javahints.CheckReturnValueHint");
    3.88 +        
    3.89 +        return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), displayName);
    3.90 +    }
    3.91 +
    3.92 +    private static final Set<String> JDK_IMMUTABLE_CLASSES = new HashSet<String>(Arrays.asList("java.lang.String"));
    3.93 +
    3.94 +    private static boolean checkReturnValueForJDKMethods(ExecutableElement method) {
    3.95 +        Element owner = method.getEnclosingElement();
    3.96 +
    3.97 +        if (!owner.getKind().isClass() && !owner.getKind().isInterface()) return false;
    3.98 +
    3.99 +        if (JDK_IMMUTABLE_CLASSES.contains(((TypeElement) owner).getQualifiedName().toString())) return true;
   3.100 +
   3.101 +        return false;
   3.102 +    }
   3.103 +}
     4.1 --- a/javahints/test/unit/src/org/netbeans/modules/javahints/Bundle_test.properties	Fri Oct 28 19:35:47 2011 +0200
     4.2 +++ b/javahints/test/unit/src/org/netbeans/modules/javahints/Bundle_test.properties	Sun Oct 30 22:14:10 2011 +0100
     4.3 @@ -21,3 +21,4 @@
     4.4  ERR_NULL_TO_NON_NULL_ARG=ERR_NULL_TO_NON_NULL_ARG
     4.5  ERR_POSSIBLENULL_TO_NON_NULL_ARG=ERR_POSSIBLENULL_TO_NON_NULL_ARG
     4.6  DN_NegateCondition=Negate condition
     4.7 +ERR_org.netbeans.modules.javahints.CheckReturnValueHint=ERR_org.netbeans.modules.javahints.CheckReturnValueHint
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/javahints/test/unit/src/org/netbeans/modules/javahints/CheckReturnValueHintTest.java	Sun Oct 30 22:14:10 2011 +0100
     5.3 @@ -0,0 +1,79 @@
     5.4 +/*
     5.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     5.6 + *
     5.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
     5.8 + *
     5.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    5.10 + * Other names may be trademarks of their respective owners.
    5.11 + *
    5.12 + * The contents of this file are subject to the terms of either the GNU
    5.13 + * General Public License Version 2 only ("GPL") or the Common
    5.14 + * Development and Distribution License("CDDL") (collectively, the
    5.15 + * "License"). You may not use this file except in compliance with the
    5.16 + * License. You can obtain a copy of the License at
    5.17 + * http://www.netbeans.org/cddl-gplv2.html
    5.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    5.19 + * specific language governing permissions and limitations under the
    5.20 + * License.  When distributing the software, include this License Header
    5.21 + * Notice in each file and include the License file at
    5.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    5.23 + * particular file as subject to the "Classpath" exception as provided
    5.24 + * by Oracle in the GPL Version 2 section of the License file that
    5.25 + * accompanied this code. If applicable, add the following below the
    5.26 + * License Header, with the fields enclosed by brackets [] replaced by
    5.27 + * your own identifying information:
    5.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    5.29 + *
    5.30 + * If you wish your version of this file to be governed by only the CDDL
    5.31 + * or only the GPL Version 2, indicate your decision by adding
    5.32 + * "[Contributor] elects to include this software in this distribution
    5.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    5.34 + * single choice of license, a recipient has the option to distribute
    5.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    5.36 + * to extend the choice of license to its licensees as provided above.
    5.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    5.38 + * Version 2 license, then the option applies only if the new code is
    5.39 + * made subject to such option by the copyright holder.
    5.40 + *
    5.41 + * Contributor(s):
    5.42 + *
    5.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
    5.44 + */
    5.45 +package org.netbeans.modules.javahints;
    5.46 +
    5.47 +import org.netbeans.modules.java.hints.jackpot.code.spi.TestBase;
    5.48 +
    5.49 +/**
    5.50 + *
    5.51 + * @author lahvac
    5.52 + */
    5.53 +public class CheckReturnValueHintTest extends TestBase {
    5.54 +
    5.55 +    public CheckReturnValueHintTest(String name) {
    5.56 +        super(name, CheckReturnValueHint.class);
    5.57 +    }
    5.58 +
    5.59 +    public void testSimpleReport() throws Exception {
    5.60 +        performAnalysisTest("test/Test.java",
    5.61 +                            "package test;\n" +
    5.62 +                            "public class Test {\n" +
    5.63 +                            "    public @CheckReturnValue String foo() { return null; }\n" +
    5.64 +                            "    public void test() {\n" +
    5.65 +                            "        foo();\n" +
    5.66 +                            "    }\n" +
    5.67 +                            "}\n" +
    5.68 +                            "public @interface CheckReturnValue {}\n",
    5.69 +                            "4:8-4:14:verifier:ERR_org.netbeans.modules.javahints.CheckReturnValueHint");
    5.70 +    }
    5.71 +
    5.72 +    public void testStringSubString() throws Exception {
    5.73 +        performAnalysisTest("test/Test.java",
    5.74 +                            "package test;\n" +
    5.75 +                            "public class Test {\n" +
    5.76 +                            "    public void test(String arg) {\n" +
    5.77 +                            "        arg.substring(0);\n" +
    5.78 +                            "    }\n" +
    5.79 +                            "}\n",
    5.80 +                            "3:8-3:25:verifier:ERR_org.netbeans.modules.javahints.CheckReturnValueHint");
    5.81 +    }
    5.82 +}