Title: [211017] trunk
Revision
211017
Author
[email protected]
Date
2017-01-21 14:10:54 -0800 (Sat, 21 Jan 2017)

Log Message

dynamic import is ambiguous with import declaration at module code
https://bugs.webkit.org/show_bug.cgi?id=167098

Reviewed by Darin Adler.

JSTests:

* modules/import-call.js: Added.
(from.string_appeared_here.import.string_appeared_here.then):
* modules/import-call/main.js: Added.
* stress/import-syntax.js:
(async):

Source/_javascript_Core:

This patch fixes two syntax issues related to dynamic import.

1. Fix member _expression_ parsing with dynamic import results

We should not return import _expression_ immediately after parsing
it in parseMemberExpression. This prohibits us to parse the following
code,

    import("...").then(function () {
    });

2. dynamic import with import declaration under the module context

Before this patch, we always attempt to parse IMPORT as import declaration
under the module context. It means that import call in the top level
_expression_ statement fails to be parsed since the parser attempts to parse
it as import declaration.

    import("...")  // module top level statement.

In this patch, we check the condition `[lookahead != (]` before starting
parsing import declaration. This allows us to put import call in the module
top level statement.

* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseModuleSourceElements):
(JSC::Parser<LexerType>::parseMemberExpression):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (211016 => 211017)


--- trunk/JSTests/ChangeLog	2017-01-21 20:46:29 UTC (rev 211016)
+++ trunk/JSTests/ChangeLog	2017-01-21 22:10:54 UTC (rev 211017)
@@ -1,3 +1,16 @@
+2017-01-21  Yusuke Suzuki  <[email protected]>
+
+        dynamic import is ambiguous with import declaration at module code
+        https://bugs.webkit.org/show_bug.cgi?id=167098
+
+        Reviewed by Darin Adler.
+
+        * modules/import-call.js: Added.
+        (from.string_appeared_here.import.string_appeared_here.then):
+        * modules/import-call/main.js: Added.
+        * stress/import-syntax.js:
+        (async):
+
 2017-01-19  Skachkov Oleksandr  <[email protected]>
 
         "this" missing after await in async arrow function

Added: trunk/JSTests/modules/import-call/main.js (0 => 211017)


--- trunk/JSTests/modules/import-call/main.js	                        (rev 0)
+++ trunk/JSTests/modules/import-call/main.js	2017-01-21 22:10:54 UTC (rev 211017)
@@ -0,0 +1 @@
+export let Cocoa = 42;

Added: trunk/JSTests/modules/import-call.js (0 => 211017)


--- trunk/JSTests/modules/import-call.js	                        (rev 0)
+++ trunk/JSTests/modules/import-call.js	2017-01-21 22:10:54 UTC (rev 211017)
@@ -0,0 +1,5 @@
+import { shouldBe } from "./resources/assert.js"
+
+import("./import-call/main.js").then((result) => {
+    shouldBe(result.Cocoa, 42);
+});

Modified: trunk/JSTests/stress/import-syntax.js (211016 => 211017)


