--- old/src/sample/nashorn/prettyprinter.js 2020-04-15 18:54:25.000000000 +0530 +++ /dev/null 2020-04-15 18:54:25.000000000 +0530 @@ -1,642 +0,0 @@ -/* - * Copyright (c) 2015, 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 script is a AST pretty printer for ECMAScript. It uses - * Nashorn parser API to parser given script and uses tree visitor - * to pretty print the AST to stdout as a script string. - */ - -var File = Java.type("java.io.File"); -var file = arguments.length == 0? new File(__FILE__) : new File(arguments[0]); -if (! file.isFile()) { - print(arguments[0] + " is not a file"); - exit(1); -} - -// Java classes used -var ArrayAccess = Java.type("jdk.nashorn.api.tree.ArrayAccessTree"); -var Block = Java.type("jdk.nashorn.api.tree.BlockTree"); -var FunctionDeclaration = Java.type("jdk.nashorn.api.tree.FunctionDeclarationTree"); -var FunctionExpression = Java.type("jdk.nashorn.api.tree.FunctionExpressionTree"); -var Identifier = Java.type("jdk.nashorn.api.tree.IdentifierTree"); -var Kind = Java.type("jdk.nashorn.api.tree.Tree.Kind"); -var MemberSelect = Java.type("jdk.nashorn.api.tree.MemberSelectTree"); -var ObjectLiteral = Java.type("jdk.nashorn.api.tree.ObjectLiteralTree"); -var Parser = Java.type("jdk.nashorn.api.tree.Parser"); -var SimpleTreeVisitor = Java.type("jdk.nashorn.api.tree.SimpleTreeVisitorES5_1"); -var System = Java.type("java.lang.System"); - -// make a nashorn parser -var parser = Parser.create("-scripting", "--const-as-var"); - -// symbols for nashorn operators -var operatorSymbols = { - POSTFIX_INCREMENT: "++", - POSTFIX_DECREMENT: "--", - PREFIX_INCREMENT: "++", - PREFIX_DECREMENT: "--", - UNARY_PLUS: "+", - UNARY_MINUS: "-", - BITWISE_COMPLEMENT: "~", - LOGICAL_COMPLEMENT: "!", - DELETE: "delete ", - TYPEOF: "typeof ", - VOID: "void ", - COMMA: ",", - MULTIPLY: "*", - DIVIDE: "/", - REMINDER: "%", - PLUS: "+", - MINUS: "-", - LEFT_SHIFT: "<<", - RIGHT_SHIFT: ">>", - UNSIGNED_RIGHT_SHIFT: ">>>", - LESS_THAN: "<", - GREATER_THAN: ">", - LESS_THAN_EQUAL: "<=", - GREATER_THAN_EQUAL: ">=", - IN: "in", - EQUAL_TO: "==", - NOT_EQUAL_TO: "!=", - STRICT_EQUAL_TO: "===", - STRICT_NOT_EQUAL_TO: "!==", - AND: "&", - XOR: "^", - OR: "|", - CONDITIONAL_AND: "&&", - CONDITIONAL_OR: "||", - MULTIPLY_ASSIGNMENT: "*=", - DIVIDE_ASSIGNMENT: "/=", - REMINDER_ASSIGNMENT: "%=", - PLUS_ASSIGNMENT: "+=", - MINUS_ASSIGNMENT: "-=", - LEFT_SHIFT_ASSIGNMENT: "<<=", - RIGHT_SHIFT_ASSIGNMENT: ">>=", - UNSIGNED_RIGHT_SHIFT_ASSIGNMENT: ">>>=", - AND_ASSIGNMENT: "&=", - XOR_ASSIGNMENT: "^=", - OR_ASSIGNMENT: "|=" -}; - -function operatorOf(kind) { - var name = kind.name(); - if (name in operatorSymbols) { - return operatorSymbols[name]; - } - throw "invalid operator: " + name; -} - -var gprint = print; - -function prettyPrint(file) { - var ast = parser.parse(file, gprint); - if (!ast) { - // failed to parse. don't print anything! - return; - } - - // AST visitor - var visitor; - // current indent level - var indentLevel = 0; - var out = System.out; - - function print(obj) { - out.print(String(obj)); - } - - function println(obj) { - obj? out.println(String(obj)) : out.println(); - } - - // semicolon and end-of-line - function eol() { - println(";"); - } - - // print indentation - 4 spaces per level - function indent() { - for (var i = 0; i < indentLevel; i++) { - // 4 spaces per indent level - print(" "); - } - } - - // escape string literals - function escapeString(str) { - // FIXME: incomplete, revisit again! - return str.replace(/[\\"']/g, '\\$&') - } - - // print a single statement (could be a block too) - function printStatement(stat, extra, end) { - if (stat instanceof Block) { - println(" {"); - printStatements(stat.statements, extra); - indent(); - print('}'); - typeof end != "undefined"? print(end) : println(); - } else { - println(); - indentLevel++; - try { - stat.accept(visitor, extra); - } finally { - indentLevel--; - } - } - } - - // print a statement list - function printStatements(stats, extra) { - indentLevel++; - try { - for each (var stat in stats) { - stat.accept(visitor, extra); - } - } finally { - indentLevel--; - } - } - - // function arguments, array literal elements. - function printCommaList(args, extra) { - var len = args.length; - for (var i = 0; i < len; i++) { - args[i].accept(visitor, extra); - if (i != len - 1) { - print(", "); - } - } - } - - // print function declarations and expressions - function printFunction(func, extra, end) { - // extra lines around function declarations for clarity - var funcDecl = (func instanceof FunctionDeclaration); - if (funcDecl) { - println(); - indent(); - } - print("function "); - if (func.name) { - print(func.name.name); - } - printFunctionBody(func, extra, end); - if (funcDecl) { - println(); - } - } - - // print function declaration/expression body - function printFunctionBody(func, extra, end) { - print('('); - var params = func.parameters; - if (params) { - printCommaList(params); - } - print(')'); - printStatement(func.body, extra, end); - } - - // print object literal property - function printProperty(node, extra, comma) { - var key = node.key; - var val = node.value; - var getter = node.getter; - var setter = node.setter; - - if (getter) { - print("get "); - } else if (setter) { - print("set "); - } - - if (typeof key == "string") { - print(key); - } else { - key.accept(visitor, extra); - } - - if (val) { - print(": "); - if (val instanceof FunctionExpression) { - printFunction(val, extra, comma? ',' : undefined); - } else { - val.accept(visitor, extra); - if (comma) print(','); - } - } else if (getter) { - printFunctionBody(getter, extra, comma? ',' : undefined); - } else if (setter) { - printFunctionBody(setter, extra, comma? ',' : undefined); - } - } - - - ast.accept(visitor = new (Java.extend(SimpleTreeVisitor)) { - visitAssignment: function(node, extra) { - node.variable.accept(visitor, extra); - print(" = "); - node.expression.accept(visitor, extra); - }, - - visitCompoundAssignment: function(node, extra) { - node.variable.accept(visitor, extra); - print(' ' + operatorOf(node.kind) + ' '); - node.expression.accept(visitor, extra); - }, - - visitBinary: function(node, extra) { - node.leftOperand.accept(visitor, extra); - print(' ' + operatorOf(node.kind) + ' '); - node.rightOperand.accept(visitor, extra); - }, - - visitBlock: function(node, extra) { - indent(); - println('{'); - printStatements(node.statements, extra); - indent(); - println('}'); - }, - - visitBreak: function(node, extra) { - indent(); - print("break"); - if (node.label) { - print(' ' + node.label); - } - eol(); - }, - - visitCase: function(node, extra) { - var expr = node.expression; - indent(); - if (expr) { - print("case "); - expr.accept(visitor, extra); - println(':'); - } else { - println("default:"); - } - - printStatements(node.statements, extra); - }, - - visitCatch: function(node, extra) { - indent(); - print("catch (" + node.parameter.name); - var cond = node.condition; - if (cond) { - print(" if "); - cond.accept(visitor, extra); - } - print(')'); - printStatement(node.block); - }, - - visitConditionalExpression: function(node, extra) { - print('('); - node.condition.accept(visitor, extra); - print(" ? "); - node.trueExpression.accept(visitor, extra); - print(" : "); - node.falseExpression.accept(visitor, extra); - print(')'); - }, - - visitContinue: function(node, extra) { - indent(); - print("continue"); - if (node.label) { - print(' ' + node.label); - } - eol(); - }, - - visitDebugger: function(node, extra) { - indent(); - print("debugger"); - eol(); - }, - - visitDoWhileLoop: function(node, extra) { - indent(); - print("do"); - printStatement(node.statement, extra); - indent(); - print("while ("); - node.condition.accept(visitor, extra); - print(')'); - eol(); - }, - - visitExpressionStatement: function(node, extra) { - indent(); - var expr = node.expression; - var objLiteral = expr instanceof ObjectLiteral; - if (objLiteral) { - print('('); - } - - expr.accept(visitor, extra); - if (objLiteral) { - print(')'); - } - eol(); - }, - - visitForLoop: function(node, extra) { - indent(); - print("for ("); - if (node.initializer) { - node.initializer.accept(visitor, extra); - } - - print(';'); - if (node.condition) { - node.condition.accept(visitor, extra); - } - print(';'); - if (node.update) { - node.update.accept(visitor, extra); - } - print(')'); - printStatement(node.statement); - }, - - visitForInLoop: function(node, extra) { - indent(); - print("for "); - if (node.forEach) { - print("each "); - } - print('('); - node.variable.accept(visitor, extra); - print(" in "); - node.expression.accept(visitor, extra); - print(')'); - printStatement(node.statement); - }, - - visitFunctionCall: function(node, extra) { - var func = node.functionSelect; - // We need parens around function selected - // in many non-simple cases. Eg. function - // expression created and called immediately. - // Such parens are not preserved in AST and so - // introduce here. - var simpleFunc = - (func instanceof ArrayAccess) || - (func instanceof Identifier) || - (func instanceof MemberSelect); - if (! simpleFunc) { - print('('); - } - func.accept(visitor, extra); - if (! simpleFunc) { - print(')'); - } - print('('); - printCommaList(node.arguments, extra); - print(')'); - }, - - visitFunctionDeclaration: function(node, extra) { - printFunction(node, extra); - }, - - visitFunctionExpression: function(node, extra) { - printFunction(node, extra); - }, - - visitIdentifier: function(node, extra) { - print(node.name); - }, - - visitIf: function(node, extra) { - indent(); - print("if ("); - node.condition.accept(visitor, extra); - print(')'); - printStatement(node.thenStatement); - var el = node.elseStatement; - if (el) { - indent(); - print("else"); - printStatement(el); - } - }, - - visitArrayAccess: function(node, extra) { - node.expression.accept(visitor, extra); - print('['); - node.index.accept(visitor, extra); - print(']'); - }, - - visitArrayLiteral: function(node, extra) { - print('['); - printCommaList(node.elements); - print(']'); - }, - - visitLabeledStatement: function(node, extra) { - indent(); - print(node.label); - print(':'); - printStatement(node.statement); - }, - - visitLiteral: function(node, extra) { - var val = node.value; - if (typeof val == "string") { - print("'" + escapeString(val) + "'"); - } else { - print(val); - } - }, - - visitParenthesized: function(node, extra) { - print('('); - node.expression.accept(visitor, extra); - print(')'); - }, - - visitReturn: function(node, extra) { - indent(); - print("return"); - if (node.expression) { - print(' '); - node.expression.accept(visitor, extra); - } - eol(); - }, - - visitMemberSelect: function(node, extra) { - node.expression.accept(visitor, extra); - print('.' + node.identifier); - }, - - visitNew: function(node, extra) { - print("new "); - node.constructorExpression.accept(visitor, extra); - }, - - visitObjectLiteral: function(node, extra) { - println('{'); - indentLevel++; - try { - var props = node.properties; - var len = props.length; - for (var p = 0; p < len; p++) { - var last = (p == len - 1); - indent(); - printProperty(props[p], extra, !last); - println(); - } - } finally { - indentLevel--; - } - indent(); - print('}'); - }, - - visitRegExpLiteral: function(node, extra) { - print('/' + node.pattern + '/'); - print(node.options); - }, - - visitEmptyStatement: function(node, extra) { - indent(); - eol(); - }, - - visitSwitch: function(node, extra) { - indent(); - print("switch ("); - node.expression.accept(visitor, extra); - println(") {"); - indentLevel++; - try { - for each (var c in node.cases) { - c.accept(visitor, extra); - } - } finally { - indentLevel--; - } - indent(); - println('}'); - }, - - visitThrow: function(node, extra) { - indent(); - print("throw "); - node.expression.accept(visitor, extra); - eol(); - }, - - visitCompilationUnit: function(node, extra) { - for each (var stat in node.sourceElements) { - stat.accept(visitor, extra); - } - }, - - visitTry: function(node, extra) { - indent(); - print("try"); - printStatement(node.block); - var catches = node.catches; - for each (var c in catches) { - c.accept(visitor, extra); - } - var finallyBlock = node.finallyBlock; - if (finallyBlock) { - indent(); - print("finally"); - printStatement(finallyBlock); - } - }, - - visitInstanceOf: function(node, extra) { - node.expression.accept(visitor, extra); - print(" instanceof "); - node.type.accept(visitor, extra); - }, - - visitUnary: function(node, extra) { - var kind = node.kind; - var prefix = kind != Kind.POSTFIX_INCREMENT && kind != Kind.POSTFIX_DECREMENT; - if (prefix) { - print(operatorOf(kind)); - } - node.expression.accept(visitor, extra); - if (!prefix) { - print(operatorOf(kind)); - } - }, - - visitVariable: function(node, extra) { - indent(); - print("var " + node.binding.name); - var init = node.initializer; - if (init) { - print(" = "); - if (init instanceof FunctionExpression) { - printFunction(init, extra, ""); - } else { - init.accept(visitor, extra); - } - } - eol(); - }, - - visitWhileLoop: function(node, extra) { - indent(); - print("while ("); - node.condition.accept(visitor, extra); - print(')'); - printStatement(node.statement); - }, - - visitWith: function(node, extra) { - indent(); - print("with ("); - node.scope.accept(visitor, extra); - print(')'); - printStatement(node.statement); - } - }, null); -} - -prettyPrint(file);