Path: blob/aarch64-shenandoah-jdk8u272-b10/nashorn/samples/getclassnpe.js
32278 views
#// Usage: jjs getclassnpe.js -- <directory>12/*3* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* - Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* - Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* - Neither the name of Oracle nor the names of its17* contributors may be used to endorse or promote products derived18* from this software without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS21* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,22* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR23* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR24* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,25* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,26* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR27* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF28* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING29* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS30* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31*/3233/*34* java.lang.Object.getClass() is sometimes used to do null check. This35* obfuscating Object.getClass() check relies on non-related intrinsic36* performance, which is potentially not available everywhere.37* See also http://cr.openjdk.java.net/~shade/scratch/NullChecks.java38* This nashorn script checks for such uses in your .java files in the39* given directory (recursively).40*/4142if (arguments.length == 0) {43print("Usage: jjs getclassnpe.js -- <directory>");44exit(1);45}4647// Java types used48var File = Java.type("java.io.File");49var Files = Java.type("java.nio.file.Files");50var StringArray = Java.type("java.lang.String[]");51var ToolProvider = Java.type("javax.tools.ToolProvider");52var MethodInvocationTree = Java.type("com.sun.source.tree.MethodInvocationTree");53var TreeScanner = Java.type("com.sun.source.util.TreeScanner");5455// parse a specific .java file to check if it uses56// Object.getClass() for null check.57function checkGetClassNPE() {58// get the system compiler tool59var compiler = ToolProvider.systemJavaCompiler;60// get standard file manager61var fileMgr = compiler.getStandardFileManager(null, null, null);62// Using Java.to convert script array (arguments) to a Java String[]63var compUnits = fileMgr.getJavaFileObjects(64Java.to(arguments, StringArray));65// create a new compilation task66var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);67// subclass SimpleTreeVisitor - to check for obj.getClass(); statements68var GetClassNPEChecker = Java.extend(TreeScanner);6970var visitor = new GetClassNPEChecker() {71lineMap: null,72sourceFile: null,7374// save compilation unit details for reporting75visitCompilationUnit: function(node, p) {76this.sourceFile = node.sourceFile;77this.lineMap = node.lineMap;78return Java.super(visitor).visitCompilationUnit(node, p);79},8081// look for "foo.getClass();" expression statements82visitExpressionStatement: function(node, p) {83var expr = node.expression;84if (expr instanceof MethodInvocationTree) {85var name = String(expr.methodSelect.identifier);8687// will match any "getClass" call with zero arguments!88if (name == "getClass" && expr.arguments.size() == 0) {89print(this.sourceFile.getName()90+ " @ "91+ this.lineMap.getLineNumber(node.pos)92+ ":"93+ this.lineMap.getColumnNumber(node.pos));9495print("\t", node);96}97}98}99}100101for each (var cu in task.parse()) {102cu.accept(visitor, null);103}104}105106// for each ".java" file in the directory (recursively)107function main(dir) {108Files.walk(dir.toPath()).109forEach(function(p) {110var name = p.toFile().absolutePath;111if (name.endsWith(".java")) {112try {113checkGetClassNPE(p.toFile().getAbsolutePath());114} catch (e) {115print(e);116}117}118});119}120121main(new File(arguments[0]));122123124