Skip to content

Commit 3e92545

Browse files
szuendDevtools-frontend LUCI CQ
authored andcommitted
[source-map] Refactor away 'sourceMapToSourceList' weak map
The 'sourceMapToSourceList' maps from source map objects to a list of sourceURLs which that source map contains. This is also useful when dealing with index source maps. Unfortunately this doesn't play nicely when resolving "sourceIndices" from mappings, since you'd first have to resolve the raw source map object, before you could resolve the full index. This CL cleans this up by getting rid of the weak map alltogether: We store the 'SourceInfo' objects in a plain array, indexed by the "sourceIndex". For index maps, we simply concatenate all the sources in the order of the "child source maps". To preserve the existing behavior (and fast access), we also map the 'sourceURL' to SourceInfo object in a separate map. If a source map contains multiple 'sources' entries that resolve to the same URL, then the first one wins. Same as the old implementation. [email protected] Bug: 390337576 Change-Id: I2ae7c6b3d0667b98390085eb949cdee52375ef7f Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6180299 Reviewed-by: Kim-Anh Tran <[email protected]> Commit-Queue: Simon Zünd <[email protected]>
1 parent dd9806c commit 3e92545

File tree

1 file changed

+31
-45
lines changed

1 file changed

+31
-45
lines changed

front_end/core/sdk/SourceMap.ts

Lines changed: 31 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,8 @@ class ScopeTreeEntry implements ScopeEntry {
174174
}
175175
}
176176

