Created
August 4, 2022 21:48
-
-
Save jasonLaster/eceabf785784a03ca42d3ce2c18d7bf8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/packages/protocol/thread/thread.ts b/packages/protocol/thread/thread.ts | |
index da1347c2a..f5962bfb1 100644 | |
--- a/packages/protocol/thread/thread.ts | |
+++ b/packages/protocol/thread/thread.ts | |
@@ -1053,293 +1053,6 @@ class _ThreadFront { | |
column: preferredLocation.column, | |
}; | |
} | |
- | |
- // Given an RRP MappedLocation array with locations in different sources | |
- // representing the same generated location (i.e. a generated location plus | |
- // all the corresponding locations in original or pretty printed sources etc.), | |
- // choose the location which we should be using within the devtools. Normally | |
- // this is the most original location, except when preferSource has been used | |
- // to prefer a generated source instead. | |
- async getPreferredLocation(locations: MappedLocation) { | |
- await this.ensureAllSources(); | |
- return this.getPreferredLocationRaw(locations); | |
- } | |
- | |
- async getAlternateLocation(locations: MappedLocation) { | |
- await Promise.all(locations.map(({ sourceId }) => this.ensureSource(sourceId))); | |
- const { alternateId } = this._chooseSourceId(locations.map(l => l.sourceId)); | |
- if (alternateId) { | |
- return locations.find(l => l.sourceId == alternateId); | |
- } | |
- return null; | |
- } | |
- | |
- getGeneratedLocation(locations: MappedLocation) { | |
- const sourceIds = new Set<SourceId>(locations.map(location => location.sourceId)); | |
- return locations.find(location => { | |
- const generated = this.getGeneratedSourceIds(location.sourceId); | |
- if (!generated) { | |
- return true; | |
- } | |
- // Don't return a location if it is an original version of another one of the given locations. | |
- return !generated.some(generatedId => sourceIds.has(generatedId)); | |
- }); | |
- } | |
- | |
- // Get the source which should be used in the devtools from an array of | |
- // sources representing the same location. If the chosen source is an | |
- // original or generated source and there is an alternative which users | |
- // can switch to, also returns that alternative. | |
- private _chooseSourceId(sourceIds: SourceId[]) { | |
- const fallbackSourceId = sourceIds[0]; | |
- | |
- // Ignore inline sources if we have an HTML source containing them. | |
- if (sourceIds.some(id => this.getSourceKind(id) == "html")) { | |
- sourceIds = sourceIds.filter(id => this.getSourceKind(id) != "inlineScript"); | |
- } | |
- | |
- // Ignore minified sources. | |
- sourceIds = sourceIds.filter(id => !this.isMinifiedSource(id)); | |
- | |
- // Determine the base generated/original ID to use for the source. | |
- let generatedId, originalId; | |
- for (const id of sourceIds) { | |
- const info = this.sources.get(id); | |
- if (!info) { | |
- // Sources haven't finished loading, bail out and return this one. | |
- return { sourceId: id }; | |
- } | |
- // Determine the kind of this source, or its minified version. | |
- let kind = info.kind; | |
- if (kind == "prettyPrinted") { | |
- const minifiedInfo = info.generatedSourceIds | |
- ? this.sources.get(info.generatedSourceIds[0]) | |
- : undefined; | |
- if (!minifiedInfo) { | |
- return { sourceId: id }; | |
- } | |
- kind = minifiedInfo.kind; | |
- assert(kind != "prettyPrinted", "source kind must not be prettyPrinted"); | |
- } | |
- if (kind == "sourceMapped") { | |
- originalId = id; | |
- } else { | |
- assert(!generatedId, "there should be no generatedId"); | |
- generatedId = id; | |
- } | |
- } | |
- | |
- if (!generatedId) { | |
- assert(originalId, "there should be an originalId"); | |
- // backend issues like #1310 may cause a situation where there is no originalId, | |
- // in this case it's better to return some sourceId instead of undefined | |
- return { sourceId: originalId || fallbackSourceId }; | |
- } | |
- | |
- if (!originalId) { | |
- return { sourceId: generatedId }; | |
- } | |
- | |
- // Prefer original sources over generated sources, except when overridden | |
- // through user action. | |
- if (this.preferredGeneratedSources.has(generatedId)) { | |
- return { sourceId: generatedId, alternateId: originalId }; | |
- } | |
- return { sourceId: originalId, alternateId: generatedId }; | |
- } | |
- | |
- // Get the set of chosen sources from a list of source IDs which might | |
- // represent different generated locations. | |
- private _chooseSourceIdList(sourceIds: SourceId[]) { | |
- const groups = this._groupSourceIds(sourceIds); | |
- return groups.map(ids => this._chooseSourceId(ids)); | |
- } | |
- | |
- // Group together a set of source IDs according to whether they are generated | |
- // or original versions of each other. | |
- private _groupSourceIds(sourceIds: SourceId[]) { | |
- const groups = []; | |
- while (sourceIds.length) { | |
- const id = sourceIds[0]; | |
- const group = [...this.getAlternateSourceIds(id)].filter(id => sourceIds.includes(id)); | |
- groups.push(group); | |
- sourceIds = sourceIds.filter(id => !group.includes(id)); | |
- } | |
- return groups; | |
- } | |
- | |
- // Get all original/generated IDs which can represent a location in sourceId. | |
- getAlternateSourceIds(sourceId: SourceId) { | |
- if (this.alternateSourceIds.has(sourceId)) { | |
- return this.alternateSourceIds.get(sourceId)!; | |
- } | |
- | |
- const rv = new Set<SourceId>(); | |
- let currentSourceId = sourceId; | |
- const worklist = [currentSourceId]; | |
- | |
- while (worklist.length) { | |
- currentSourceId = worklist.pop()!; | |
- if (rv.has(currentSourceId)) { | |
- continue; | |
- } | |
- rv.add(currentSourceId); | |
- const sources = this.sources.get(currentSourceId); | |
- assert(sources, "no sources found for sourceId"); | |
- | |
- const { generatedSourceIds } = sources; | |
- (generatedSourceIds || []).forEach(id => worklist.push(id)); | |
- | |
- const originalSourceIds = this.originalSources.map.get(currentSourceId); | |
- (originalSourceIds || []).forEach(id => worklist.push(id)); | |
- } | |
- | |
- if (this.hasAllSources) { | |
- this.alternateSourceIds.set(sourceId, rv); | |
- } | |
- return rv; | |
- } | |
- | |
- // Return whether sourceId is minified and has a pretty printed alternate. | |
- isMinifiedSource(sourceId: SourceId) { | |
- return !!this.getPrettyPrintedSourceId(sourceId); | |
- } | |
- | |
- getPrettyPrintedSourceId(sourceId: SourceId) { | |
- const originalIds = this.originalSources.map.get(sourceId) || []; | |
- return originalIds.find(id => { | |
- const info = this.sources.get(id); | |
- return info && info.kind == "prettyPrinted"; | |
- }); | |
- } | |
- | |
- isSourceMappedSource(sourceId: SourceId) { | |
- const info = this.sources.get(sourceId); | |
- if (!info) { | |
- return false; | |
- } | |
- let kind = info.kind; | |
- if (kind == "prettyPrinted") { | |
- const minifiedInfo = info.generatedSourceIds | |
- ? this.sources.get(info.generatedSourceIds[0]) | |
- : undefined; | |
- if (!minifiedInfo) { | |
- return false; | |
- } | |
- kind = minifiedInfo.kind; | |
- assert(kind != "prettyPrinted", "source kind must not be prettyPrinted"); | |
- } | |
- return kind == "sourceMapped"; | |
- } | |
- | |
- preferSource(sourceId: SourceId, value: boolean) { | |
- assert(!this.isSourceMappedSource(sourceId), "source is not sourceMapped"); | |
- if (value) { | |
- this.preferredGeneratedSources.add(sourceId); | |
- } else { | |
- this.preferredGeneratedSources.delete(sourceId); | |
- } | |
- } | |
- | |
- hasPreferredGeneratedSource(location: MappedLocation) { | |
- return location.some(({ sourceId }) => { | |
- return this.preferredGeneratedSources.has(sourceId); | |
- }); | |
- } | |
- | |
- // Given a location in a generated source, get the preferred location to use. | |
- // This has to query the server to get the original / pretty printed locations | |
- // corresponding to this generated location, so getPreferredLocation is | |
- // better to use when possible. | |
- async getPreferredMappedLocation(location: Location) { | |
- const mappedLocation = await this.mappedLocations.getMappedLocation(location); | |
- return this.getPreferredLocation(mappedLocation); | |
- } | |
- | |
- // Get the chosen (i.e. preferred and alternate) sources for the given URL. | |
- getChosenSourceIdsForUrl(url: string) { | |
- return this._chooseSourceIdList(this.getSourceIdsForURL(url)); | |
- } | |
- | |
- // Try to group identical sources together and save the result in `correspondingSourceIds` | |
- private groupSourceIds() { | |
- for (const [sourceId, source] of this.sources.entries()) { | |
- if (!source.url) { | |
- this.correspondingSourceIds.set(sourceId, [sourceId]); | |
- continue; | |
- } | |
- if (this.correspondingSourceIds.has(sourceId)) { | |
- continue; | |
- } | |
- | |
- const groups = this.getChosenSourceIdsForUrl(source.url); | |
- assert(groups.length > 0, "no chosen sourceIds found for URL"); | |
- const sourceIdGroups = this.groupByContentHash(groups.map(group => group.sourceId)); | |
- for (const sourceIdGroup of sourceIdGroups.values()) { | |
- for (const sourceId of sourceIdGroup) { | |
- this.correspondingSourceIds.set(sourceId, sourceIdGroup); | |
- } | |
- } | |
- const alternateIdGroups = this.groupByContentHash( | |
- groups | |
- .map(group => group.alternateId) | |
- .filter((alternateId): alternateId is SourceId => !!alternateId) | |
- ); | |
- for (const alternateIdGroup of alternateIdGroups.values()) { | |
- for (const alternateId of alternateIdGroup) { | |
- this.correspondingSourceIds.set(alternateId, alternateIdGroup); | |
- } | |
- } | |
- | |
- if (!this.correspondingSourceIds.has(sourceId)) { | |
- this.correspondingSourceIds.set(sourceId, [sourceId]); | |
- } | |
- } | |
- } | |
- | |
- private groupByContentHash(sourceIds: SourceId[]): Map<string, SourceId[]> { | |
- const sourceIdsByHash = new ArrayMap<string, SourceId>(); | |
- for (const sourceId of sourceIds) { | |
- const source = this.sources.get(sourceId); | |
- assert(source, "no source found for sourceId"); | |
- let hash = source?.contentHash || ""; | |
- // source.contentHash is not set for pretty-printed sources, we use | |
- // the contentHash of the minified version instead | |
- if (source.kind === "prettyPrinted") { | |
- assert( | |
- source.generatedSourceIds?.length === 1, | |
- "a pretty-printed source should have exactly one generated source" | |
- ); | |
- const minifiedSource = this.sources.get(source.generatedSourceIds?.[0]); | |
- assert(minifiedSource?.contentHash, "no contentHash found for minified source"); | |
- hash = "minified:" + minifiedSource?.contentHash; | |
- } else { | |
- assert(hash, "no contentHash found for source that is not pretty-printed"); | |
- } | |
- sourceIdsByHash.add(hash, sourceId); | |
- } | |
- return sourceIdsByHash.map; | |
- } | |
- | |
- getCorrespondingSourceIds(sourceId: SourceId) { | |
- assert(this.hasAllSources, "not all sources have been loaded yet"); | |
- return this.correspondingSourceIds.get(sourceId) || [sourceId]; | |
- } | |
- | |
- // Replace the sourceId in a location with the first corresponding sourceId | |
- updateLocation(location: Location) { | |
- location.sourceId = this.getCorrespondingSourceIds(location.sourceId)[0]; | |
- } | |
- | |
- // Replace all sourceIds in a mapped location with the first corresponding sourceId | |
- updateMappedLocation(mappedLocation: MappedLocation | undefined) { | |
- if (!mappedLocation) { | |
- return; | |
- } | |
- for (const location of mappedLocation) { | |
- this.updateLocation(location); | |
- } | |
- } | |
} | |
export const ThreadFront = new _ThreadFront(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment