samples/getclassnpe.js

Fri, 05 Jun 2015 12:38:53 +0200

author
mhaupt
date
Fri, 05 Jun 2015 12:38:53 +0200
changeset 1398
2f1b9f4daec1
parent 1232
09bd5b8abcba
permissions
-rw-r--r--

8080087: Nashorn $ENV.PWD is originally undefined
Summary: On Windows, the PWD environment variable does not exist and cannot be imported in scripting mode, so it is set explicitly.
Reviewed-by: lagergren, sundar

sundar@1232 1 #// Usage: jjs getclassnpe.js -- <directory>
sundar@1232 2
sundar@1232 3 /*
sundar@1232 4 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
sundar@1232 5 *
sundar@1232 6 * Redistribution and use in source and binary forms, with or without
sundar@1232 7 * modification, are permitted provided that the following conditions
sundar@1232 8 * are met:
sundar@1232 9 *
sundar@1232 10 * - Redistributions of source code must retain the above copyright
sundar@1232 11 * notice, this list of conditions and the following disclaimer.
sundar@1232 12 *
sundar@1232 13 * - Redistributions in binary form must reproduce the above copyright
sundar@1232 14 * notice, this list of conditions and the following disclaimer in the
sundar@1232 15 * documentation and/or other materials provided with the distribution.
sundar@1232 16 *
sundar@1232 17 * - Neither the name of Oracle nor the names of its
sundar@1232 18 * contributors may be used to endorse or promote products derived
sundar@1232 19 * from this software without specific prior written permission.
sundar@1232 20 *
sundar@1232 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
sundar@1232 22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
sundar@1232 23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
sundar@1232 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
sundar@1232 25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
sundar@1232 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
sundar@1232 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
sundar@1232 28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
sundar@1232 29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
sundar@1232 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
sundar@1232 31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
sundar@1232 32 */
sundar@1232 33
sundar@1232 34 /*
sundar@1232 35 * java.lang.Object.getClass() is sometimes used to do null check. This
sundar@1232 36 * obfuscating Object.getClass() check relies on non-related intrinsic
sundar@1232 37 * performance, which is potentially not available everywhere.
sundar@1232 38 * See also http://cr.openjdk.java.net/~shade/scratch/NullChecks.java
sundar@1232 39 * This nashorn script checks for such uses in your .java files in the
sundar@1232 40 * given directory (recursively).
sundar@1232 41 */
sundar@1232 42
sundar@1232 43 if (arguments.length == 0) {
sundar@1232 44 print("Usage: jjs getclassnpe.js -- <directory>");
sundar@1232 45 exit(1);
sundar@1232 46 }
sundar@1232 47
sundar@1232 48 // Java types used
sundar@1232 49 var File = Java.type("java.io.File");
sundar@1232 50 var Files = Java.type("java.nio.file.Files");
sundar@1232 51 var StringArray = Java.type("java.lang.String[]");
sundar@1232 52 var ToolProvider = Java.type("javax.tools.ToolProvider");
sundar@1232 53 var MethodInvocationTree = Java.type("com.sun.source.tree.MethodInvocationTree");
sundar@1232 54 var TreeScanner = Java.type("com.sun.source.util.TreeScanner");
sundar@1232 55
sundar@1232 56 // parse a specific .java file to check if it uses
sundar@1232 57 // Object.getClass() for null check.
sundar@1232 58 function checkGetClassNPE() {
sundar@1232 59 // get the system compiler tool
sundar@1232 60 var compiler = ToolProvider.systemJavaCompiler;
sundar@1232 61 // get standard file manager
sundar@1232 62 var fileMgr = compiler.getStandardFileManager(null, null, null);
sundar@1232 63 // Using Java.to convert script array (arguments) to a Java String[]
sundar@1232 64 var compUnits = fileMgr.getJavaFileObjects(
sundar@1232 65 Java.to(arguments, StringArray));
sundar@1232 66 // create a new compilation task
sundar@1232 67 var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);
sundar@1232 68 // subclass SimpleTreeVisitor - to check for obj.getClass(); statements
sundar@1232 69 var GetClassNPEChecker = Java.extend(TreeScanner);
sundar@1232 70
sundar@1232 71 var visitor = new GetClassNPEChecker() {
sundar@1232 72 lineMap: null,
sundar@1232 73 sourceFile: null,
sundar@1232 74
sundar@1232 75 // save compilation unit details for reporting
sundar@1232 76 visitCompilationUnit: function(node, p) {
sundar@1232 77 this.sourceFile = node.sourceFile;
sundar@1232 78 this.lineMap = node.lineMap;
sundar@1232 79 return Java.super(visitor).visitCompilationUnit(node, p);
sundar@1232 80 },
sundar@1232 81
sundar@1232 82 // look for "foo.getClass();" expression statements
sundar@1232 83 visitExpressionStatement: function(node, p) {
sundar@1232 84 var expr = node.expression;
sundar@1232 85 if (expr instanceof MethodInvocationTree) {
sundar@1232 86 var name = String(expr.methodSelect.identifier);
sundar@1232 87
sundar@1232 88 // will match any "getClass" call with zero arguments!
sundar@1232 89 if (name == "getClass" && expr.arguments.size() == 0) {
sundar@1232 90 print(this.sourceFile.getName()
sundar@1232 91 + " @ "
sundar@1232 92 + this.lineMap.getLineNumber(node.pos)
sundar@1232 93 + ":"
sundar@1232 94 + this.lineMap.getColumnNumber(node.pos));
sundar@1232 95
sundar@1232 96 print("\t", node);
sundar@1232 97 }
sundar@1232 98 }
sundar@1232 99 }
sundar@1232 100 }
sundar@1232 101
sundar@1232 102 for each (var cu in task.parse()) {
sundar@1232 103 cu.accept(visitor, null);
sundar@1232 104 }
sundar@1232 105 }
sundar@1232 106
sundar@1232 107 // for each ".java" file in the directory (recursively)
sundar@1232 108 function main(dir) {
sundar@1232 109 Files.walk(dir.toPath()).
sundar@1232 110 forEach(function(p) {
sundar@1232 111 var name = p.toFile().absolutePath;
sundar@1232 112 if (name.endsWith(".java")) {
sundar@1232 113 try {
sundar@1232 114 checkGetClassNPE(p.toFile().getAbsolutePath());
sundar@1232 115 } catch (e) {
sundar@1232 116 print(e);
sundar@1232 117 }
sundar@1232 118 }
sundar@1232 119 });
sundar@1232 120 }
sundar@1232 121
sundar@1232 122 main(new File(arguments[0]));

mercurial