[ES6] Module binding can be exported by multiple names
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 31 Jul 2016 07:04:57 +0000 (07:04 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 31 Jul 2016 07:04:57 +0000 (07:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=160343

Reviewed by Saam Barati.

ES6 Module can export the same local binding by using multiple names.
For example,

    ```
    var value = 42;

    export { value };
    export { value as value2 };
    ```

Currently, we only allowed one local binding to be exported with one name. So, in the above case,
the local binding "value" is exported as "value2" and "value" name is not exported. This is wrong.

To fix this issue, we collect the correspondence (local name => exported name) to the local bindings
in the parser. Previously, we only maintained the exported local bindings in the parser. And utilize
this information when creating the export entries in ModuleAnalyzer.

And this patch also moves ModuleScopeData from the Scope object to the Parser class since exported
names should be managed per-module, not per-scope.

This change fixes several test262 failures.

* JavaScriptCore.xcodeproj/project.pbxproj:
* parser/ModuleAnalyzer.cpp:
(JSC::ModuleAnalyzer::exportVariable):
(JSC::ModuleAnalyzer::analyze):
(JSC::ModuleAnalyzer::exportedBinding): Deleted.
(JSC::ModuleAnalyzer::declareExportAlias): Deleted.
* parser/ModuleAnalyzer.h:
* parser/ModuleScopeData.h: Copied from Source/JavaScriptCore/parser/ModuleAnalyzer.h.
(JSC::ModuleScopeData::create):
(JSC::ModuleScopeData::exportedBindings):
(JSC::ModuleScopeData::exportName):
(JSC::ModuleScopeData::exportBinding):
* parser/Nodes.cpp:
(JSC::ProgramNode::ProgramNode):
(JSC::ModuleProgramNode::ModuleProgramNode):
(JSC::EvalNode::EvalNode):
(JSC::FunctionNode::FunctionNode):
* parser/Nodes.h:
(JSC::ModuleProgramNode::moduleScopeData):
* parser/NodesAnalyzeModule.cpp:
(JSC::ExportDefaultDeclarationNode::analyzeModule):
(JSC::ExportNamedDeclarationNode::analyzeModule): Deleted.
* parser/Parser.cpp:
(JSC::Parser<LexerType>::Parser):
(JSC::Parser<LexerType>::parseModuleSourceElements):
(JSC::Parser<LexerType>::parseVariableDeclarationList):
(JSC::Parser<LexerType>::createBindingPattern):
(JSC::Parser<LexerType>::parseFunctionDeclaration):
(JSC::Parser<LexerType>::parseClassDeclaration):
(JSC::Parser<LexerType>::parseExportSpecifier):
(JSC::Parser<LexerType>::parseExportDeclaration):
* parser/Parser.h:
(JSC::Parser::exportName):
(JSC::Parser<LexerType>::parse):
(JSC::ModuleScopeData::create): Deleted.
(JSC::ModuleScopeData::exportedBindings): Deleted.
(JSC::ModuleScopeData::exportName): Deleted.
(JSC::ModuleScopeData::exportBinding): Deleted.
(JSC::Scope::Scope): Deleted.
(JSC::Scope::setSourceParseMode): Deleted.
(JSC::Scope::moduleScopeData): Deleted.
(JSC::Scope::setIsModule): Deleted.
* tests/modules/aliased-names.js: Added.
* tests/modules/aliased-names/main.js: Added.
(change):
* tests/stress/modules-syntax-error-with-names.js:
(export.Cocoa):
(SyntaxError.Cannot.export.a.duplicate.name):
* tests/test262.yaml:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@203953 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/parser/ModuleAnalyzer.cpp
Source/JavaScriptCore/parser/ModuleAnalyzer.h
Source/JavaScriptCore/parser/ModuleScopeData.h [new file with mode: 0644]
Source/JavaScriptCore/parser/Nodes.cpp
Source/JavaScriptCore/parser/Nodes.h
Source/JavaScriptCore/parser/NodesAnalyzeModule.cpp
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/parser/Parser.h
Source/JavaScriptCore/tests/modules/aliased-names.js [new file with mode: 0644]
Source/JavaScriptCore/tests/modules/aliased-names/main.js [new file with mode: 0644]
Source/JavaScriptCore/tests/stress/modules-syntax-error-with-names.js
Source/JavaScriptCore/tests/test262.yaml

index 8adbebb..7aef68a 100644 (file)
@@ -1,3 +1,82 @@
+2016-07-31  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Module binding can be exported by multiple names
+        https://bugs.webkit.org/show_bug.cgi?id=160343
+
+        Reviewed by Saam Barati.
+
+        ES6 Module can export the same local binding by using multiple names.
+        For example,
+
+            ```
+            var value = 42;
+
+            export { value };
+            export { value as value2 };
+            ```
+
+        Currently, we only allowed one local binding to be exported with one name. So, in the above case,
+        the local binding "value" is exported as "value2" and "value" name is not exported. This is wrong.
+
+        To fix this issue, we collect the correspondence (local name => exported name) to the local bindings
+        in the parser. Previously, we only maintained the exported local bindings in the parser. And utilize
+        this information when creating the export entries in ModuleAnalyzer.
+
+        And this patch also moves ModuleScopeData from the Scope object to the Parser class since exported
+        names should be managed per-module, not per-scope.
+
+        This change fixes several test262 failures.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * parser/ModuleAnalyzer.cpp:
+        (JSC::ModuleAnalyzer::exportVariable):
+        (JSC::ModuleAnalyzer::analyze):
+        (JSC::ModuleAnalyzer::exportedBinding): Deleted.
+        (JSC::ModuleAnalyzer::declareExportAlias): Deleted.
+        * parser/ModuleAnalyzer.h:
+        * parser/ModuleScopeData.h: Copied from Source/JavaScriptCore/parser/ModuleAnalyzer.h.
+        (JSC::ModuleScopeData::create):
+        (JSC::ModuleScopeData::exportedBindings):
+        (JSC::ModuleScopeData::exportName):
+        (JSC::ModuleScopeData::exportBinding):
+        * parser/Nodes.cpp:
+        (JSC::ProgramNode::ProgramNode):
+        (JSC::ModuleProgramNode::ModuleProgramNode):
+        (JSC::EvalNode::EvalNode):
+        (JSC::FunctionNode::FunctionNode):
+        * parser/Nodes.h:
+        (JSC::ModuleProgramNode::moduleScopeData):
+        * parser/NodesAnalyzeModule.cpp:
+        (JSC::ExportDefaultDeclarationNode::analyzeModule):
+        (JSC::ExportNamedDeclarationNode::analyzeModule): Deleted.
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::Parser):
+        (JSC::Parser<LexerType>::parseModuleSourceElements):
+        (JSC::Parser<LexerType>::parseVariableDeclarationList):
+        (JSC::Parser<LexerType>::createBindingPattern):
+        (JSC::Parser<LexerType>::parseFunctionDeclaration):
+        (JSC::Parser<LexerType>::parseClassDeclaration):
+        (JSC::Parser<LexerType>::parseExportSpecifier):
+        (JSC::Parser<LexerType>::parseExportDeclaration):
+        * parser/Parser.h:
+        (JSC::Parser::exportName):
+        (JSC::Parser<LexerType>::parse):
+        (JSC::ModuleScopeData::create): Deleted.
+        (JSC::ModuleScopeData::exportedBindings): Deleted.
+        (JSC::ModuleScopeData::exportName): Deleted.
+        (JSC::ModuleScopeData::exportBinding): Deleted.
+        (JSC::Scope::Scope): Deleted.
+        (JSC::Scope::setSourceParseMode): Deleted.
+        (JSC::Scope::moduleScopeData): Deleted.
+        (JSC::Scope::setIsModule): Deleted.
+        * tests/modules/aliased-names.js: Added.
+        * tests/modules/aliased-names/main.js: Added.
+        (change):
+        * tests/stress/modules-syntax-error-with-names.js:
+        (export.Cocoa):
+        (SyntaxError.Cannot.export.a.duplicate.name):
+        * tests/test262.yaml:
+
 2016-07-30  Mark Lam  <mark.lam@apple.com>
 
         Assertion failure while setting the length of an ArrayClass array.
index 958dea7..ef0b1bb 100644 (file)
                FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */; };
                FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; };
