Skip to content

Commit 879046e

Browse files
srujzsCommit Queue
authored andcommitted
[frontend_server] Refactor usage of module to library bundle
With the new (and eventually, only) module format, we refer to collections of libraries as bundles rather than modules. This convention is a better fit as the frontend server already treats modules as a collection of libraries. Furthermore, places where we use the word "module" may be better communicated by using "library bundle import" (the component URI) or "library bundle name" (the synthesized name we give library bundles). This CL leaves usages of modules that are tied to user-facing flags for clarity, e.g. "module format" and "useDebuggerModuleNames". It also ignores usages where the intention is very much tied to a module e.g. when using require.js. Change-Id: I363b1eac955f710accece9fa3a8ea2624c751430 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/397200 Reviewed-by: Johnni Winther <[email protected]> Reviewed-by: Nicholas Shahan <[email protected]> Commit-Queue: Srujan Gaddam <[email protected]>
1 parent d9502e2 commit 879046e

File tree

7 files changed

+176
-156
lines changed

7 files changed

+176
-156
lines changed

pkg/front_end/test/spell_checking_list_code.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,6 +1707,7 @@ sq
17071707
sra
17081708
srawlins
17091709
src
1710+
srujzs
17101711
ssa
17111712
st
17121713
stability

pkg/frontend_server/lib/frontend_server.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,7 @@ StreamSubscription<String> listenAndCompile(CompilerInterface compiler,
15691569
state = _State.COMPILE_EXPRESSION_TO_JS_JSMODULES;
15701570
break;
15711571
case _State.COMPILE_EXPRESSION_TO_JS_JSMODULES:
1572+
// TODO(srujzs): Deprecate jsModules as we never use this.
15721573
if (string == boundaryKey) {
15731574
state = _State.COMPILE_EXPRESSION_TO_JS_JSFRAMEVALUES;
15741575
} else {

pkg/frontend_server/lib/src/javascript_bundle.dart

Lines changed: 66 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ import 'strong_components.dart';
2323
/// Produce a special bundle format for compiled JavaScript.
2424
///
2525
/// The bundle format consists of two files: One containing all produced
26-
/// JavaScript modules concatenated together, and a second containing the byte
27-
/// offsets by module name for each JavaScript module in JSON format.
26+
/// JavaScript library bundles concatenated together, and a second containing
27+
/// the byte offsets by the synthesized library bundle name for each JavaScript
28+
/// library bundle in JSON format. The library bundle name is based off of a
29+
/// library URI from the associated component.
2830
///
2931
/// The format is analogous to the dill and .incremental.dill in that during
3032
/// an incremental build, a different file is written for each which contains
@@ -49,10 +51,9 @@ class IncrementalJavaScriptBundler {
4951
final FileSystem? _fileSystem;
5052
final Set<Library> _loadedLibraries;
5153
final Map<Uri, Component> _uriToComponent = <Uri, Component>{};
52-
final _importToSummary = new Map<Library, Component>.identity();
53-
final _summaryToModule = new Map<Component, String>.identity();
54-
final Map<Uri, String> _moduleImportForSummary = <Uri, String>{};
55-
final Map<Uri, String> _moduleImportNameForSummary = <Uri, String>{};
54+
final _libraryToSummary = new Map<Library, Component>.identity();
55+
final _summaryToLibraryBundleName = new Map<Component, String>.identity();
56+
final Map<Uri, String> _summaryToLibraryBundleJSPath = <Uri, String>{};
5657
final String _fileSystemScheme;
5758

5859
late Component _lastFullComponent;
@@ -70,8 +71,9 @@ class IncrementalJavaScriptBundler {
7071
mainUri,
7172
_fileSystem,
7273
);
73-
await _strongComponents.computeModules();
74-
_updateSummaries(_strongComponents.modules.keys, packageConfig);
74+
await _strongComponents.computeLibraryBundles();
75+
_updateSummaries(
76+
_strongComponents.libraryBundleImportToLibraries.keys, packageConfig);
7577
}
7678

7779
/// Update the incremental bundler from a partial component and the last full
@@ -90,13 +92,14 @@ class IncrementalJavaScriptBundler {
9092
_fileSystem,
9193
);
9294

93-
await _strongComponents.computeModules(<Uri, Library>{
95+
await _strongComponents.computeLibraryBundles(<Uri, Library>{
9496
for (Library library in partialComponent.libraries)
9597
library.importUri: library,
9698
});
9799
Set<Uri> invalidated = <Uri>{
98100
for (Library library in partialComponent.libraries)
99-
_strongComponents.moduleAssignment[library.importUri]!,
101+
_strongComponents
102+
.libraryImportToLibraryBundleImport[library.importUri]!,
100103
};
101104
_updateSummaries(invalidated, packageConfig);
102105
}
@@ -123,10 +126,12 @@ class IncrementalJavaScriptBundler {
123126
}
124127
}
125128

126-
/// Update the summaries [moduleKeys].
127-
void _updateSummaries(Iterable<Uri> moduleKeys, PackageConfig packageConfig) {
128-
for (Uri uri in moduleKeys) {
129-
final List<Library> libraries = _strongComponents.modules[uri]!.toList();
129+
/// Update the summaries using the [libraryBundleImports].
130+
void _updateSummaries(
131+
Iterable<Uri> libraryBundleImports, PackageConfig packageConfig) {
132+
for (Uri uri in libraryBundleImports) {
133+
final List<Library> libraries =
134+
_strongComponents.libraryBundleImportToLibraries[uri]!.toList();
130135
final Component summaryComponent = new Component(
131136
libraries: libraries,
132137
nameRoot: _lastFullComponent.root,
@@ -136,34 +141,33 @@ class IncrementalJavaScriptBundler {
136141
null, false, _currentComponent.mode);
137142

138143
String baseName = urlForComponentUri(uri, packageConfig);
139-
_moduleImportForSummary[uri] = '$baseName.lib.js';
140-
_moduleImportNameForSummary[uri] = makeModuleName(baseName);
144+
_summaryToLibraryBundleJSPath[uri] = '$baseName.lib.js';
145+
// Library bundle loaders loads bundles by bundle names, not paths
146+
String libraryBundleName = makeLibraryBundleName(baseName);
141147

142148
_uriToComponent[uri] = summaryComponent;
143-
// module loaders loads modules by modules names, not paths
144-
String moduleImport = _moduleImportNameForSummary[uri]!;
145149

146150
List<Component> oldSummaries = [];
147-
for (Component summary in _summaryToModule.keys) {
148-
if (_summaryToModule[summary] == moduleImport) {
151+
for (Component summary in _summaryToLibraryBundleName.keys) {
152+
if (_summaryToLibraryBundleName[summary] == libraryBundleName) {
149153
oldSummaries.add(summary);
150154
}
151155
}
152156
for (Component summary in oldSummaries) {
153-
_summaryToModule.remove(summary);
157+
_summaryToLibraryBundleName.remove(summary);
154158
}
155-
_importToSummary
159+
_libraryToSummary
156160
.removeWhere((key, value) => oldSummaries.contains(value));
157161

158162
for (Library library in summaryComponent.libraries) {
159-
assert(!_importToSummary.containsKey(library));
160-
_importToSummary[library] = summaryComponent;
161-
_summaryToModule[summaryComponent] = moduleImport;
163+
assert(!_libraryToSummary.containsKey(library));
164+
_libraryToSummary[library] = summaryComponent;
165+
_summaryToLibraryBundleName[summaryComponent] = libraryBundleName;
162166
}
163167
}
164168
}
165169

166-
/// Compile each component into a single JavaScript module.
170+
/// Compile each component into a single JavaScript library bundle.
167171
Future<Map<String, Compiler>> compile(
168172
ClassHierarchy classHierarchy,
169173
CoreTypes coreTypes,
@@ -187,25 +191,27 @@ class IncrementalJavaScriptBundler {
187191
library.importUri.isScheme('dart')) {
188192
continue;
189193
}
190-
final Uri moduleUri =
191-
_strongComponents.moduleAssignment[library.importUri]!;
192-
if (visited.containsKey(moduleUri)) {
193-
kernel2JsCompilers[library.importUri.toString()] = visited[moduleUri]!;
194+
final Uri libraryBundleImport = _strongComponents
195+
.libraryImportToLibraryBundleImport[library.importUri]!;
196+
if (visited.containsKey(libraryBundleImport)) {
197+
kernel2JsCompilers[library.importUri.toString()] =
198+
visited[libraryBundleImport]!;
194199
continue;
195200
}
196201

197-
final Component summaryComponent = _uriToComponent[moduleUri]!;
202+
final Component summaryComponent = _uriToComponent[libraryBundleImport]!;
198203

199-
// module name to use in trackLibraries
200-
// use full path for tracking if module uri is not a package uri.
201-
final String moduleUrl = urlForComponentUri(moduleUri, packageConfig);
202-
final String moduleName = makeModuleName(moduleUrl);
204+
final String componentUrl =
205+
urlForComponentUri(libraryBundleImport, packageConfig);
206+
// library bundle name to use in trackLibraries
207+
// use full path for tracking if library bundle uri is not a package uri.
208+
final String libraryBundleName = makeLibraryBundleName(componentUrl);
203209
final Options ddcOptions = new Options(
204210
sourceMap: true,
205211
summarizeApi: false,
206212
emitDebugMetadata: emitDebugMetadata,
207213
emitDebugSymbols: emitDebugSymbols,
208-
moduleName: moduleName,
214+
moduleName: libraryBundleName,
209215
soundNullSafety: true,
210216
canaryFeatures: canaryFeatures,
211217
moduleFormats: [_moduleFormat],
@@ -215,44 +221,45 @@ class IncrementalJavaScriptBundler {
215221
_currentComponent,
216222
classHierarchy,
217223
ddcOptions,
218-
_importToSummary,
219-
_summaryToModule,
224+
_libraryToSummary,
225+
_summaryToLibraryBundleName,
220226
coreTypes: coreTypes,
221227
)
222228
: new ProgramCompiler(
223229
_currentComponent,
224230
classHierarchy,
225231
ddcOptions,
226-
_importToSummary,
227-
_summaryToModule,
232+
_libraryToSummary,
233+
_summaryToLibraryBundleName,
228234
coreTypes: coreTypes,
229235
);
230236

231-
final Program jsModule = compiler.emitModule(summaryComponent);
237+
final Program jsBundle = compiler.emitModule(summaryComponent);
232238

233239
// Save program compiler to reuse for expression evaluation.
234240
kernel2JsCompilers[library.importUri.toString()] = compiler;
235-
visited[moduleUri] = compiler;
241+
visited[libraryBundleImport] = compiler;
236242

237243
String? sourceMapBase;
238-
if (moduleUri.isScheme('package')) {
244+
if (libraryBundleImport.isScheme('package')) {
239245
// Source locations come through as absolute file uris. In order to
240246
// make relative paths in the source map we get the absolute uri for
241-
// the module and make them relative to that.
242-
sourceMapBase = p.dirname((packageConfig.resolve(moduleUri))!.path);
247+
// the library bundle and make them relative to that.
248+
sourceMapBase =
249+
p.dirname((packageConfig.resolve(libraryBundleImport))!.path);
243250
}
244251

245252
final JSCode code = jsProgramToCode(
246-
jsModule,
253+
jsBundle,
247254
ddcOptions.emitLibraryBundle
248255
? ModuleFormat.ddcLibraryBundle
249256
: _moduleFormat,
250257
inlineSourceMap: true,
251258
buildSourceMap: true,
252259
emitDebugMetadata: emitDebugMetadata,
253260
emitDebugSymbols: emitDebugSymbols,
254-
jsUrl: '$moduleUrl.lib.js',
255-
mapUrl: '$moduleUrl.lib.js.map',
261+
jsUrl: '$componentUrl.lib.js',
262+
mapUrl: '$componentUrl.lib.js.map',
256263
sourceMapBase: sourceMapBase,
257264
customScheme: _fileSystemScheme,
258265
compiler: compiler,
@@ -273,8 +280,9 @@ class IncrementalJavaScriptBundler {
273280
if (emitDebugSymbols) {
274281
symbolsSink!.add(symbolsBytes!);
275282
}
276-
final String moduleKey = _moduleImportForSummary[moduleUri]!;
277-
manifest[moduleKey] = {
283+
final String libraryBundleJSPath =
284+
_summaryToLibraryBundleJSPath[libraryBundleImport]!;
285+
manifest[libraryBundleJSPath] = {
278286
'code': <int>[codeOffset, codeOffset += codeBytes.length],
279287
'sourcemap': <int>[
280288
sourceMapOffset,
@@ -297,22 +305,20 @@ class IncrementalJavaScriptBundler {
297305
return kernel2JsCompilers;
298306
}
299307

300-
/// Module name used in the browser to load modules.
308+
/// Library bundle name used in the browser to load library bundles.
301309
///
302-
/// Module names are used to load modules using module
303-
/// paths maps in RequireJS, which treats names with
304-
/// leading '/' or '.js' extensions specially, and tries
305-
/// to load them without mapping.
306-
/// Skip the leading '/' to always load modules via module
307-
/// path maps.
308-
String makeModuleName(String name) {
310+
/// Library bundle names are used to load library bundles using library bundle
311+
/// path maps in RequireJS, which treats names with leading '/' or '.js'
312+
/// extensions specially, and tries to load them without mapping. Skip the
313+
/// leading '/' to always load library bundles via library bundle path maps.
314+
String makeLibraryBundleName(String name) {
309315
return name.startsWith('/') ? name.substring(1) : name;
310316
}
311317

312318
/// Create component url.
313319
///
314-
/// Used as a server path in the browser for the module created
315-
/// from the component.
320+
/// Used as a server path in the browser for the library bundle created from
321+
/// the component.
316322
String urlForComponentUri(Uri componentUri, PackageConfig packageConfig) {
317323
if (!componentUri.isScheme('package')) {
318324
return componentUri.path;

pkg/frontend_server/lib/src/strong_components.dart

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ import 'package:kernel/util/graph.dart';
1313
/// Implements a Path-based strong component algorithm.
1414
/// See https://en.wikipedia.org/wiki/Path-based_strong_component_algorithm
1515
///
16-
/// The file URI for each library is used as an identifier for the module
17-
/// name. [moduleAssignment] will be populated with a mapping of library URI to
18-
/// module name, while [modules] will be populated with a mapping of module
19-
/// name to library set.
16+
/// The file URI for each library is used as an identifier for the library
17+
/// bundle name. [libraryImportToLibraryBundleImport] will be populated with a
18+
/// mapping of library URI to library bundle name, while
19+
/// [libraryBundleImportToLibraries] will be populated with a mapping of library
20+
/// bundle name to library set.
2021
///
2122
/// JavaScript import semantics do not permit circular imports in the same
2223
/// manner that Dart does. When compiling a set of libraries with circular
23-
/// imports, these must be combined into a single JavaScript module.
24+
/// imports, these must be combined into a single JavaScript library bundle.
2425
///
2526
/// On incremental updates, we completely recompute the strongly connected
2627
/// components, but only for the partial component produced.
@@ -47,15 +48,16 @@ class StrongComponents {
4748
/// The filesystem instance for resolving files.
4849
final FileSystem? fileSystem;
4950

50-
/// The set of libraries for each module URI.
51+
/// Libraries for each library bundle URI.
5152
///
52-
/// This is populated after calling [computeModules] once.
53-
final Map<Uri, List<Library>> modules = <Uri, List<Library>>{};
53+
/// This is populated after calling [computeLibraryBundles] once.
54+
final Map<Uri, List<Library>> libraryBundleImportToLibraries =
55+
<Uri, List<Library>>{};
5456

55-
/// The module URI for each library file URI.
57+
/// The library bundle URI for each library URI.
5658
///
57-
/// This is populated after calling [computeModules] once.
58-
final Map<Uri, Uri> moduleAssignment = <Uri, Uri>{};
59+
/// This is populated after calling [computeLibraryBundles] once.
60+
final Map<Uri, Uri> libraryImportToLibraryBundleImport = <Uri, Uri>{};
5961

6062
/// Compute the strongly connected components for the current program.
6163
///
@@ -66,8 +68,9 @@ class StrongComponents {
6668
///
6769
/// Throws an [Exception] if [mainUri] cannot be located in the given
6870
/// component.
69-
Future<void> computeModules([Map<Uri, Library>? partialComponent]) async {
70-
assert(modules.isEmpty);
71+
Future<void> computeLibraryBundles(
72+
[Map<Uri, Library>? partialComponent]) async {
73+
assert(libraryBundleImportToLibraries.isEmpty);
7174
if (component.libraries.isEmpty) {
7275
return;
7376
}
@@ -87,13 +90,16 @@ class StrongComponents {
8790
new _LibraryGraph(entrypoint, loadedLibraries, partialComponent));
8891
for (List<Library> component in results) {
8992
assert(component.isNotEmpty);
90-
final Uri moduleUri = component
93+
// Pick a Uri to associate this component with. We choose the entrypoint
94+
// if it exists or just the first library's Uri.
95+
final Uri componentUri = component
9196
.firstWhere((lib) => lib.importUri == mainUri,
9297
orElse: () => component.first)
9398
.importUri;
94-
modules[moduleUri] = component;
99+
libraryBundleImportToLibraries[componentUri] = component;
95100
for (Library componentLibrary in component) {
96-
moduleAssignment[componentLibrary.importUri] = moduleUri;
101+
libraryImportToLibraryBundleImport[componentLibrary.importUri] =
102+
componentUri;
97103
}
98104
}
99105
}

0 commit comments

Comments
 (0)