find_nonfinals.js revision 973:d564abed1e6a
1/*
2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 *   - Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 *
11 *   - Redistributions in binary form must reproduce the above copyright
12 *     notice, this list of conditions and the following disclaimer in the
13 *     documentation and/or other materials provided with the distribution.
14 *
15 *   - Neither the name of Oracle nor the names of its
16 *     contributors may be used to endorse or promote products derived
17 *     from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/**
33 * Nashorn project uses "final" modifier for method parameters
34 * (like 'val' of Scala). This tool finds method parameters that
35 * miss final modifier.
36 */
37
38// Usage: jjs -J-Djava.ext.dirs=<your_nashorn_jar_dir> find_nonfinals.js
39
40var Class = Java.type("java.lang.Class");
41var System = Java.type("java.lang.System");
42var File = Java.type("java.io.File");
43var JarFile = Java.type("java.util.jar.JarFile");
44var Modifier = Java.type("java.lang.reflect.Modifier");
45
46// locate nashorn.jar from java.ext.dirs
47function findNashorn() {
48    var paths = System.getProperty("java.ext.dirs").split(':');
49    for each (var p in paths) {
50        var nashorn = p + File.separator + "nashorn.jar";
51        if (new File(nashorn).exists()) {
52            return nashorn;
53        }
54    }
55}
56
57// analyze a single Class and print info on non-final parameters
58function analyzeClass(cls) {
59    var methods = cls.getDeclaredMethods();
60    for each (var method in methods) {
61        // this requires -parameters option when compiling java sources
62        var params = method.parameters;
63        for each (var p in params) {
64           var modifiers = p.modifiers;
65           if (!Modifier.isFinal(modifiers)) {
66               if (! method.name.startsWith("access$")) {
67                   print(method);
68                   print(" ->", p);
69               }
70           }
71        }
72    }
73}
74
75var jarFile = findNashorn();
76// load each class and use reflection to analyze each Class
77new JarFile(jarFile).stream().forEach(
78    function(entry) {
79        var name = entry.name;
80        if (name.endsWith(".class")) {
81            var clsName = name.substring(0, name.lastIndexOf('.class'));
82            clsName = clsName.replace(/\//g, '.');
83            var cls = Class.forName(clsName);
84            analyzeClass(cls);
85        }
86    }
87)
88