nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ParserImpl.java
changeset 39662 e2b36a3779b9
parent 31094 7a9fa21da791
child 41422 97eda72f53b6
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ParserImpl.java	Wed Jul 05 21:57:11 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ParserImpl.java	Tue Jul 12 21:18:13 2016 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.nashorn.api.tree;
 
 import java.io.File;
@@ -31,6 +30,7 @@
 import java.io.Reader;
 import java.net.URL;
 import java.nio.file.Path;
+import java.util.Arrays;
 import java.util.Map;
 import java.util.Objects;
 import jdk.nashorn.api.scripting.NashornException;
@@ -47,51 +47,94 @@
 final class ParserImpl implements Parser {
 
     private final ScriptEnvironment env;
+    private final boolean moduleMode;
 
     ParserImpl(final String... args) throws IllegalArgumentException {
-       Objects.requireNonNull(args);
-       Options options = new Options("nashorn");
-       options.process(args);
-       this.env = new ScriptEnvironment(options,
-               new PrintWriter(System.out), new PrintWriter(System.err));
+        Objects.requireNonNull(args);
+
+        // handle the parser specific "--es6-module" option
+        boolean seenModuleOption = false;
+        for (int idx = 0; idx < args.length; idx++) {
+            final String opt = args[idx];
+            if (opt.equals("--es6-module")) {
+                seenModuleOption = true;
+                /*
+                 * Nashorn parser does not understand parser API specific
+                 * option. This option implies --language=es6. So, we change
+                 * the option to --language=es6. Note that if user specified
+                 * --language=es6 explicitly, that is okay. Nashorn tolerates
+                 * repeated options!
+                 */
+                args[idx] = "--language=es6";
+                break;
+            }
+        }
+        this.moduleMode = seenModuleOption;
+
+        // append "--parse-only to signal to the Nashorn that it
+        // is being used in "parse only" mode.
+        String[] newArgs = Arrays.copyOf(args, args.length + 1, String[].class);
+        newArgs[args.length] = "--parse-only";
+        Options options = new Options("nashorn");
+        options.process(newArgs);
+        this.env = new ScriptEnvironment(options,
+                new PrintWriter(System.out), new PrintWriter(System.err));
     }
 
     @Override
     public CompilationUnitTree parse(final File file, final DiagnosticListener listener) throws IOException, NashornException {
+        if (moduleMode) {
+            return parseModule(file, listener);
+        }
         final Source src = Source.sourceFor(Objects.requireNonNull(file).getName(), file);
         return translate(makeParser(src, listener).parse());
     }
 
     @Override
     public CompilationUnitTree parse(final Path path, final DiagnosticListener listener) throws IOException, NashornException {
+        if (moduleMode) {
+            return parseModule(path, listener);
+        }
         final Source src = Source.sourceFor(Objects.requireNonNull(path).toString(), path);
         return translate(makeParser(src, listener).parse());
     }
 
     @Override
     public CompilationUnitTree parse(final URL url, final DiagnosticListener listener) throws IOException, NashornException {
+        if (moduleMode) {
+            return parseModule(url, listener);
+        }
         final Source src = Source.sourceFor(url.toString(), url);
         return translate(makeParser(src, listener).parse());
     }
 
     @Override
     public CompilationUnitTree parse(final String name, final Reader reader, final DiagnosticListener listener) throws IOException, NashornException {
+        if (moduleMode) {
+            return parseModule(name, reader, listener);
+        }
         final Source src = Source.sourceFor(Objects.requireNonNull(name), Objects.requireNonNull(reader));
         return translate(makeParser(src, listener).parse());
     }
 
     @Override
     public CompilationUnitTree parse(final String name, final String code, final DiagnosticListener listener) throws NashornException {
+        if (moduleMode) {
+            return parseModule(name, code, listener);
+        }
         final Source src = Source.sourceFor(name, code);
         return translate(makeParser(src, listener).parse());
     }
 
     @Override
     public CompilationUnitTree parse(final ScriptObjectMirror scriptObj, final DiagnosticListener listener) throws NashornException {
-        final Map<?,?> map = Objects.requireNonNull(scriptObj);
+        if (moduleMode) {
+            return parseModule(scriptObj, listener);
+        }
+        final Map<?, ?> map = Objects.requireNonNull(scriptObj);
         if (map.containsKey("script") && map.containsKey("name")) {
             final String script = JSType.toString(map.get("script"));
-            final String name   = JSType.toString(map.get("name"));
+            final String name = JSType.toString(map.get("name"));
             final Source src = Source.sourceFor(name, script);
             return translate(makeParser(src, listener).parse());
         } else {
@@ -99,12 +142,55 @@
         }
     }
 
+    private CompilationUnitTree parseModule(File file, DiagnosticListener listener) throws IOException, NashornException {
+        final Source src = Source.sourceFor(Objects.requireNonNull(file).getName(), file);
+        return makeModule(src, listener);
+    }
+
+    private CompilationUnitTree parseModule(Path path, DiagnosticListener listener) throws IOException, NashornException {
+        final Source src = Source.sourceFor(Objects.requireNonNull(path).toString(), path);
+        return makeModule(src, listener);
+    }
+
+    private CompilationUnitTree parseModule(URL url, DiagnosticListener listener) throws IOException, NashornException {
+        final Source src = Source.sourceFor(url.toString(), url);
+        return makeModule(src, listener);
+    }
+
+    private CompilationUnitTree parseModule(String name, Reader reader, DiagnosticListener listener) throws IOException, NashornException {
+        final Source src = Source.sourceFor(Objects.requireNonNull(name), Objects.requireNonNull(reader));
+        return makeModule(src, listener);
+    }
+
+    private CompilationUnitTree parseModule(String name, String code, DiagnosticListener listener) throws NashornException {
+        final Source src = Source.sourceFor(name, code);
+        return makeModule(src, listener);
+    }
+
+    private CompilationUnitTree parseModule(ScriptObjectMirror scriptObj, DiagnosticListener listener) throws NashornException {
+        final Map<?, ?> map = Objects.requireNonNull(scriptObj);
+        if (map.containsKey("script") && map.containsKey("name")) {
+            final String script = JSType.toString(map.get("script"));
+            final String name = JSType.toString(map.get("name"));
+            final Source src = Source.sourceFor(name, script);
+            return makeModule(src, listener);
+        } else {
+            throw new IllegalArgumentException("can't find 'script' and 'name' properties");
+        }
+    }
+
+    private CompilationUnitTree makeModule(Source src, DiagnosticListener listener) {
+        final FunctionNode modFunc = makeParser(src, listener).parseModule(src.getName());
+        return new IRTranslator().translate(modFunc);
+    }
+
     private jdk.nashorn.internal.parser.Parser makeParser(final Source source, final DiagnosticListener listener) {
-        final ErrorManager errMgr = listener != null? new ListenerErrorManager(listener) : new Context.ThrowErrorManager();
+        final ErrorManager errMgr = listener != null ? new ListenerErrorManager(listener) : new Context.ThrowErrorManager();
         return new jdk.nashorn.internal.parser.Parser(env, source, errMgr);
     }
 
     private static class ListenerErrorManager extends ErrorManager {
+
         private final DiagnosticListener listener;
 
         ListenerErrorManager(final DiagnosticListener listener) {