--- trunk/JSTests/stress/import-syntax.js	2017-01-21 20:46:29 UTC (rev 211016)
+++ trunk/JSTests/stress/import-syntax.js	2017-01-21 22:10:54 UTC (rev 211017)
@@ -53,6 +53,11 @@
 (async function () {
     await testSyntax(`import("./import-tests/cocoa.js")`);
     await testSyntax(`import("./import-tests/../import-tests/cocoa.js")`);
+    await testSyntax(`import("./import-tests/../import-tests/cocoa.js").then(() => { })`);
+    await testSyntax(`(import("./import-tests/../import-tests/cocoa.js").then(() => { }))`);
+    await testSyntax(`(import("./import-tests/../import-tests/cocoa.js"))`);
+    await testSyntax(`import("./import-tests/../import-tests/cocoa.js").catch(() => { })`);
+    await testSyntax(`(import("./import-tests/../import-tests/cocoa.js").catch(() => { }))`);
 }()).catch((error) => {
     print(String(error));
     abort();

Modified: trunk/Source/_javascript_Core/ChangeLog (211016 => 211017)


--- trunk/Source/_javascript_Core/ChangeLog	2017-01-21 20:46:29 UTC (rev 211016)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-01-21 22:10:54 UTC (rev 211017)
@@ -1,3 +1,38 @@
+2017-01-21  Yusuke Suzuki  <[email protected]>
+
+        dynamic import is ambiguous with import declaration at module code
+        https://bugs.webkit.org/show_bug.cgi?id=167098
+
+        Reviewed by Darin Adler.
+
+        This patch fixes two syntax issues related to dynamic import.
+
+        1. Fix member _expression_ parsing with dynamic import results
+
+        We should not return import _expression_ immediately after parsing
+        it in parseMemberExpression. This prohibits us to parse the following
+        code,
+
+            import("...").then(function () {
+            });
+
+        2. dynamic import with import declaration under the module context
+
+        Before this patch, we always attempt to parse IMPORT as import declaration
+        under the module context. It means that import call in the top level
+        _expression_ statement fails to be parsed since the parser attempts to parse
+        it as import declaration.
+
+            import("...")  // module top level statement.
+
+        In this patch, we check the condition `[lookahead != (]` before starting
+        parsing import declaration. This allows us to put import call in the module
+        top level statement.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseModuleSourceElements):
+        (JSC::Parser<LexerType>::parseMemberExpression):
+
 2017-01-20  Joseph Pecoraro  <[email protected]>
 
         Remove outdated ENABLE(CSP_NEXT) build flag

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (211016 => 211017)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2017-01-21 20:46:29 UTC (rev 211016)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2017-01-21 22:10:54 UTC (rev 211017)
@@ -375,30 +375,48 @@
 
     while (true) {
         TreeStatement statement = 0;
-        if (match(IMPORT)) {
-            statement = parseImportDeclaration(context);
-            if (statement)
-                recordPauseLocation(context.breakpointLocation(statement));
-        } else if (match(EXPORT)) {
+        switch (m_token.m_type) {
+        case EXPORT:
             statement = parseExportDeclaration(context);
             if (statement)
                 recordPauseLocation(context.breakpointLocation(statement));
-        } else {
+            break;
+
+        case IMPORT: {
+            SavePoint savePoint = createSavePoint();
+            next();
+            bool isImportDeclaration = !match(OPENPAREN);
+            restoreSavePoint(savePoint);
+            if (isImportDeclaration) {
+                statement = parseImportDeclaration(context);
+                if (statement)
+                    recordPauseLocation(context.breakpointLocation(statement));
+                break;
+            }
+
+            // This is `import("...")` call case.
+            FALLTHROUGH;
+        }
+
+        default: {
             const Identifier* directive = 0;
             unsigned directiveLiteralLength = 0;
             if (parseMode == SourceParseMode::ModuleAnalyzeMode) {
                 if (!parseStatementListItem(syntaxChecker, directive, &directiveLiteralLength))
-                    break;
+                    goto end;
                 continue;
             }
             statement = parseStatementListItem(context, directive, &directiveLiteralLength);
+            break;
         }
+        }
 
         if (!statement)
-            break;
+            goto end;
         context.appendStatement(sourceElements, statement);
     }
 
+end:
     propagateError();
 
     for (const auto& pair : m_moduleScopeData->exportedBindings()) {
@@ -4395,7 +4413,7 @@
         TreeExpression expr = parseAssignmentExpression(context);
         failIfFalse(expr, "Cannot parse _expression_");
         consumeOrFail(CLOSEPAREN, "import call expects exactly one argument");
-        return context.createImportExpr(location, expr, expressionStart, expressionEnd, lastTokenEndPosition());
+        base = context.createImportExpr(location, expr, expressionStart, expressionEnd, lastTokenEndPosition());
     } else if (!baseIsNewTarget) {
         const bool isAsync = match(ASYNC);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to