Ignore:
Timestamp:
Jan 24, 2022, 2:51:13 PM (3 years ago)
Author:
[email protected]
Message:

[JSC] Support import assertion syntax
https://bugs.webkit.org/show_bug.cgi?id=235312

Reviewed by Ross Kirsling.

JSTests:

  • modules/import-meta-syntax.js:

(shouldThrow):

  • stress/import-syntax.js:
  • stress/modules-syntax-error.js:
  • stress/modules-syntax-import-assertion-error.js: Added.

(shouldThrow):

  • stress/modules-syntax-import-assertion.js: Added.

LayoutTests/imported/w3c:

  • web-platform-tests/html/semantics/scripting-1/the-script-element/css-module/css-module-worker-test-expected.txt:
  • web-platform-tests/html/semantics/scripting-1/the-script-element/css-module/import-css-module-dynamic-expected.txt:
  • web-platform-tests/html/semantics/scripting-1/the-script-element/import-assertions/dynamic-import-with-assertion-argument.any-expected.txt:
  • web-platform-tests/html/semantics/scripting-1/the-script-element/import-assertions/dynamic-import-with-assertion-argument.any.worker-expected.txt:
  • web-platform-tests/html/semantics/scripting-1/the-script-element/json-module/charset-bom.any-expected.txt:
  • web-platform-tests/html/semantics/scripting-1/the-script-element/json-module/charset-bom.any.worker-expected.txt:
  • web-platform-tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any-expected.txt:
  • web-platform-tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.worker-expected.txt:
  • web-platform-tests/html/semantics/scripting-1/the-script-element/json-module/json-module-service-worker-test.https-expected.txt:
  • web-platform-tests/html/semantics/scripting-1/the-script-element/json-module/non-object.any-expected.txt:
  • web-platform-tests/html/semantics/scripting-1/the-script-element/json-module/non-object.any.worker-expected.txt:
  • web-platform-tests/html/semantics/scripting-1/the-script-element/json-module/repeated-imports.any-expected.txt:
  • web-platform-tests/html/semantics/scripting-1/the-script-element/json-module/repeated-imports.any.worker-expected.txt:
  • web-platform-tests/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt:
  • web-platform-tests/workers/dedicated-worker-parse-error-failure-expected.txt:
  • web-platform-tests/workers/modules/dedicated-worker-options-credentials-expected.txt:

Source/JavaScriptCore:

This patch adds syntax support for import assertion[1].
This does not add the actual feature propagating import assertion
to the module request yet.

[1]: https://github.com/tc39/proposal-import-assertions

  • bytecompiler/NodesCodegen.cpp:

(JSC::ImportNode::emitBytecode):

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createImportExpr):
(JSC::ASTBuilder::createImportAssertionList):
(JSC::ASTBuilder::appendImportAssertion):
(JSC::ASTBuilder::createImportDeclaration):
(JSC::ASTBuilder::createExportAllDeclaration):
(JSC::ASTBuilder::createExportNamedDeclaration):

  • parser/NodeConstructors.h:

(JSC::ImportNode::ImportNode):
(JSC::ImportDeclarationNode::ImportDeclarationNode):
(JSC::ExportAllDeclarationNode::ExportAllDeclarationNode):
(JSC::ExportNamedDeclarationNode::ExportNamedDeclarationNode):

  • parser/Nodes.h:
  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseImportAssertions):
(JSC::Parser<LexerType>::parseImportDeclaration):
(JSC::Parser<LexerType>::parseExportDeclaration):
(JSC::Parser<LexerType>::parseMemberExpression):

  • parser/Parser.h:
  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createImportExpr):
