Path: blob/aarch64-shenandoah-jdk8u272-b10/nashorn/samples/javaastviewer.js
32278 views
#// Usage: jjs -fx javaastviewer.js -- <.java files>12/*3* Copyright (c) 2014, 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// This example demonstrates Java subclassing by Java.extend34// and javac Compiler and Tree API. This example also uses35// -fx and javafx TreeView to visualize Java AST as TreeView3637if (!$OPTIONS._fx || arguments.length == 0) {38print("Usage: jjs -fx javaastviewer.js -- <.java files>");39exit(1);40}4142// Java types used43var Enum = Java.type("java.lang.Enum");44var HashSet = Java.type("java.util.HashSet");45var Name = Java.type("javax.lang.model.element.Name");46var List = Java.type("java.util.List");47var Set = Java.type("java.util.Set");48var SimpleTreeVisitor = Java.type("com.sun.source.util.SimpleTreeVisitor");49var StringArray = Java.type("java.lang.String[]");50var ToolProvider = Java.type("javax.tools.ToolProvider");51var Tree = Java.type("com.sun.source.tree.Tree");5253function javaASTToScriptObject(args) {54// properties ignored (javac implementation class properties) in AST view.55// may not be exhaustive - any getAbc would become "abc" property or56// public field becomes a property of same name.57var ignoredProps = new HashSet();58for each (var word in59['extending', 'implementing', 'init', 'mods', 'clazz', 'defs',60'expr', 'tag', 'preferredPosition', 'qualid', 'recvparam',61'restype', 'params', 'startPosition', 'thrown',62'tree', 'typarams', 'typetag', 'vartype']) {63ignoredProps.add(word);64}6566// get the system compiler tool67var compiler = ToolProvider.systemJavaCompiler;6869// get standard file manager70var fileMgr = compiler.getStandardFileManager(null, null, null);7172// make a list of compilation unit from command line argument file names73// Using Java.to convert script array (arguments) to a Java String[]74var compUnits = fileMgr.getJavaFileObjects(Java.to(args, StringArray));7576// create a new compilation task77var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);7879// subclass SimpleTreeVisitor - converts Java AST node to80// a simple script object by walking through it81var ConverterVisitor = Java.extend(SimpleTreeVisitor);8283var visitor = new ConverterVisitor() {84// convert java AST node to a friendly script object85// which can be viewed. Every node ends up in defaultAction86// method of SimpleTreeVisitor method.8788defaultAction: function (node, p) {89var resultObj = {};90// Nashorn does not iterate properties and methods of Java objects91// But, we can bind properties of any object (including java objects)92// to a script object and iterate it!93var obj = {};94Object.bindProperties(obj, node);9596// we don't want every property, method of java object97for (var prop in obj) {98var val = obj[prop];99var type = typeof val;100// ignore 'method' members101if (type == 'function' || type == 'undefined') {102continue;103}104105// ignore properties from Javac implementation106// classes - hack by name!!107if (ignoredProps.contains(prop)) {108continue;109}110111// subtree - recurse it112if (val instanceof Tree) {113resultObj[prop] = visitor.visit(val, p);114} else if (val instanceof List) {115// List of trees - recurse each and make an array116var len = val.size();117if (len != 0) {118var arr = [];119for (var j = 0; j < len; j++) {120var e = val[j];121if (e instanceof Tree) {122arr.push(visitor.visit(e, p));123}124}125resultObj[prop] = arr;126}127} else if (val instanceof Set) {128// Set - used for modifier flags129// make array130var len = val.size();131if (len != 0) {132var arr = [];133for each (var e in val) {134if (e instanceof Enum || typeof e == 'string') {135arr.push(e.toString());136}137}138resultObj[prop] = arr;139}140} else if (val instanceof Enum || val instanceof Name) {141// make string for any Enum or Name142resultObj[prop] = val.toString();143} else if (type != 'object') {144// primitives 'as is'145resultObj[prop] = val;146}147}148return resultObj;149}150}151152// top level object with one property for each compilation unit153var scriptObj = {};154for each (var cu in task.parse()) {155scriptObj[cu.sourceFile.name] = cu.accept(visitor, null);156}157158return scriptObj;159}160161// JavaFX classes used162var StackPane = Java.type("javafx.scene.layout.StackPane");163var Scene = Java.type("javafx.scene.Scene");164var TreeItem = Java.type("javafx.scene.control.TreeItem");165var TreeView = Java.type("javafx.scene.control.TreeView");166167// Create a javafx TreeItem to view a script object168function treeItemForObject(obj, name) {169var item = new TreeItem(name);170for (var prop in obj) {171var node = obj[prop];172if (typeof node == 'object') {173if (node == null) {174// skip nulls175continue;176}177var subitem = treeItemForObject(node, prop);178} else {179var subitem = new TreeItem(prop + ": " + node);180}181item.children.add(subitem);182}183184item.expanded = true;185return item;186}187188var commandArgs = arguments;189190// JavaFX start method191function start(stage) {192var obj = javaASTToScriptObject(commandArgs);193stage.title = "Java AST Viewer"194var rootItem = treeItemForObject(obj, "AST");195rootItem.expanded = true;196var tree = new TreeView(rootItem);197var root = new StackPane();198root.children.add(tree);199stage.scene = new Scene(root, 300, 450);200stage.show();201}202203204