ParserImpl.java revision 1217:6490bba01455
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
26package jdk.nashorn.api.tree;
27
28import java.io.File;
29import java.io.IOException;
30import java.io.PrintWriter;
31import java.io.Reader;
32import java.net.URL;
33import java.nio.file.Path;
34import java.util.Map;
35import java.util.Objects;
36import jdk.nashorn.api.scripting.NashornException;
37import jdk.nashorn.api.scripting.ScriptObjectMirror;
38import jdk.nashorn.internal.ir.FunctionNode;
39import jdk.nashorn.internal.runtime.Context;
40import jdk.nashorn.internal.runtime.ErrorManager;
41import jdk.nashorn.internal.runtime.JSType;
42import jdk.nashorn.internal.runtime.ParserException;
43import jdk.nashorn.internal.runtime.ScriptEnvironment;
44import jdk.nashorn.internal.runtime.Source;
45import jdk.nashorn.internal.runtime.options.Options;
46
47final 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 static CompilationUnitTree translate(final FunctionNode node) {
143        return new IRTranslator().translate(node);
144    }
145}
146