(JSC::SyntaxChecker::createImportAssertionList):
(JSC::SyntaxChecker::appendImportAssertion):
(JSC::SyntaxChecker::createImportDeclaration):
(JSC::SyntaxChecker::createExportAllDeclaration):
(JSC::SyntaxChecker::createExportNamedDeclaration):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::JSC_DEFINE_HOST_FUNCTION):

  • runtime/OptionsList.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r284435 r288473  
    35773577
    35783578template <typename LexerType>
     3579template <class TreeBuilder> typename TreeBuilder::ImportAssertionList Parser<LexerType>::parseImportAssertions(TreeBuilder& context)
     3580{
     3581    auto assertionList = context.createImportAssertionList();
     3582    consumeOrFail(OPENBRACE, "Expected opening '{' at the start of import assertion");
     3583    while (!match(CLOSEBRACE)) {
     3584        failIfFalse(matchIdentifierOrKeyword() || match(STRING), "Expected an assertion key");
     3585        auto key = m_token.m_data.ident;
     3586        next();
     3587        consumeOrFail(COLON, "Expected ':' after assertion key");
     3588        failIfFalse(match(STRING), "Expected an assertion value");
     3589        auto value = m_token.m_data.ident;
     3590        next();
     3591        context.appendImportAssertion(assertionList, *key, *value);
     3592        if (!consume(COMMA))
     3593            break;
     3594    }
     3595    handleProductionOrFail2(CLOSEBRACE, "}", "end", "import assertion");
     3596    return assertionList;
     3597}
     3598
     3599template <typename LexerType>
    35793600template <class TreeBuilder> TreeStatement Parser<LexerType>::parseImportDeclaration(TreeBuilder& context)
    35803601{
     
    35883609    if (match(STRING)) {
    35893610        // import ModuleSpecifier ;
     3611        // import ModuleSpecifier [no LineTerminator here] AssertClause ;
    35903612        auto moduleName = parseModuleName(context);
    35913613        failIfFalse(moduleName, "Cannot parse the module name");
     3614
     3615        typename TreeBuilder::ImportAssertionList assertionList = 0;
     3616        if (Options::useImportAssertion() && !m_lexer->hasLineTerminatorBeforeToken() && matchContextualKeyword(m_vm.propertyNames->builtinNames().assertPublicName())) {
     3617            next();
     3618            assertionList = parseImportAssertions(context);
     3619            failIfFalse(assertionList, "Unable to parse import assertion");
     3620        }
     3621
    35923622        failIfFalse(autoSemiColon(), "Expected a ';' following a targeted import declaration");
    3593         return context.createImportDeclaration(importLocation, specifierList, moduleName);
     3623        return context.createImportDeclaration(importLocation, specifierList, moduleName, assertionList);
    35943624    }
    35953625
     
    36413671    auto moduleName = parseModuleName(context);
    36423672    failIfFalse(moduleName, "Cannot parse the module name");
     3673
     3674    // [no LineTerminator here] AssertClause ;
     3675    typename TreeBuilder::ImportAssertionList assertionList = 0;
     3676    if (Options::useImportAssertion() && !m_lexer->hasLineTerminatorBeforeToken() && matchContextualKeyword(m_vm.propertyNames->builtinNames().assertPublicName())) {
     3677        next();
     3678        assertionList = parseImportAssertions(context);
     3679        failIfFalse(assertionList, "Unable to parse import assertion");
     3680    }
     3681
    36433682    failIfFalse(autoSemiColon(), "Expected a ';' following a targeted import declaration");
    36443683
    3645     return context.createImportDeclaration(importLocation, specifierList, moduleName);
     3684    return context.createImportDeclaration(importLocation, specifierList, moduleName, assertionList);
    36463685}
    36473686
     
    37153754        auto moduleName = parseModuleName(context);
    37163755        failIfFalse(moduleName, "Cannot parse the 'from' clause");
     3756
     3757        // [no LineTerminator here] AssertClause ;
     3758        typename TreeBuilder::ImportAssertionList assertionList = 0;
     3759        if (Options::useImportAssertion() && !m_lexer->hasLineTerminatorBeforeToken() && matchContextualKeyword(m_vm.propertyNames->builtinNames().assertPublicName())) {
     3760            next();
     3761            assertionList = parseImportAssertions(context);
     3762            failIfFalse(assertionList, "Unable to parse import assertion");
     3763        }
     3764
    37173765        failIfFalse(autoSemiColon(), "Expected a ';' following a targeted export declaration");
    37183766
     
    37233771            auto specifier = context.createExportSpecifier(specifierLocation, *localName, *exportedName);
    37243772            context.appendExportSpecifier(specifierList, specifier);
    3725             return context.createExportNamedDeclaration(exportLocation, specifierList, moduleName);
    3726         }
    3727 
    3728         return context.createExportAllDeclaration(exportLocation, moduleName);
     3773            return context.createExportNamedDeclaration(exportLocation, specifierList, moduleName, assertionList);
     3774        }
     3775
     3776        return context.createExportAllDeclaration(exportLocation, moduleName, assertionList);
    37293777    }
    37303778
     
    38483896
    38493897        typename TreeBuilder::ModuleName moduleName = 0;
     3898        typename TreeBuilder::ImportAssertionList assertionList = 0;
    38503899        if (matchContextualKeyword(m_vm.propertyNames->from)) {
    38513900            next();
    38523901            moduleName = parseModuleName(context);
    38533902            failIfFalse(moduleName, "Cannot parse the 'from' clause");
     3903
     3904            // [no LineTerminator here] AssertClause ;
     3905            if (Options::useImportAssertion() && !m_lexer->hasLineTerminatorBeforeToken() && matchContextualKeyword(m_vm.propertyNames->builtinNames().assertPublicName())) {
     3906                next();
     3907                assertionList = parseImportAssertions(context);
     3908                failIfFalse(assertionList, "Unable to parse import assertion");
     3909            }
    38543910        } else
    38553911            semanticFailIfTrue(hasReferencedModuleExportNames, "Cannot use module export names if they reference variable names in the current module");
     
    38733929        }
    38743930
    3875         return context.createExportNamedDeclaration(exportLocation, specifierList, moduleName);
     3931        return context.createExportNamedDeclaration(exportLocation, specifierList, moduleName, assertionList);
    38763932    }
    38773933
     
    51375193        } else {
    51385194            semanticFailIfTrue(newCount, "Cannot use new with import");
    5139             consumeOrFail(OPENPAREN, "import call expects exactly one argument");
     5195            consumeOrFail(OPENPAREN, "import call expects one or two arguments");
    51405196            TreeExpression expr = parseAssignmentExpression(context);
    51415197            failIfFalse(expr, "Cannot parse expression");
    5142             consumeOrFail(CLOSEPAREN, "import call expects exactly one argument");
    5143             base = context.createImportExpr(location, expr, expressionStart, expressionEnd, lastTokenEndPosition());
     5198            TreeExpression optionExpression = 0;
     5199            if (consume(COMMA)) {
     5200                if (!match(CLOSEPAREN)) {
     5201                    optionExpression = parseAssignmentExpression(context);
     5202                    failIfFalse(optionExpression, "Cannot parse expression");
     5203                    consume(COMMA);
     5204                }
     5205            }
     5206            consumeOrFail(CLOSEPAREN, "import call expects one or two arguments");
     5207            base = context.createImportExpr(location, expr, optionExpression, expressionStart, expressionEnd, lastTokenEndPosition());
    51445208        }
    51455209    } else if (!baseIsNewTarget) {
Note: See TracChangeset for help on using the changeset viewer.