source: webkit/trunk/Source/JavaScriptCore/parser/ModuleAnalyzer.cpp

Last change on this file was 278253, checked in by Darin Adler, 4 years ago

Remove WTF::Optional synonym for std::optional, using that class template directly instead
https://bugs.webkit.org/show_bug.cgi?id=226433

Reviewed by Chris Dumez.

Source/JavaScriptCore:

  • <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.
  • inspector/scripts/codegen/generate_objc_protocol_types_implementation.py:

(ObjCProtocolTypesImplementationGenerator._generate_init_method_for_payload): Use auto instead
of Optional<>. Also use * instead of value() and nest the definition of the local inside an if
statement in the case where it's an optional.

  • inspector/scripts/tests/expected/*: Regenerated these results.

Source/WebCore:

  • <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

Source/WebCore/PAL:

  • <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

Source/WebDriver:

  • <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

Source/WebKit:

  • <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.
  • Scripts/webkit/tests: Regenerated expected results, by running the command "python

Scripts/webkit/messages_unittest.py -r". (How am I supposed to know to do that?)

Source/WebKitLegacy/ios:

  • WebCoreSupport/WebChromeClientIOS.h: Let the do-webcore-rename script rename

Optional<> to std::optional<>.

Source/WebKitLegacy/mac:

  • <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

Source/WebKitLegacy/win:

  • <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

Source/WTF:

  • <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.
  • wtf/Optional.h: Remove WTF::Optional.

Tools:

  • <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.
File size: 6.7 KB
Line 
1/*
2 * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "ModuleAnalyzer.h"
28
29#include "IdentifierInlines.h"
30#include "JSGlobalObject.h"
31#include "JSModuleRecord.h"
32#include "ModuleScopeData.h"
33#include "StrongInlines.h"
34
35namespace JSC {
36
37ModuleAnalyzer::ModuleAnalyzer(JSGlobalObject* globalObject, const Identifier& moduleKey, const SourceCode& sourceCode, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables)
38 : m_vm(globalObject->vm())
39 , m_moduleRecord(m_vm, JSModuleRecord::create(globalObject, m_vm, globalObject->moduleRecordStructure(), moduleKey, sourceCode, declaredVariables, lexicalVariables))
40{
41}
42
43void ModuleAnalyzer::exportVariable(ModuleProgramNode& moduleProgramNode, const RefPtr<UniquedStringImpl>& localName, const VariableEnvironmentEntry& variable)
44{
45 // In the parser, we already marked the variables as Exported and Imported.
46 // By leveraging this information, we collect the information that is needed
47 // to construct the module environment.
48 //
49 // I E
50 // * = exported module local variable
51 // * = imported binding
52 // = non-exported module local variable
53 // * * = indirect exported binding
54 //
55 // One exception is namespace binding (like import * as ns from "mod").
56 // This is annotated as an imported, but the actual binding is locate in the
57 // current module.
58
59 if (!variable.isExported())
60 return;
61
62 // Exported module local variable.
63 if (!variable.isImported()) {
64 for (auto& exportName : moduleProgramNode.moduleScopeData().exportedBindings().get(localName.get()))
65 moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createLocal(Identifier::fromUid(m_vm, exportName.get()), Identifier::fromUid(m_vm, localName.get())));
66 return;
67 }
68
69 if (variable.isImportedNamespace()) {
70 // Exported namespace binding.
71 // import * as namespace from "mod"
72 // export { namespace }
73 //
74 // Sec 15.2.1.16.1 step 11-a-ii-2-b https://tc39.github.io/ecma262/#sec-parsemodule
75 // Namespace export is handled as local export since a namespace object binding itself is implemented as a local binding.
76 for (auto& exportName : moduleProgramNode.moduleScopeData().exportedBindings().get(localName.get()))
77 moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createLocal(Identifier::fromUid(m_vm, exportName.get()), Identifier::fromUid(m_vm, localName.get())));
78 return;
79 }
80
81 // Indirectly exported binding.
82 // import a from "mod"
83 // export { a }
84 std::optional<JSModuleRecord::ImportEntry> optionalImportEntry = moduleRecord()->tryGetImportEntry(localName.get());
85 ASSERT(optionalImportEntry);
86 const JSModuleRecord::ImportEntry& importEntry = *optionalImportEntry;
87 for (auto& exportName : moduleProgramNode.moduleScopeData().exportedBindings().get(localName.get()))
88 moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createIndirect(Identifier::fromUid(m_vm, exportName.get()), importEntry.importName, importEntry.moduleRequest));
89}
90
91
92
93JSModuleRecord* ModuleAnalyzer::analyze(ModuleProgramNode& moduleProgramNode)
94{
95 // Traverse the module AST and collect
96 // * Import entries
97 // * Export entries that have FromClause (e.g. export { a } from "mod")
98 // * Export entries that have star (e.g. export * from "mod")
99 // * Aliased export names (e.g. export { a as b })
100 moduleProgramNode.analyzeModule(*this);
101
102 // Based on the collected information, categorize export entries into 3 types.
103 // 1. Local export entries
104 // This references the local variable in the current module.
105 // This variable should be allocated in the current module environment as a heap variable.
106 //
107 // const variable = 20
108 // export { variable }
109 //
110 // 2. Namespace export entries
111 // This references the namespace object imported by some import entries.
112 // This variable itself should be allocated in the current module environment as a heap variable.
113 // But when the other modules attempt to resolve this export name in this module, this module
114 // should tell the link to the original module.
115 //
116 // import * as namespace from "mod"
117 // export { namespace as mod }
118 //
119 // 3. Indirect export entries
120 // This references the imported binding name from the other module.
121 // This module environment itself should hold the pointer to (1) the original module and
122 // (2) the binding in the original module. The variable itself is allocated in the original
123 // module. This indirect binding is resolved when the CodeBlock resolves the references.
124 //
125 // import mod from "mod"
126 // export { mod }
127 //
128 // export { a } from "mod"
129 //
130 // And separeted from the above 3 types, we also collect the star export entries.
131 //
132 // 4. Star export entries
133 // This exports all the names from the specified external module as the current module's name.
134 //
135 // export * from "mod"
136 for (const auto& pair : m_moduleRecord->declaredVariables())
137 exportVariable(moduleProgramNode, pair.key, pair.value);
138
139 for (const auto& pair : m_moduleRecord->lexicalVariables())
140 exportVariable(moduleProgramNode, pair.key, pair.value);
141
142 if (UNLIKELY(Options::dumpModuleRecord()))
143 m_moduleRecord->dump();
144
145 return m_moduleRecord.get();
146}
147
148} // namespace JSC
Note: See TracBrowser for help on using the repository browser.