#// Usage: jjs -fx javaastviewer.js -- <.java files>

/*
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// This example demonstrates Java subclassing by Java.extend
// and javac Compiler and Tree API. This example also uses
// -fx and javafx TreeView to visualize Java AST as TreeView

if (!$OPTIONS._fx || arguments.length == 0) {
    print("Usage: jjs -fx javaastviewer.js -- <.java files>");
    exit(1);
}

// Java types used
var Enum = Java.type("java.lang.Enum");
var HashSet  = Java.type("java.util.HashSet");
var Name = Java.type("javax.lang.model.element.Name");
var List = Java.type("java.util.List");
var Set  = Java.type("java.util.Set");
var SimpleTreeVisitor = Java.type("com.sun.source.util.SimpleTreeVisitor");
var StringArray = Java.type("java.lang.String[]");
var ToolProvider = Java.type("javax.tools.ToolProvider");
var Tree = Java.type("com.sun.source.tree.Tree");

function javaASTToScriptObject(args) {
    // properties ignored (javac implementation class properties) in AST view.
    // may not be exhaustive - any getAbc would become "abc" property or
    // public field becomes a property of same name.
    var ignoredProps = new HashSet();
    for each (var word in
        ['extending', 'implementing', 'init', 'mods', 'clazz', 'defs',
         'expr', 'tag', 'preferredPosition', 'qualid', 'recvparam',
         'restype', 'params', 'startPosition', 'thrown',
         'tree', 'typarams', 'typetag', 'vartype']) {
        ignoredProps.add(word);
    }

    // get the system compiler tool
    var compiler = ToolProvider.systemJavaCompiler;

    // get standard file manager
    var fileMgr = compiler.getStandardFileManager(null, null, null);

    // make a list of compilation unit from command line argument file names
    // Using Java.to convert script array (arguments) to a Java String[]
    var compUnits = fileMgr.getJavaFileObjects(Java.to(args, StringArray));

    // create a new compilation task
    var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);

    // subclass SimpleTreeVisitor - converts Java AST node to
    // a simple script object by walking through it
    var ConverterVisitor = Java.extend(SimpleTreeVisitor);

    var visitor = new ConverterVisitor() {
        // convert java AST node to a friendly script object
        // which can be viewed. Every node ends up in defaultAction
        // method of SimpleTreeVisitor method.

        defaultAction: function (node, p) {
            var resultObj = {};
            // Nashorn does not iterate properties and methods of Java objects
            // But, we can bind properties of any object (including java objects)
            // to a script object and iterate it!
            var obj = {};
            Object.bindProperties(obj, node);

            // we don't want every property, method of java object
            for (var prop in obj) {
                var val = obj[prop];
                var type = typeof val;
                // ignore 'method' members
                if (type == 'function' || type == 'undefined') {
                    continue;
                }

                // ignore properties from Javac implementation
                // classes - hack by name!!
                if (ignoredProps.contains(prop)) {
                    continue;
                }

                // subtree - recurse it
                if (val instanceof Tree) {
                    resultObj[prop] = visitor.visit(val, p);
                } else if (val instanceof List) {
                    // List of trees - recurse each and make an array
                    var len = val.size();
                    if (len != 0) {
                        var arr = [];
                        for (var j = 0; j < len; j++) {
                            var e = val[j];
                            if (e instanceof Tree) {
                                arr.push(visitor.visit(e, p));
                            }
                        }
                        resultObj[prop] = arr;
                    }
                } else if (val instanceof Set) {
                    // Set - used for modifier flags
                    // make array
                    var len = val.size();
                    if (len != 0) {
                        var arr = [];
                        for each (var e in val) {
                            if (e instanceof Enum || typeof e == 'string') {
                                arr.push(e.toString());
                            }
                        }
                        resultObj[prop] = arr;
                    }
                } else if (val instanceof Enum || val instanceof Name) {
                    // make string for any Enum or Name
                    resultObj[prop] = val.toString();
                } else if (type != 'object') {
                    // primitives 'as is'
                    resultObj[prop] = val;
                }
            }
            return resultObj;
        }
    }

    // top level object with one property for each compilation unit
    var scriptObj = {};
    for each (var cu in task.parse()) {
        scriptObj[cu.sourceFile.name] = cu.accept(visitor, null);
    }

    return scriptObj;
}

// JavaFX classes used
var StackPane = Java.type("javafx.scene.layout.StackPane");
var Scene     = Java.type("javafx.scene.Scene");
var TreeItem  = Java.type("javafx.scene.control.TreeItem");
var TreeView  = Java.type("javafx.scene.control.TreeView");

// Create a javafx TreeItem to view a script object
function treeItemForObject(obj, name) {
    var item = new TreeItem(name);
    for (var prop in obj) {
       var node = obj[prop];
       if (typeof node == 'object') {
           if (node == null) {
               // skip nulls
               continue;
           }
           var subitem = treeItemForObject(node, prop);
       } else {
           var subitem = new TreeItem(prop + ": " + node);
       }
       item.children.add(subitem);
    }

    item.expanded = true;
    return item;
}

var commandArgs = arguments;

// JavaFX start method
function start(stage) {
    var obj = javaASTToScriptObject(commandArgs);
    stage.title = "Java AST Viewer"
    var rootItem = treeItemForObject(obj, "AST");
    rootItem.expanded = true;
    var tree = new TreeView(rootItem);
    var root = new StackPane();
    root.children.add(tree);
    stage.scene = new Scene(root, 300, 450);
    stage.show();
}
