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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.api.tree; 27 28 import java.io.File; 29 import java.io.IOException; 30 import java.io.PrintWriter; 31 import java.io.Reader; 32 import java.net.URL; 33 import java.nio.file.Path; 34 import java.util.Map; 35 import java.util.Objects; 36 import jdk.nashorn.api.scripting.NashornException; 37 import jdk.nashorn.api.scripting.ScriptObjectMirror; 38 import jdk.nashorn.internal.ir.FunctionNode; 39 import jdk.nashorn.internal.runtime.Context; 40 import jdk.nashorn.internal.runtime.ErrorManager; 41 import jdk.nashorn.internal.runtime.JSType; 42 import jdk.nashorn.internal.runtime.ParserException; 43 import jdk.nashorn.internal.runtime.ScriptEnvironment; 44 import jdk.nashorn.internal.runtime.Source; 45 import jdk.nashorn.internal.runtime.options.Options; 46 47 final class ParserImpl implements Parser { 48 49 private final ScriptEnvironment env; 50 51 ParserImpl(final String... args) throws IllegalArgumentException { 52 Objects.requireNonNull(args); 53 Options options = new Options("nashorn"); 54 options.process(args); 55 this.env = new ScriptEnvironment(options, 56 new PrintWriter(System.out), new PrintWriter(System.err)); 57 } 58 59 @Override 60 public CompilationUnitTree parse(final File file, final DiagnosticListener listener) throws IOException, NashornException { 61 Objects.requireNonNull(file); 62 final Source src = Source.sourceFor(file.getName(), file); 63 return translate(makeParser(src, listener).parse()); 64 } 65 66 @Override 67 public CompilationUnitTree parse(final Path path, final DiagnosticListener listener) throws IOException, NashornException { 68 Objects.requireNonNull(path); 69 final Source src = Source.sourceFor(path.toString(), path); 70 return translate(makeParser(src, listener).parse()); 71 } 72 73 @Override 74 public CompilationUnitTree parse(final URL url, final DiagnosticListener listener) throws IOException, NashornException { 75 final Source src = Source.sourceFor(url.toString(), url); 76 return translate(makeParser(src, listener).parse()); 77 } 78 79 @Override 80 public CompilationUnitTree parse(final String name, final Reader reader, final DiagnosticListener listener) throws IOException, NashornException { 81 Objects.requireNonNull(name); 82 Objects.requireNonNull(reader); 83 final Source src = Source.sourceFor(name, reader); 84 return translate(makeParser(src, listener).parse()); 85 } 86 87 @Override 88 public CompilationUnitTree parse(final String name, final String code, final DiagnosticListener listener) throws NashornException { 89 final Source src = Source.sourceFor(name, code); 90 return translate(makeParser(src, listener).parse()); 91 } 92 93 @Override 94 public CompilationUnitTree parse(final ScriptObjectMirror scriptObj, final DiagnosticListener listener) throws NashornException { 95 Objects.requireNonNull(scriptObj); 96 final Map<?,?> map = scriptObj; 97 if (map.containsKey("script") && map.containsKey("name")) { 98 final String script = JSType.toString(map.get("script")); 99 final String name = JSType.toString(map.get("name")); 100 final Source src = Source.sourceFor(name, script); 101 return translate(makeParser(src, listener).parse()); 102 } else { 103 throw new IllegalArgumentException("can't find 'script' and 'name' properties"); 104 } 105 } 106 107 private jdk.nashorn.internal.parser.Parser makeParser(final Source source, final DiagnosticListener listener) { 108 final ErrorManager errMgr = listener != null? new ListenerErrorManager(listener) : new Context.ThrowErrorManager(); 109 return new jdk.nashorn.internal.parser.Parser(env, source, errMgr); 110 } 111 112 private static class ListenerErrorManager extends ErrorManager { 113 private final DiagnosticListener listener; 114 115 ListenerErrorManager(final DiagnosticListener listener) { 116 // null check 117 listener.getClass(); 118 this.listener = listener; 119 } 120 121 @Override 122 public void error(final String msg) { 123 error(new ParserException(msg)); 124 } 125 126 @Override 127 public void error(final ParserException e) { 128 listener.report(new DiagnosticImpl(e, Diagnostic.Kind.ERROR)); 129 } 130 131 @Override 132 public void warning(final String msg) { 133 warning(new ParserException(msg)); 134 } 135 136 @Override 137 public void warning(final ParserException e) { 138 listener.report(new DiagnosticImpl(e, Diagnostic.Kind.WARNING)); 139 } 140 } 141 142 private CompilationUnitTree translate(final FunctionNode node) { 143 return new IRTranslator().translate(node); 144 } 145 }