ParserImpl.java revision 1309:15a67b4f8935
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        final Source src = Source.sourceFor(Objects.requireNonNull(file).getName(), file);
62        return translate(makeParser(src, listener).parse());
63    }
64
65    @Override
66    public CompilationUnitTree parse(final Path path, final DiagnosticListener listener) throws IOException, NashornException {
67        final Source src = Source.sourceFor(Objects.requireNonNull(path).toString(), path);
68        return translate(makeParser(src, listener).parse());
69    }
70
71    @Override
72    public CompilationUnitTree parse(final URL url, final DiagnosticListener listener) throws IOException, NashornException {
73        final Source src = Source.sourceFor(url.toString(), url);
74        return translate(makeParser(src, listener).parse());
75    }
76
77    @Override
78    public CompilationUnitTree parse(final String name, final Reader reader, final DiagnosticListener listener) throws IOException, NashornException {
79        final Source src = Source.sourceFor(Objects.requireNonNull(name), Objects.requireNonNull(reader));
80        return translate(makeParser(src, listener).parse());
81    }
82
83    @Override
84    public CompilationUnitTree parse(final String name, final String code, final DiagnosticListener listener) throws NashornException {
85        final Source src = Source.sourceFor(name, code);
86        return translate(makeParser(src, listener).parse());
87    }
88
89    @Override
90    public CompilationUnitTree parse(final ScriptObjectMirror scriptObj, final DiagnosticListener listener) throws NashornException {
91        final Map<?,?> map = Objects.requireNonNull(scriptObj);
92        if (map.containsKey("script") && map.containsKey("name")) {
93            final String script = JSType.toString(map.get("script"));
94            final String name   = JSType.toString(map.get("name"));
95            final Source src = Source.sourceFor(name, script);
96            return translate(makeParser(src, listener).parse());
97        } else {
98            throw new IllegalArgumentException("can't find 'script' and 'name' properties");
99        }
100    }
101
102    private jdk.nashorn.internal.parser.Parser makeParser(final Source source, final DiagnosticListener listener) {
103        final ErrorManager errMgr = listener != null? new ListenerErrorManager(listener) : new Context.ThrowErrorManager();
104        return new jdk.nashorn.internal.parser.Parser(env, source, errMgr);
105    }
106
107    private static class ListenerErrorManager extends ErrorManager {
108        private final DiagnosticListener listener;
109
110        ListenerErrorManager(final DiagnosticListener listener) {
111            // null check
112            listener.getClass();
113            this.listener = listener;
114        }
115
116        @Override
117        public void error(final String msg) {
118            error(new ParserException(msg));
119        }
120
121        @Override
122        public void error(final ParserException e) {
123            listener.report(new DiagnosticImpl(e, Diagnostic.Kind.ERROR));
124        }
125
126        @Override
127        public void warning(final String msg) {
128            warning(new ParserException(msg));
129        }
130
131        @Override
132        public void warning(final ParserException e) {
133            listener.report(new DiagnosticImpl(e, Diagnostic.Kind.WARNING));
134        }
135    }
136
137    private static CompilationUnitTree translate(final FunctionNode node) {
138        return new IRTranslator().translate(node);
139    }
140}
141