sundar@1531: #// Usage: jjs exceptionswallow.js -- sundar@1531: sundar@1531: /* sundar@1531: * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. sundar@1531: * sundar@1531: * Redistribution and use in source and binary forms, with or without sundar@1531: * modification, are permitted provided that the following conditions sundar@1531: * are met: sundar@1531: * sundar@1531: * - Redistributions of source code must retain the above copyright sundar@1531: * notice, this list of conditions and the following disclaimer. sundar@1531: * sundar@1531: * - Redistributions in binary form must reproduce the above copyright sundar@1531: * notice, this list of conditions and the following disclaimer in the sundar@1531: * documentation and/or other materials provided with the distribution. sundar@1531: * sundar@1531: * - Neither the name of Oracle nor the names of its sundar@1531: * contributors may be used to endorse or promote products derived sundar@1531: * from this software without specific prior written permission. sundar@1531: * sundar@1531: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS sundar@1531: * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, sundar@1531: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR sundar@1531: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR sundar@1531: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, sundar@1531: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, sundar@1531: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR sundar@1531: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF sundar@1531: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING sundar@1531: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS sundar@1531: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sundar@1531: */ sundar@1531: sundar@1531: // This example demonstrates Java subclassing by Java.extend sundar@1531: // and javac Compiler and Tree API. This example looks for sundar@1531: // empty catch blocks ("exception swallow") and reports those. sundar@1531: sundar@1531: if (arguments.length == 0) { sundar@1531: print("Usage: jjs exceptionswallow.js -- "); sundar@1531: exit(1); sundar@1531: } sundar@1531: sundar@1531: // Java types used sundar@1531: var File = Java.type("java.io.File"); sundar@1531: var Files = Java.type("java.nio.file.Files"); sundar@1531: var StringArray = Java.type("java.lang.String[]"); sundar@1531: var ToolProvider = Java.type("javax.tools.ToolProvider"); sundar@1531: var Tree = Java.type("com.sun.source.tree.Tree"); sundar@1531: var EmptyStatementTree = Java.type("com.sun.source.tree.EmptyStatementTree"); sundar@1531: var Trees = Java.type("com.sun.source.util.Trees"); sundar@1531: var TreeScanner = Java.type("com.sun.source.util.TreeScanner"); sundar@1531: sundar@1531: // printEmptyCatch sundar@1531: sundar@1531: function printEmptyCatch() { sundar@1531: // get the system compiler tool sundar@1531: var compiler = ToolProvider.systemJavaCompiler; sundar@1531: // get standard file manager sundar@1531: var fileMgr = compiler.getStandardFileManager(null, null, null); sundar@1531: // Using Java.to convert script array (arguments) to a Java String[] sundar@1531: var compUnits = fileMgr.getJavaFileObjects( sundar@1531: Java.to(arguments, StringArray)); sundar@1531: // create a new compilation task sundar@1531: var task = compiler.getTask(null, fileMgr, null, null, null, compUnits); sundar@1531: sundar@1531: // SourcePositions object to get positions of AST nodes sundar@1531: var sourcePositions = Trees.instance(task).sourcePositions; sundar@1531: sundar@1531: // subclass SimpleTreeVisitor - to print empty catch sundar@1531: var EmptyCatchFinder = Java.extend(TreeScanner); sundar@1531: sundar@1531: function hasOnlyEmptyStats(stats) { sundar@1531: var itr = stats.iterator(); sundar@1531: while (itr.hasNext()) { sundar@1531: if (! (itr.next() instanceof EmptyStatementTree)) { sundar@1531: return false; sundar@1531: } sundar@1531: } sundar@1531: sundar@1531: return true; sundar@1531: } sundar@1531: sundar@1531: var visitor = new EmptyCatchFinder() { sundar@1531: // current CompilationUnitTree sundar@1531: compUnit: null, sundar@1531: // current LineMap (pos -> line, column) sundar@1531: lineMap: null, sundar@1531: // current compilation unit's file name sundar@1531: fileName: null, sundar@1531: sundar@1531: // overrides of TreeScanner methods sundar@1531: sundar@1531: visitCompilationUnit: function(node, p) { sundar@1531: // capture info about current Compilation unit sundar@1531: this.compUnit = node; sundar@1531: this.lineMap = node.lineMap; sundar@1531: this.fileName = node.sourceFile.name; sundar@1531: sundar@1531: // Using Java.super API to call super class method here sundar@1531: return Java.super(visitor).visitCompilationUnit(node, p); sundar@1531: }, sundar@1531: sundar@1531: visitCatch: function (node, p) { sundar@1531: var stats = node.block.statements; sundar@1531: if (stats.empty || hasOnlyEmptyStats(stats)) { sundar@1531: // print information on this empty catch sundar@1531: var pos = sourcePositions.getStartPosition(this.compUnit, node); sundar@1531: var line = this.lineMap.getLineNumber(pos); sundar@1531: var col = this.lineMap.getColumnNumber(pos); sundar@1531: print("Exception swallow" + " @ " + this.fileName + ":" + line + ":" + col); sundar@1531: // print(node); sundar@1531: } sundar@1531: } sundar@1531: } sundar@1531: sundar@1531: for each (var cu in task.parse()) { sundar@1531: cu.accept(visitor, null); sundar@1531: } sundar@1531: } sundar@1531: sundar@1531: // for each ".java" file in directory (recursively) and check it! sundar@1531: function main(dir) { sundar@1531: Files.walk(dir.toPath()). sundar@1531: forEach(function(p) { sundar@1531: var name = p.toFile().absolutePath; sundar@1531: if (name.endsWith(".java")) { sundar@1531: try { sundar@1531: printEmptyCatch(p.toFile().getAbsolutePath()); sundar@1531: } catch (e) { sundar@1531: print(e); sundar@1531: } sundar@1531: } sundar@1531: }); sundar@1531: } sundar@1531: sundar@1531: main(new File(arguments[0]));