+               A79D3ED9C5064DD0A8466A3A /* ModuleScopeData.h in Headers */ = {isa = PBXBuildFile; fileRef = 000BEAF0DF604481AF6AB68C /* ModuleScopeData.h */; settings = {ATTRIBUTES = (Private, ); }; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
                FEDA50D51B97F4D9009A3B4F /* PingPongStackOverflowTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PingPongStackOverflowTest.h; path = API/tests/PingPongStackOverflowTest.h; sourceTree = "<group>"; };
                FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = "<group>"; };
                FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = "<group>"; };
+               000BEAF0DF604481AF6AB68C /* ModuleScopeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ModuleScopeData.h; path = ModuleScopeData.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                                A7A7EE7711B98B8D0065A14F /* SyntaxChecker.h */,
                                79EE0BFD1B4AFB85000385C9 /* VariableEnvironment.cpp */,
                                79EE0BFE1B4AFB85000385C9 /* VariableEnvironment.h */,
+                               000BEAF0DF604481AF6AB68C /* ModuleScopeData.h */,
                        );
                        path = parser;
                        sourceTree = "<group>";
                                86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
                                262D85B71C0D650F006ACB61 /* AirFixPartialRegisterStalls.h in Headers */,
                                86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
+                               A79D3ED9C5064DD0A8466A3A /* ModuleScopeData.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 29668e9..1c70366 100644 (file)
@@ -31,6 +31,7 @@
 #include "JSCellInlines.h"
 #include "JSGlobalObject.h"
 #include "JSModuleRecord.h"
+#include "ModuleScopeData.h"
 #include "StrongInlines.h"
 
 namespace JSC {
@@ -42,20 +43,7 @@ ModuleAnalyzer::ModuleAnalyzer(ExecState* exec, const Identifier& moduleKey, con
 {
 }
 
-Identifier ModuleAnalyzer::exportedBinding(const RefPtr<UniquedStringImpl>& ident)
-{
-    const auto iterator = m_aliasMap.find(ident);
-    if (iterator != m_aliasMap.end())
-        return iterator->value;
-    return Identifier::fromUid(&vm(), ident.get());
-}
-
-void ModuleAnalyzer::declareExportAlias(const Identifier& localName, const Identifier& exportName)
-{
-    m_aliasMap.add(localName.impl(), exportName);
-}
-
-void ModuleAnalyzer::exportVariable(const RefPtr<UniquedStringImpl>& localName, const VariableEnvironmentEntry& variable)
+void ModuleAnalyzer::exportVariable(ModuleProgramNode& moduleProgramNode, const RefPtr<UniquedStringImpl>& localName, const VariableEnvironmentEntry& variable)
 {
     // In the parser, we already marked the variables as Exported and Imported.
     // By leveraging this information, we collect the information that is needed
@@ -74,11 +62,10 @@ void ModuleAnalyzer::exportVariable(const RefPtr<UniquedStringImpl>& localName,
     if (!variable.isExported())
         return;
 
-    const Identifier exportName = exportedBinding(localName);
-
     // Exported module local variable.
     if (!variable.isImported()) {
-        moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createLocal(exportName, Identifier::fromUid(m_vm, localName.get())));
+        for (auto& exportName : moduleProgramNode.moduleScopeData().exportedBindings().get(localName.get()))
+            moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createLocal(Identifier::fromUid(m_vm, exportName.get()), Identifier::fromUid(m_vm, localName.get())));
         return;
     }
 
@@ -89,7 +76,8 @@ void ModuleAnalyzer::exportVariable(const RefPtr<UniquedStringImpl>& localName,
         //
         // Sec 15.2.1.16.1 step 11-a-ii-2-b https://tc39.github.io/ecma262/#sec-parsemodule
         // Namespace export is handled as local export since a namespace object binding itself is implemented as a local binding.
-        moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createLocal(exportName, Identifier::fromUid(m_vm, localName.get())));
+        for (auto& exportName : moduleProgramNode.moduleScopeData().exportedBindings().get(localName.get()))
+            moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createLocal(Identifier::fromUid(m_vm, exportName.get()), Identifier::fromUid(m_vm, localName.get())));
         return;
     }
 
@@ -99,7 +87,8 @@ void ModuleAnalyzer::exportVariable(const RefPtr<UniquedStringImpl>& localName,
     Optional<JSModuleRecord::ImportEntry> optionalImportEntry = moduleRecord()->tryGetImportEntry(localName.get());
     ASSERT(optionalImportEntry);
     const JSModuleRecord::ImportEntry& importEntry = *optionalImportEntry;
-    moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createIndirect(exportName, importEntry.importName, importEntry.moduleRequest));
+    for (auto& exportName : moduleProgramNode.moduleScopeData().exportedBindings().get(localName.get()))
+        moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createIndirect(Identifier::fromUid(m_vm, exportName.get()), importEntry.importName, importEntry.moduleRequest));
 }
 
 
@@ -148,10 +137,10 @@ JSModuleRecord* ModuleAnalyzer::analyze(ModuleProgramNode& moduleProgramNode)
     //
     //     export * from "mod"
     for (const auto& pair : m_moduleRecord->declaredVariables())
-        exportVariable(pair.key, pair.value);
+        exportVariable(moduleProgramNode, pair.key, pair.value);
 
     for (const auto& pair : m_moduleRecord->lexicalVariables())
-        exportVariable(pair.key, pair.value);
+        exportVariable(moduleProgramNode, pair.key, pair.value);
 
     if (Options::dumpModuleRecord())
         m_moduleRecord->dump();
index 7083ca9..bb3c53f 100644 (file)
@@ -44,18 +44,11 @@ public:
 
     JSModuleRecord* moduleRecord() { return m_moduleRecord.get(); }
 
-    void declareExportAlias(const Identifier& localName, const Identifier& exportName);
-
 private:
-    typedef HashMap<RefPtr<UniquedStringImpl>, Identifier, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> IdentifierAliasMap;
-
-    void exportVariable(const RefPtr<UniquedStringImpl>&, const VariableEnvironmentEntry&);
-
-    Identifier exportedBinding(const RefPtr<UniquedStringImpl>& ident);
+    void exportVariable(ModuleProgramNode&, const RefPtr<UniquedStringImpl>&, const VariableEnvironmentEntry&);
 
     VM* m_vm;
     Strong<JSModuleRecord> m_moduleRecord;
-    IdentifierAliasMap m_aliasMap;
 };
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/parser/ModuleScopeData.h b/Source/JavaScriptCore/parser/ModuleScopeData.h
new file mode 100644 (file)
index 0000000..8221af4
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "Identifier.h"
+#include <wtf/RefPtr.h>
+
+namespace JSC {
+
+class ModuleScopeData : public RefCounted<ModuleScopeData> {
+WTF_MAKE_NONCOPYABLE(ModuleScopeData);
+WTF_MAKE_FAST_ALLOCATED;
+public:
+    typedef HashMap<RefPtr<UniquedStringImpl>, IdentifierSet, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> IdentifierAliasMap;
+
+    static Ref<ModuleScopeData> create() { return adoptRef(*new ModuleScopeData); }
+
+    const IdentifierAliasMap& exportedBindings() const { return m_exportedBindings; }
+
+    bool exportName(const Identifier& exportedName)
+    {
+        return m_exportedNames.add(exportedName.impl()).isNewEntry;
+    }
+
+    void exportBinding(const Identifier& localName, const Identifier& exportedName)
+    {
+        m_exportedBindings.add(localName.impl(), IdentifierSet()).iterator->value.add(exportedName.impl());
+    }
+
+    void exportBinding(const Identifier& localName)
+    {
+        exportBinding(localName, localName);
+    }
+
+private:
+    ModuleScopeData() = default;
+
+    IdentifierSet m_exportedNames { };
+    IdentifierAliasMap m_exportedBindings { };
+};
+
+} // namespace
index 63c732d..4f9fa2f 100644 (file)
@@ -117,7 +117,7 @@ StatementNode* ScopeNode::singleStatement() const
 
 // ------------------------------ ProgramNode -----------------------------
 
-ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants)
+ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
     : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
     , m_startColumn(startColumn)
     , m_endColumn(endColumn)
@@ -126,16 +126,17 @@ ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startL
 
 // ------------------------------ ModuleProgramNode -----------------------------
 
-ModuleProgramNode::ModuleProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants)
+ModuleProgramNode::ModuleProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&& moduleScopeData)
     : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
     , m_startColumn(startColumn)
     , m_endColumn(endColumn)
+    , m_moduleScopeData(*WTFMove(moduleScopeData))
 {
 }
 
 // ------------------------------ EvalNode -----------------------------
 
-EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants)
+EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
     : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
     , m_endColumn(endColumn)
 {
@@ -181,7 +182,7 @@ void FunctionMetadataNode::setEndPosition(JSTextPosition position)
 
 // ------------------------------ FunctionNode -----------------------------
 
-FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters* parameters, const SourceCode& sourceCode, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants)
+FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters* parameters, const SourceCode& sourceCode, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
     : ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
     , m_parameters(parameters)
     , m_startColumn(startColumn)
index 1e08827..67af4fc 100644 (file)
@@ -52,6 +52,7 @@ namespace JSC {
     class JSScope;
     class ScopeNode;
     class ModuleAnalyzer;
+    class ModuleScopeData;
 
     typedef SmallPtrSet<UniquedStringImpl*> UniquedStringImplPtrSet;
 
@@ -1644,7 +1645,7 @@ namespace JSC {
 
     class ProgramNode : public ScopeNode {
     public:
-        ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants);
+        ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
 
         unsigned startColumn() const { return m_startColumn; }
         unsigned endColumn() const { return m_endColumn; }
@@ -1659,7 +1660,7 @@ namespace JSC {
 
     class EvalNode : public ScopeNode {
     public:
-        EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants);
+        EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
 
         ALWAYS_INLINE unsigned startColumn() const { return 0; }
         unsigned endColumn() const { return m_endColumn; }
@@ -1674,17 +1675,23 @@ namespace JSC {
 
     class ModuleProgramNode : public ScopeNode {
     public:
-        ModuleProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants);
+        ModuleProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
 
         unsigned startColumn() const { return m_startColumn; }
         unsigned endColumn() const { return m_endColumn; }
 
         static const bool scopeIsFunction = false;
 
+        ModuleScopeData& moduleScopeData()
+        {
+            return m_moduleScopeData;
+        }
+
     private:
         void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
         unsigned m_startColumn;
         unsigned m_endColumn;
+        Ref<ModuleScopeData> m_moduleScopeData;
     };
 
     class ModuleNameNode : public Node {
@@ -1915,7 +1922,7 @@ namespace JSC {
 
     class FunctionNode final : public ScopeNode {
     public:
-        FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants);
+        FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
 
         FunctionParameters* parameters() const { return m_parameters; }
 
index ed461da..426e53b 100644 (file)
@@ -65,9 +65,8 @@ void ExportAllDeclarationNode::analyzeModule(ModuleAnalyzer& analyzer)
     analyzer.moduleRecord()->addStarExportEntry(m_moduleName->moduleName());
 }
 
-void ExportDefaultDeclarationNode::analyzeModule(ModuleAnalyzer& analyzer)
+void ExportDefaultDeclarationNode::analyzeModule(ModuleAnalyzer&)
 {
-    analyzer.declareExportAlias(m_localName, analyzer.vm().propertyNames->defaultKeyword);
 }
 
 void ExportLocalDeclarationNode::analyzeModule(ModuleAnalyzer&)
@@ -86,11 +85,7 @@ void ExportNamedDeclarationNode::analyzeModule(ModuleAnalyzer& analyzer)
             // In this case, no local variable names are imported into the current module.
             // "v" indirectly points the binding in "mod".
             analyzer.moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createIndirect(specifier->exportedName(), specifier->localName(), m_moduleName->moduleName()));
-            continue;
         }
-
-        if (specifier->localName() != specifier->exportedName())
-            analyzer.declareExportAlias(specifier->localName(), specifier->exportedName());
     }
 }
 
index 24d9436..4a1c1e5 100644 (file)
@@ -234,6 +234,9 @@ Parser<LexerType>::Parser(VM* vm, const SourceCode& source, JSParserBuiltinMode
     if (strictMode == JSParserStrictMode::Strict)
         scope->setStrictMode();
 
+    if (parseMode == SourceParseMode::ModuleAnalyzeMode || parseMode == SourceParseMode::ModuleEvaluateMode)
+        m_moduleScopeData = ModuleScopeData::create();
+
     next();
 }
 
@@ -476,7 +479,8 @@ template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseModuleSo
 
     propagateError();
 
-    for (const auto& uid : currentScope()->moduleScopeData().exportedBindings()) {
+    for (const auto& pair : m_moduleScopeData->exportedBindings()) {
+        const auto& uid = pair.key;
         if (currentScope()->hasDeclaredVariable(uid)) {
             currentScope()->declaredVariables().markVariableAsExported(uid);
             continue;
@@ -708,7 +712,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVariableDecl
             }
             if (exportType == ExportType::Exported) {
                 semanticFailIfFalse(exportName(*name), "Cannot export a duplicate name '", name->impl(), "'");
-                currentScope()->moduleScopeData().exportBinding(*name);
+                m_moduleScopeData->exportBinding(*name);
             }
 
             if (hasInitializer) {
@@ -828,7 +832,7 @@ template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::createB
 
     if (exportType == ExportType::Exported) {
         semanticFailIfFalse(exportName(name), "Cannot export a duplicate name '", name.impl(), "'");
-        currentScope()->moduleScopeData().exportBinding(name);
+        m_moduleScopeData->exportBinding(name);
     }
     return context.createBindingLocation(token.m_location, name, token.m_startPosition, token.m_endPosition, bindingContext);
 }
@@ -2229,7 +2233,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
         internalFailWithMessage(false, "Cannot declare a function that shadows a let/const/class/function variable '", functionInfo.name->impl(), "' in strict mode");
     if (exportType == ExportType::Exported) {
         semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'");
-        currentScope()->moduleScopeData().exportBinding(*functionInfo.name);
+        m_moduleScopeData->exportBinding(*functionInfo.name);
     }
 
     TreeStatement result = context.createFuncDeclStatement(location, functionInfo);
@@ -2255,7 +2259,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclarat
         internalFailWithMessage(false, "Cannot declare a class twice: '", info.className->impl(), "'");
     if (exportType == ExportType::Exported) {
         semanticFailIfFalse(exportName(*info.className), "Cannot export a duplicate class name: '", info.className->impl(), "'");
-        currentScope()->moduleScopeData().exportBinding(*info.className);
+        m_moduleScopeData->exportBinding(*info.className);
     }
 
     JSTextPosition classEnd = lastTokenEndPosition();
@@ -2786,7 +2790,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseImportDeclara
 }
 
 template <typename LexerType>
-template <class TreeBuilder> typename TreeBuilder::ExportSpecifier Parser<LexerType>::parseExportSpecifier(TreeBuilder& context, Vector<const Identifier*>& maybeLocalNames, bool& hasKeywordForLocalBindings)
+template <class TreeBuilder> typename TreeBuilder::ExportSpecifier Parser<LexerType>::parseExportSpecifier(TreeBuilder& context, Vector<std::pair<const Identifier*, const Identifier*>>& maybeExportedLocalNames, bool& hasKeywordForLocalBindings)
 {
     // ExportSpecifier :
     // IdentifierName
@@ -2808,7 +2812,7 @@ template <class TreeBuilder> typename TreeBuilder::ExportSpecifier Parser<LexerT
     }
 
     semanticFailIfFalse(exportName(*exportedName), "Cannot export a duplicate name '", exportedName->impl(), "'");
-    maybeLocalNames.append(localName);
+    maybeExportedLocalNames.append(std::make_pair(localName, exportedName));
     return context.createExportSpecifier(specifierLocation, *localName, *exportedName);
 }
 
@@ -2896,7 +2900,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
         failIfFalse(result, "Cannot parse the declaration");
 
         semanticFailIfFalse(exportName(m_vm->propertyNames->defaultKeyword), "Only one 'default' export is allowed");
-        currentScope()->moduleScopeData().exportBinding(*localName);
+        m_moduleScopeData->exportBinding(*localName, m_vm->propertyNames->defaultKeyword);
         return context.createExportDefaultDeclaration(exportLocation, result, *localName);
     }
 
@@ -2916,12 +2920,12 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
         next();
 
         auto specifierList = context.createExportSpecifierList();
-        Vector<const Identifier*> maybeLocalNames;
+        Vector<std::pair<const Identifier*, const Identifier*>> maybeExportedLocalNames;
 
         bool hasKeywordForLocalBindings = false;
         while (!match(CLOSEBRACE)) {
             failIfFalse(matchIdentifierOrKeyword(), "Expected a variable name for the export declaration");
-            auto specifier = parseExportSpecifier(context, maybeLocalNames, hasKeywordForLocalBindings);
+            auto specifier = parseExportSpecifier(context, maybeExportedLocalNames, hasKeywordForLocalBindings);
             failIfFalse(specifier, "Cannot parse the named export");
             context.appendExportSpecifier(specifierList, specifier);
             if (!consume(COMMA))
@@ -2947,8 +2951,11 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
             // does not have effect on the current module's scope. But,
             //   export { A, B, C as D }
             // will reference the current module's bindings.
-            for (const Identifier* localName : maybeLocalNames)
-                currentScope()->moduleScopeData().exportBinding(*localName);
+            for (const auto& pair : maybeExportedLocalNames) {
+                const Identifier* localName = pair.first;
+                const Identifier* exportedName = pair.second;
+                m_moduleScopeData->exportBinding(*localName, *exportedName);
+            }
         }
 
         return context.createExportNamedDeclaration(exportLocation, specifierList, moduleName);
index 25cec95..a00b804 100644 (file)
@@ -28,6 +28,7 @@
 #include "Executable.h"
 #include "JSGlobalObject.h"
 #include "Lexer.h"
+#include "ModuleScopeData.h"
 #include "Nodes.h"
 #include "ParserArena.h"
 #include "ParserError.h"
@@ -128,27 +129,6 @@ ALWAYS_INLINE static bool isIdentifierOrKeyword(const JSToken& token)
     return token.m_type == IDENT || token.m_type & KeywordTokenFlag;
 }
 
-class ModuleScopeData : public RefCounted<ModuleScopeData> {
-public:
-    static Ref<ModuleScopeData> create() { return adoptRef(*new ModuleScopeData); }
-
-    const IdentifierSet& exportedBindings() const { return m_exportedBindings; }
-
-    bool exportName(const Identifier& exportedName)
-    {
-        return m_exportedNames.add(exportedName.impl()).isNewEntry;
-    }
-
-    void exportBinding(const Identifier& localName)
-    {
-        m_exportedBindings.add(localName.impl());
-    }
-
-private:
-    IdentifierSet m_exportedNames { };
-    IdentifierSet m_exportedBindings { };
-};
-
 struct Scope {
     WTF_MAKE_NONCOPYABLE(Scope);
 
@@ -216,7 +196,6 @@ public:
         , m_lexicalVariables(WTFMove(other.m_lexicalVariables))
         , m_usedVariables(WTFMove(other.m_usedVariables))
         , m_closedVariableCandidates(WTFMove(other.m_closedVariableCandidates))
-        , m_moduleScopeData(WTFMove(other.m_moduleScopeData))
         , m_functionDeclarations(WTFMove(other.m_functionDeclarations))
     {
     }
@@ -277,11 +256,8 @@ public:
             break;
 
         case SourceParseMode::ProgramMode:
-            break;
-
         case SourceParseMode::ModuleAnalyzeMode:
         case SourceParseMode::ModuleEvaluateMode:
-            setIsModule();
             break;
         }
     }
@@ -313,12 +289,6 @@ public:
         return m_lexicalVariables;
     }
 
-    ModuleScopeData& moduleScopeData() const
-    {
-        ASSERT(m_moduleScopeData);
-        return *m_moduleScopeData;
-    }
-
     void computeLexicallyCapturedVariablesAndPurgeCandidates()
     {
         // Because variables may be defined at any time in the range of a lexical scope, we must
@@ -731,11 +701,6 @@ private:
         m_isArrowFunction = true;
     }
 
-    void setIsModule()
-    {
-        m_moduleScopeData = ModuleScopeData::create();
-    }
-
     const VM* m_vm;
     bool m_shadowsArguments;
     bool m_usesEval;
@@ -771,7 +736,6 @@ private:
     Vector<UniquedStringImplPtrSet, 6> m_usedVariables;
     UniquedStringImplPtrSet m_sloppyModeHoistableFunctionCandidates;
     HashSet<UniquedStringImpl*> m_closedVariableCandidates;
-    RefPtr<ModuleScopeData> m_moduleScopeData;
     DeclarationStacks::FunctionStack m_functionDeclarations;
 };
 
@@ -1176,7 +1140,8 @@ private:
     bool exportName(const Identifier& ident)
     {
         ASSERT(currentScope().index() == 0);
-        return currentScope()->moduleScopeData().exportName(ident);
+        ASSERT(m_moduleScopeData);
+        return m_moduleScopeData->exportName(ident);
     }
 
     ScopeStack m_scopeStack;
@@ -1442,7 +1407,7 @@ private:
     template <class TreeBuilder> typename TreeBuilder::ImportSpecifier parseImportClauseItem(TreeBuilder&, ImportSpecifierType);
     template <class TreeBuilder> typename TreeBuilder::ModuleName parseModuleName(TreeBuilder&);
     template <class TreeBuilder> TreeStatement parseImportDeclaration(TreeBuilder&);
-    template <class TreeBuilder> typename TreeBuilder::ExportSpecifier parseExportSpecifier(TreeBuilder& context, Vector<const Identifier*>& maybeLocalNames, bool& hasKeywordForLocalBindings);
+    template <class TreeBuilder> typename TreeBuilder::ExportSpecifier parseExportSpecifier(TreeBuilder& context, Vector<std::pair<const Identifier*, const Identifier*>>& maybeExportedLocalNames, bool& hasKeywordForLocalBindings);
     template <class TreeBuilder> TreeStatement parseExportDeclaration(TreeBuilder&);
 
     enum class FunctionDefinitionType { Expression, Declaration, Method };
@@ -1623,6 +1588,7 @@ private:
     ExpressionErrorClassifier* m_expressionErrorClassifier;
     bool m_isEvalContext;
     bool m_immediateParentAllowsFunctionDeclarationInStatement;
+    RefPtr<ModuleScopeData> m_moduleScopeData;
     
     struct DepthManager {
         DepthManager(int* depth)
@@ -1697,7 +1663,8 @@ std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error, const I
                                     *m_source,
                                     m_features,
                                     currentScope()->innerArrowFunctionFeatures(),
-                                    m_numConstants);
+                                    m_numConstants,
+                                    WTFMove(m_moduleScopeData));
         result->setLoc(m_source->firstLine(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
         result->setEndOffset(m_lexer->currentOffset());
 
diff --git a/Source/JavaScriptCore/tests/modules/aliased-names.js b/Source/JavaScriptCore/tests/modules/aliased-names.js
new file mode 100644 (file)
index 0000000..4c87965
--- /dev/null
@@ -0,0 +1,8 @@
+import { a, b, change } from 'aliased-names/main.js'
+import { shouldBe, shouldThrow } from "./resources/assert.js";
+
+shouldBe(a, 42);
+shouldBe(b, 42);
+change(400);
+shouldBe(a, 400);
+shouldBe(b, 400);
diff --git a/Source/JavaScriptCore/tests/modules/aliased-names/main.js b/Source/JavaScriptCore/tests/modules/aliased-names/main.js
new file mode 100644 (file)
index 0000000..3033cf9
--- /dev/null
@@ -0,0 +1,10 @@
+var a = 42;
+
+function change(value)
+{
+    a = value;
+}
+
+export { a }
+export { a as b }
+export { change }
index 62f4887..ef7d54f 100644 (file)
@@ -192,26 +192,61 @@ export default function hello () { }
 export default 20;
 `, `SyntaxError: Only one 'default' export is allowed.:4`);
 
+checkModuleSyntaxError(String.raw`
+var a = 42;
+var b = 55;
+export { a as Cocoa, b as Cocoa };
+`, `SyntaxError: Cannot export a duplicate name 'Cocoa'.:4`);
+
+checkModuleSyntaxError(String.raw`
+var a = 42;
+var b = 55;
+export { a as Cocoa, b as Cocoa };
+`, `SyntaxError: Cannot export a duplicate name 'Cocoa'.:4`);
+
+checkModuleSyntaxError(String.raw`
+var Cocoa = 42;
+var b = 55;
+export { Cocoa, b as Cocoa };
+`, `SyntaxError: Cannot export a duplicate name 'Cocoa'.:4`);
+
+checkModuleSyntaxError(String.raw`
+export var Cocoa = 42;
+var b = 55;
+export { b as Cocoa };
+`, `SyntaxError: Cannot export a duplicate name 'Cocoa'.:4`);
+
+checkModuleSyntaxError(String.raw`
+var a = 42;
+export { a as Cocoa };
+export function Cocoa() { }
+`, `SyntaxError: Cannot export a duplicate function name: 'Cocoa'.:5`);
+
+checkModuleSyntaxError(String.raw`
+var a = 42;
+export { a as Cocoa };
+export class Cocoa { }
+`, `SyntaxError: Cannot export a duplicate class name: 'Cocoa'.:5`);
+
 // FIXME: These tests also should be passed. But now, var and lexical declared names can be co-exist on Script / Module top level scope.
 // This will be fixed when this issue is fixed for Script environment.
 // http://www.ecma-international.org/ecma-262/6.0/#sec-scripts-static-semantics-early-errors
 // http://www.ecma-international.org/ecma-262/6.0/#sec-module-semantics-static-semantics-early-errors
-//
-// checkModuleSyntaxError(String.raw`
-// import A from "Cocoa"
-// var A = 20;
-// `, ``);
-//
+checkModuleSyntaxError(String.raw`
+import A from "Cocoa"
+var A = 20;
+`, `SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'A'.:3`);
+
 // checkModuleSyntaxError(String.raw`
 // var A = 20;
 // import A from "Cocoa"
 // `, ``);
-//
-// checkModuleSyntaxError(String.raw`
-// import A from "Cocoa"
-// var A = 20;
-// `, ``);
-//
+
+checkModuleSyntaxError(String.raw`
+import A from "Cocoa"
+var A = 20;
+`, `SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'A'.:3`);
+
 // checkModuleSyntaxError(String.raw`
 // var A = 20;
 // import A from "Cocoa"
index 0a7d2a8..8aae131 100644 (file)
 - path: test262/test/language/module-code/instn-star-props-nrml-star_FIXTURE.js
   cmd: prepareTest262Fixture
 - path: test262/test/language/module-code/instn-star-props-nrml.js
-  cmd: runTest262 :fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module]
+  cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module]
 - path: test262/test/language/module-code/instn-star-star-cycle-2_FIXTURE.js
   cmd: prepareTest262Fixture
 - path: test262/test/language/module-code/instn-star-star-cycle-indirect-x_FIXTURE.js
 - path: test262/test/language/module-code/namespace/Symbol.iterator/this-val-not-ns.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
 - path: test262/test/language/module-code/namespace/Symbol.iterator/values-binding-types.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
 - path: test262/test/language/module-code/namespace/Symbol.iterator/values-binding-types_.js
   cmd: prepareTest262Fixture
 - path: test262/test/language/module-code/namespace/Symbol.iterator/values-order.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
 - path: test262/test/language/module-code/namespace/Symbol.toStringTag.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:module]
 - path: test262/test/language/module-code/namespace/internals/define-own-property.js
 - path: test262/test/language/module-code/namespace/internals/is-extensible.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
 - path: test262/test/language/module-code/namespace/internals/own-property-keys-binding-types.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
 - path: test262/test/language/module-code/namespace/internals/own-property-keys-binding-types_FIXTURE.js
   cmd: prepareTest262Fixture
 - path: test262/test/language/module-code/namespace/internals/own-property-keys-sort.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
 - path: test262/test/language/module-code/namespace/internals/prevent-extensions.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
 - path: test262/test/language/module-code/namespace/internals/set-prototype-of.js