177-
const sourceMapToSourceList = new WeakMap<SourceMapV3, Platform.DevToolsPath.UrlString[]>();
178-
179177
interface SourceInfo {
178+
sourceURL: Platform.DevToolsPath.UrlString;
180179
content: string|null;
181180
ignoreListHint: boolean;
182181
reverseMappings: number[]|null;
@@ -189,7 +188,9 @@ export class SourceMap {
189188
readonly #sourceMappingURL: Platform.DevToolsPath.UrlString;
190189
readonly #baseURL: Platform.DevToolsPath.UrlString;
191190
#mappingsInternal: SourceMapEntry[]|null;
192-
readonly #sourceInfos: Map<Platform.DevToolsPath.UrlString, SourceInfo>;
191+
192+
readonly #sourceInfos: SourceInfo[] = [];
193+
readonly #sourceInfoByURL = new Map<Platform.DevToolsPath.UrlString, SourceInfo>();
193194

194195
#scopesInfo: SourceMapScopesInfo|null = null;
195196

@@ -206,7 +207,6 @@ export class SourceMap {
206207
this.#baseURL = (Common.ParsedURL.schemeIs(sourceMappingURL, 'data:')) ? compiledURL : sourceMappingURL;
207208

208209
this.#mappingsInternal = null;
209-
this.#sourceInfos = new Map();
210210
if ('sections' in this.#json) {
211211
if (this.#json.sections.find(section => 'url' in section)) {
212212
Common.Console.Console.instance().warn(
@@ -225,11 +225,11 @@ export class SourceMap {
225225
}
226226

227227
sourceURLs(): Platform.DevToolsPath.UrlString[] {
228-
return [...this.#sourceInfos.keys()];
228+
return [...this.#sourceInfoByURL.keys()];
229229
}
230230

231231
embeddedContentByURL(sourceURL: Platform.DevToolsPath.UrlString): string|null {
232-
const entry = this.#sourceInfos.get(sourceURL);
232+
const entry = this.#sourceInfoByURL.get(sourceURL);
233233
if (!entry) {
234234
return null;
235235
}
@@ -404,7 +404,7 @@ export class SourceMap {
404404

405405
private reversedMappings(sourceURL: Platform.DevToolsPath.UrlString): number[] {
406406
this.#ensureMappingsProcessed();
407-
return this.#sourceInfos.get(sourceURL)?.reverseMappings ?? [];
407+
return this.#sourceInfoByURL.get(sourceURL)?.reverseMappings ?? [];
408408
}
409409

410410
#ensureMappingsProcessed(): void {
@@ -441,7 +441,7 @@ export class SourceMap {
441441
}
442442

443443
for (const [url, reverseMap] of reverseMappingsPerUrl.entries()) {
444-
const info = this.#sourceInfos.get(url);
444+
const info = this.#sourceInfoByURL.get(url);
445445
if (!info) {
446446
continue;
447447
}
@@ -475,7 +475,6 @@ export class SourceMap {
475475
}
476476

477477
private parseSources(sourceMap: SourceMapV3Object): void {
478-
const sourcesList = [];
479478
const sourceRoot = sourceMap.sourceRoot ?? '';
480479
const ignoreList = new Set(sourceMap.ignoreList ?? sourceMap.x_google_ignoreList);
481480
for (let i = 0; i < sourceMap.sources.length; ++i) {
@@ -495,31 +494,28 @@ export class SourceMap {
495494
const url =
496495
Common.ParsedURL.ParsedURL.completeURL(this.#baseURL, href) || (href as Platform.DevToolsPath.UrlString);
497496
const source = sourceMap.sourcesContent && sourceMap.sourcesContent[i];
498-
sourcesList.push(url);
499-
if (!this.#sourceInfos.has(url)) {
500-
const content = source ?? null;
501-
const ignoreListHint = ignoreList.has(i);
502-
this.#sourceInfos.set(url, {content, ignoreListHint, reverseMappings: null, scopeTree: null});
497+
const sourceInfo: SourceInfo = {
498+
sourceURL: url,
499+
content: source ?? null,
500+
ignoreListHint: ignoreList.has(i),
501+
reverseMappings: null,
502+
scopeTree: null,
503+
};
504+
this.#sourceInfos.push(sourceInfo);
505+
if (!this.#sourceInfoByURL.has(url)) {
506+
this.#sourceInfoByURL.set(url, sourceInfo);
503507
}
504508
}
505-
sourceMapToSourceList.set(sourceMap, sourcesList);
506509
}
507510

508511
private parseMap(map: SourceMapV3Object, baseSourceIndex: number, lineNumber: number, columnNumber: number): void {
509-
let sourceIndex = 0;
512+
let sourceIndex = baseSourceIndex;
510513
let sourceLineNumber = 0;
511514
let sourceColumnNumber = 0;
512515
let nameIndex = 0;
513-
// TODO(crbug.com/1011811): refactor away map.
514-
// `sources` can be undefined if it wasn't previously
515-
// processed and added to the list. However, that
516-
// is not WAI and we should make sure that we can
517-
// only reach this point when we are certain
518-
// we have the list available.
519-
const sources = sourceMapToSourceList.get(map);
520516
const names = map.names ?? [];
521517
const tokenIter = new TokenIterator(map.mappings);
522-
let sourceURL: Platform.DevToolsPath.UrlString|undefined = sources && sources[sourceIndex];
518+
let sourceURL: Platform.DevToolsPath.UrlString = this.#sourceInfos[sourceIndex].sourceURL;
523519

524520
while (true) {
525521
if (tokenIter.peek() === ',') {
@@ -544,50 +540,40 @@ export class SourceMap {
544540
const sourceIndexDelta = tokenIter.nextVLQ();
545541
if (sourceIndexDelta) {
546542
sourceIndex += sourceIndexDelta;
547-
if (sources) {
548-
sourceURL = sources[sourceIndex];
549-
}
543+
sourceURL = this.#sourceInfos[sourceIndex].sourceURL;
550544
}
551545
sourceLineNumber += tokenIter.nextVLQ();
552546
sourceColumnNumber += tokenIter.nextVLQ();
553547

554548
if (!tokenIter.hasNext() || this.isSeparator(tokenIter.peek())) {
555-
this.mappings().push(new SourceMapEntry(
556-
lineNumber, columnNumber, baseSourceIndex + sourceIndex, sourceURL, sourceLineNumber, sourceColumnNumber));
549+
this.mappings().push(
550+
new SourceMapEntry(lineNumber, columnNumber, sourceIndex, sourceURL, sourceLineNumber, sourceColumnNumber));
557551
continue;
558552
}
559553

560554
nameIndex += tokenIter.nextVLQ();
561555
this.mappings().push(new SourceMapEntry(
562-
lineNumber, columnNumber, baseSourceIndex + sourceIndex, sourceURL, sourceLineNumber, sourceColumnNumber,
563-
names[nameIndex]));
556+
lineNumber, columnNumber, sourceIndex, sourceURL, sourceLineNumber, sourceColumnNumber, names[nameIndex]));
564557
}
565558

566559
if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.USE_SOURCE_MAP_SCOPES)) {
567-
this.parseBloombergScopes(map);
560+
this.parseBloombergScopes(map, baseSourceIndex);
568561
this.#parseScopes(map);
569562
}
570563
}
571564

572-
private parseBloombergScopes(map: SourceMapV3Object): void {
565+
private parseBloombergScopes(map: SourceMapV3Object, baseSourceIndex: number): void {
573566
if (!map.x_com_bloomberg_sourcesFunctionMappings) {
574567
return;
575568
}
576-
const sources = sourceMapToSourceList.get(map);
577-
if (!sources) {
578-
return;
579-
}
580569
const names = map.names ?? [];
581570
const scopeList = map.x_com_bloomberg_sourcesFunctionMappings;
582571

583-
for (let i = 0; i < sources?.length; i++) {
584-
if (!scopeList[i] || !sources[i]) {
585-
continue;
586-
}
587-
const sourceInfo = this.#sourceInfos.get(sources[i]);
588-
if (!sourceInfo) {
572+
for (let i = 0; i < scopeList.length; i++) {
573+
if (!scopeList[i]) {
589574
continue;
590575
}
576+
const sourceInfo = this.#sourceInfos[baseSourceIndex + i];
591577
const scopes = scopeList[i];
592578

593579
let nameIndex = 0;
@@ -656,7 +642,7 @@ export class SourceMap {
656642

657643
findScopeEntry(sourceURL: Platform.DevToolsPath.UrlString, sourceLineNumber: number, sourceColumnNumber: number):
658644
ScopeEntry|null {
659-
const sourceInfo = this.#sourceInfos.get(sourceURL);
645+
const sourceInfo = this.#sourceInfoByURL.get(sourceURL);
660646
if (!sourceInfo || !sourceInfo.scopeTree) {
661647
return null;
662648
}
@@ -766,7 +752,7 @@ export class SourceMap {
766752
}
767753

768754
hasIgnoreListHint(sourceURL: Platform.DevToolsPath.UrlString): boolean {
769-
return this.#sourceInfos.get(sourceURL)?.ignoreListHint ?? false;
755+
return this.#sourceInfoByURL.get(sourceURL)?.ignoreListHint ?? false;
770756
}
771757

772758
/**

0 commit comments

Comments
 (0)