1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  * 
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  * 
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  * 
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  * 
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * Nashorn parser API usage.
  26  *
  27  * @test
  28  * @option -scripting
  29  * @run
  30  */
  31 
  32 function Parser() {
  33    // create nashorn parser
  34    this._parser = Parser.create();
  35 }
  36 
  37 // Java types used
  38 Parser.Diagnostic = Java.type("jdk.nashorn.api.tree.Diagnostic");
  39 Parser.SimpleTreeVisitor = Java.type("jdk.nashorn.api.tree.SimpleTreeVisitorES5_1");
  40 Parser.Tree = Java.type("jdk.nashorn.api.tree.Tree");
  41 Parser.List = Java.type("java.util.List");
  42 Parser.Enum = Java.type("java.lang.Enum");
  43 
  44 // function to parse the script and return script friendly object
  45 Parser.prototype.parse = function(name, script, listener) {
  46     var tree = this._parser.parse(name, script, listener);
  47     tree.accept(new Parser.SimpleTreeVisitor(), null);
  48     return this.convert(tree);
  49 }
  50 
  51 Parser.create = function() {
  52     return Java.type("jdk.nashorn.api.tree.Parser").create();
  53 }
  54 
  55 // convert Nashorn parser Tree, Diagnostic as a script friendly object
  56 Parser.prototype.convert = function(tree) {
  57     if (!tree || typeof tree != 'object') {
  58         return tree;
  59     }
  60 
  61     var obj = Object.bindProperties({}, tree);
  62     var result = {};
  63     for (var i in obj) {
  64        var val = obj[i];
  65        if (val instanceof Parser.Tree) {
  66           result[i] = this.convert(val);
  67        } else if (val instanceof Parser.List) {
  68           var arr = new Array(val.size());
  69           for (var j in val) {
  70               arr[j] = this.convert(val[j]);
  71           }
  72       
  73           result[i] = arr;
  74       } else {
  75           switch (typeof val) {
  76               case 'number':
  77               case 'string':
  78               case 'boolean':
  79                   result[i] = String(val);
  80               default:
  81                   if (val instanceof Parser.Enum) {
  82                       result[i] = String(val);
  83                   }
  84           }
  85       }
  86    }
  87    return result;
  88 }
  89 
  90 function processFiles(subdir) {
  91    var File = Java.type("java.io.File");
  92    var files = new File(__DIR__ + subdir).listFiles();
  93    java.util.Arrays.sort(files);
  94    for each (var file in files) {
  95        if (file.name.endsWith(".js")) {
  96            var script = readFully(file);
  97            var parser = new Parser();
  98            var tree = parser.parse(subdir + "/" + file.name, script,
  99                function(diagnostic) {
 100                    print(JSON.stringify(parser.convert(diagnostic), null, 2));
 101                    print(",");
 102                });
 103 
 104            if (tree != null) {
 105                print(JSON.stringify(tree, null, 2));
 106                print(",");
 107            }
 108        }
 109    }
 110 }
 111 
 112 // parse files in parsertests directory
 113 function main() {
 114     print("[");
 115 
 116     processFiles("parsertests");
 117     processFiles("parsernegativetests");
 118 
 119     // parse this file first!
 120     var script = readFully(__FILE__);
 121     var tree = new Parser().parse("parserapi.js", script, null);
 122     print(JSON.stringify(tree, null, 2));
 123     print("]");
 124 }
 125 
 126 main();