chrome-devtools-frontend 1.0.1705227 → 1.0.1708524
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/code-review/SKILL.md +121 -0
- package/eslint.config.mjs +1 -0
- package/front_end/Images/src/nodejsHex.svg +28 -0
- package/front_end/core/sdk/CPUThrottlingManager.ts +14 -10
- package/front_end/core/sdk/DOMModel.ts +73 -21
- package/front_end/core/sdk/DebuggerModel.ts +0 -4
- package/front_end/core/sdk/NetworkRequest.ts +43 -7
- package/front_end/core/sdk/PageResourceLoader.ts +12 -11
- package/front_end/core/sdk/SourceMap.ts +11 -18
- package/front_end/core/sdk/SourceMapFunctionRanges.ts +22 -37
- package/front_end/core/sdk/SourceMapScopeChainEntry.ts +3 -3
- package/front_end/core/sdk/SourceMapScopesInfo.ts +183 -147
- package/front_end/core/text_utils/ContentData.ts +18 -1
- package/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.ts +7 -2
- package/front_end/entrypoints/heap_snapshot_worker/ContextAnalyzer.ts +238 -20
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotLoader.ts +16 -5
- package/front_end/entrypoints/inspector_main/nodeIcon.css +1 -1
- package/front_end/generated/InspectorBackendCommands.ts +8 -2
- package/front_end/generated/SupportedCSSProperties.ts +11 -2
- package/front_end/generated/protocol-mapping.d.ts +31 -0
- package/front_end/generated/protocol-proxy-api.d.ts +32 -0
- package/front_end/generated/protocol.ts +12 -1
- package/front_end/models/ai_assistance/AiAgent2.ts +1 -0
- package/front_end/models/ai_assistance/AiConversation.ts +16 -3
- package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.ts +26 -3
- package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +15 -16
- package/front_end/models/ai_assistance/skills/Skill.ts +1 -2
- package/front_end/models/ai_assistance/skills/SkillRegistry.ts +2 -0
- package/front_end/models/ai_assistance/skills/accessibility.md +8 -7
- package/front_end/models/ai_assistance/skills/lighthouse.md +33 -0
- package/front_end/models/ai_assistance/tools/GetLighthouseAudits.ts +6 -6
- package/front_end/models/ai_assistance/tools/RunLighthouse.ts +8 -5
- package/front_end/models/bindings/CompilerScriptMapping.ts +102 -45
- package/front_end/models/bindings/DebuggerLanguagePlugins.ts +25 -33
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +33 -39
- package/front_end/models/bindings/StylesSourceMapping.ts +3 -0
- package/front_end/models/extensions/ExtensionEndpoint.ts +27 -6
- package/front_end/models/extensions/LanguageExtensionEndpoint.ts +106 -21
- package/front_end/models/extensions/RecorderExtensionEndpoint.ts +4 -2
- package/front_end/models/formatter/FormatterWorkerPool.ts +6 -1
- package/front_end/models/javascript_metadata/NativeFunctions.ts +12 -4
- package/front_end/models/persistence/NetworkPersistenceManager.ts +4 -3
- package/front_end/models/source_map_scopes/NamesResolver.ts +7 -17
- package/front_end/models/stack_trace/StackTraceImpl.ts +138 -47
- package/front_end/models/stack_trace/StackTraceModel.ts +117 -84
- package/front_end/models/stack_trace/Trie.ts +27 -0
- package/front_end/panels/accessibility/ARIAAttributesView.ts +6 -6
- package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +2 -2
- package/front_end/panels/accessibility/AccessibilityNodeView.ts +6 -9
- package/front_end/panels/accessibility/AccessibilitySidebarView.ts +83 -69
- package/front_end/panels/accessibility/AccessibilitySubPane.ts +24 -9
- package/front_end/panels/accessibility/SourceOrderView.ts +7 -3
- package/front_end/panels/accessibility/accessibilitySidebarView.css +5 -3
- package/front_end/panels/application/BackgroundServiceView.ts +1 -0
- package/front_end/panels/application/components/AdsView.ts +6 -6
- package/front_end/panels/application/components/BackForwardCacheView.ts +1 -1
- package/front_end/panels/application/serviceWorkersView.css +1 -1
- package/front_end/panels/common/CommentThreadWidget.ts +30 -1
- package/front_end/panels/common/CommentsOverlayWidget.ts +42 -38
- package/front_end/panels/common/common-meta.ts +21 -9
- package/front_end/panels/console/ConsoleInsightTeaser.ts +25 -19
- package/front_end/panels/console/ConsoleViewMessage.ts +51 -21
- package/front_end/panels/console/console-meta.ts +1 -5
- package/front_end/panels/elements/CSSRuleValidator.ts +3 -0
- package/front_end/panels/elements/ClassesPaneWidget.ts +4 -1
- package/front_end/panels/elements/DOMTreeWidget.ts +207 -586
- package/front_end/panels/elements/ElementsPanel.ts +1 -5
- package/front_end/panels/elements/LayoutPane.ts +17 -20
- package/front_end/panels/elements/StylePropertyTreeElement.ts +100 -5
- package/front_end/panels/lighthouse/LighthouseController.ts +9 -4
- package/front_end/panels/network/NetworkConfigView.ts +231 -187
- package/front_end/panels/network/NetworkLogViewColumns.ts +10 -3
- package/front_end/panels/network/RequestPayloadView.ts +22 -14
- package/front_end/panels/network/ShowMoreDetailsWidget.ts +1 -1
- package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +0 -1
- package/front_end/panels/recorder/RecordingView.ts +42 -47
- package/front_end/panels/recorder/StepEditor.ts +1 -0
- package/front_end/panels/recorder/recordingView.css +4 -4
- package/front_end/panels/security/SecurityPanel.ts +14 -7
- package/front_end/panels/sources/BreakpointEditDialog.ts +13 -1
- package/front_end/panels/sources/CSSPlugin.ts +11 -0
- package/front_end/panels/sources/CoveragePlugin.ts +34 -23
- package/front_end/panels/sources/DebuggerPlugin.ts +66 -54
- package/front_end/panels/sources/EditingLocationHistoryManager.ts +6 -6
- package/front_end/panels/sources/NavigatorView.ts +97 -52
- package/front_end/panels/sources/OpenFileQuickOpen.ts +2 -2
- package/front_end/panels/sources/Plugin.ts +18 -3
- package/front_end/panels/sources/ResourceOriginPlugin.ts +14 -17
- package/front_end/panels/sources/SourcesPanel.ts +1 -1
- package/front_end/panels/sources/SourcesView.ts +67 -157
- package/front_end/panels/sources/TabbedEditorContainer.ts +102 -23
- package/front_end/panels/sources/UISourceCodeFrame.ts +33 -15
- package/front_end/panels/sources/navigatorTree.css +2 -2
- package/front_end/panels/sources/sourcesView.css +17 -27
- package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +1 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/source-map-scopes-codec/README.chromium +2 -2
- package/front_end/third_party/source-map-scopes-codec/package/CONTRIBUTING.md +14 -1
- package/front_end/third_party/source-map-scopes-codec/package/README.md +8 -6
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts +4 -1
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts +3 -1
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts +4 -3
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/deno.json +6 -2
- package/front_end/third_party/source-map-scopes-codec/package/package.json +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js +18 -2
- package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.ts +22 -3
- package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js +33 -5
- package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.ts +41 -5
- package/front_end/third_party/source-map-scopes-codec/package/src/codec.js +0 -2
- package/front_end/third_party/source-map-scopes-codec/package/src/codec.js.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/codec.ts +4 -3
- package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +99 -36
- package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.ts +143 -49
- package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js +3 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.ts +3 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js +40 -18
- package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.ts +51 -21
- package/front_end/third_party/source-map-scopes-codec/package/src/scopes.ts +4 -3
- package/front_end/third_party/source-map-scopes-codec/package/src/vlq.js +18 -4
- package/front_end/third_party/source-map-scopes-codec/package/src/vlq.js.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/vlq.ts +18 -4
- package/front_end/ui/comments/CommentAnchorResolver.ts +17 -0
- package/front_end/ui/comments/CommentOverlayManager.ts +23 -10
- package/front_end/ui/components/suggestion_input/SuggestionInput.ts +10 -1
- package/front_end/ui/components/text_editor/AiCodeCompletionTeaser.ts +1 -1
- package/front_end/ui/components/text_editor/AiCodeGenerationTeaser.ts +2 -2
- package/front_end/ui/components/text_editor/aiCodeCompletionTeaser.css +0 -11
- package/front_end/ui/components/text_editor/aiCodeGenerationTeaser.css +0 -11
- package/front_end/ui/components/text_editor/javascript.ts +128 -52
- package/front_end/ui/legacy/SearchableView.ts +125 -74
- package/front_end/ui/legacy/SoftDropDown.ts +17 -4
- package/front_end/ui/legacy/StackPane.ts +141 -0
- package/front_end/ui/legacy/TextPrompt.ts +37 -7
- package/front_end/ui/legacy/Toolbar.ts +7 -5
- package/front_end/ui/legacy/Widget.ts +3 -3
- package/front_end/ui/legacy/components/inline_editor/PositionAreaEditor.ts +85 -0
- package/front_end/ui/legacy/components/inline_editor/positionAreaEditor.css +61 -0
- package/front_end/ui/legacy/components/source_frame/FontView.ts +5 -5
- package/front_end/ui/legacy/components/source_frame/ImageView.ts +13 -13
- package/front_end/ui/legacy/components/source_frame/ResourceSourceFrame.ts +2 -6
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +3 -2
- package/front_end/ui/legacy/components/utils/Linkifier.ts +21 -45
- package/front_end/ui/legacy/inspectorCommon.css +11 -0
- package/front_end/ui/legacy/legacy.ts +2 -0
- package/front_end/ui/legacy/softContextMenu.css +2 -0
- package/front_end/ui/settings/ConsoleSettings.ts +7 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +10 -0
- package/mcp/mcp.ts +1 -0
- package/package.json +1 -1
- package/front_end/Images/nodeIcon.avif +0 -0
|
@@ -13,19 +13,16 @@ export interface NamedFunctionRange {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Turns a list of {@link NamedFunctionRange}s into a
|
|
17
|
-
* according to the start/end position. Each range is turned into
|
|
16
|
+
* Turns a list of {@link NamedFunctionRange}s into a list of {@link OriginalScope} trees nested
|
|
17
|
+
* according to the start/end position. Each range is turned into an OriginalScope with the `isStackFrame`
|
|
18
18
|
* bit set to denote it as a function and a generic "Function" label.
|
|
19
19
|
*
|
|
20
|
-
* We nest all these function scopes underneath a single global scope that always starts at (0, 0) and
|
|
21
|
-
* reaches to the largest end position.
|
|
22
|
-
*
|
|
23
20
|
* `ranges` can be unsorted but will be sorted in-place.
|
|
24
21
|
*
|
|
25
22
|
* @throws if the ranges are not nested properly. Concretely: start < end for each range, and no
|
|
26
23
|
* "straddling" (i.e. partially overlapping ranges).
|
|
27
24
|
*/
|
|
28
|
-
export function buildOriginalScopes(ranges: NamedFunctionRange[]): ScopesCodec.OriginalScope {
|
|
25
|
+
export function buildOriginalScopes(ranges: NamedFunctionRange[]): ScopesCodec.OriginalScope[] {
|
|
29
26
|
validateStartBeforeEnd(ranges);
|
|
30
27
|
|
|
31
28
|
// 1. Sort ranges by ascending start position.
|
|
@@ -33,27 +30,15 @@ export function buildOriginalScopes(ranges: NamedFunctionRange[]): ScopesCodec.O
|
|
|
33
30
|
// with the higher end position first, because it's the parent.
|
|
34
31
|
ranges.sort((a, b) => comparePositions(a.start, b.start) || comparePositions(b.end, a.end));
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
kind: 'Global',
|
|
40
|
-
isStackFrame: false,
|
|
41
|
-
children: [],
|
|
42
|
-
variables: [],
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
// 2. Build the tree from the ranges.
|
|
46
|
-
const stack: ScopesCodec.OriginalScope[] = [root];
|
|
33
|
+
// 2. Build the trees from the ranges.
|
|
34
|
+
const roots: ScopesCodec.OriginalScope[] = [];
|
|
35
|
+
const stack: ScopesCodec.OriginalScope[] = [];
|
|
47
36
|
for (const range of ranges) {
|
|
48
37
|
// Pop all scopes that precede the current entry (to find the right parent).
|
|
49
|
-
let stackTop = stack.at(-1)
|
|
50
|
-
while (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
stackTop = stack.at(-1) as ScopesCodec.OriginalScope;
|
|
54
|
-
} else {
|
|
55
|
-
break;
|
|
56
|
-
}
|
|
38
|
+
let stackTop = stack.at(-1);
|
|
39
|
+
while (stackTop && comparePositions(stackTop.end, range.start) <= 0) {
|
|
40
|
+
stack.pop();
|
|
41
|
+
stackTop = stack.at(-1);
|
|
57
42
|
}
|
|
58
43
|
|
|
59
44
|
/*
|
|
@@ -66,22 +51,21 @@ export function buildOriginalScopes(ranges: NamedFunctionRange[]): ScopesCodec.O
|
|
|
66
51
|
*
|
|
67
52
|
*i.e.: B.start < A.end < B.end
|
|
68
53
|
*/
|
|
69
|
-
if (comparePositions(range.start, stackTop.end) < 0 && comparePositions(stackTop.end, range.end) < 0) {
|
|
70
|
-
throw new Error(`Range ${JSON.stringify(range)} and ${
|
|
54
|
+
if (stackTop && comparePositions(range.start, stackTop.end) < 0 && comparePositions(stackTop.end, range.end) < 0) {
|
|
55
|
+
throw new Error(`Range ${JSON.stringify(range)} and ${
|
|
56
|
+
JSON.stringify(stackTop, (key, value) => key === 'parent' ? undefined : value)} partially overlap.`);
|
|
71
57
|
}
|
|
72
58
|
|
|
73
|
-
const scope = createScopeFrom(range);
|
|
74
|
-
stackTop
|
|
59
|
+
const scope = createScopeFrom(range, stackTop);
|
|
60
|
+
if (stackTop) {
|
|
61
|
+
stackTop.children.push(scope);
|
|
62
|
+
} else {
|
|
63
|
+
roots.push(scope);
|
|
64
|
+
}
|
|
75
65
|
stack.push(scope);
|
|
76
66
|
}
|
|
77
67
|
|
|
78
|
-
|
|
79
|
-
const lastChild = root.children.at(-1);
|
|
80
|
-
if (lastChild) {
|
|
81
|
-
root.end = lastChild.end;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return root;
|
|
68
|
+
return roots;
|
|
85
69
|
}
|
|
86
70
|
|
|
87
71
|
function validateStartBeforeEnd(ranges: NamedFunctionRange[]): void {
|
|
@@ -92,11 +76,12 @@ function validateStartBeforeEnd(ranges: NamedFunctionRange[]): void {
|
|
|
92
76
|
}
|
|
93
77
|
}
|
|
94
78
|
|
|
95
|
-
function createScopeFrom(range: NamedFunctionRange): ScopesCodec.OriginalScope {
|
|
79
|
+
function createScopeFrom(range: NamedFunctionRange, parent?: ScopesCodec.OriginalScope): ScopesCodec.OriginalScope {
|
|
96
80
|
return {
|
|
97
81
|
...range,
|
|
98
82
|
kind: 'Function',
|
|
99
83
|
isStackFrame: true,
|
|
84
|
+
parent,
|
|
100
85
|
children: [],
|
|
101
86
|
variables: [],
|
|
102
87
|
};
|
|
@@ -183,7 +183,7 @@ class SourceMapScopeRemoteObject extends RemoteObjectImpl {
|
|
|
183
183
|
if (value === null) {
|
|
184
184
|
return SourceMapScopeRemoteObject.#unavailableProperty(variable);
|
|
185
185
|
}
|
|
186
|
-
return new RemoteObjectProperty(variable, value, /* enumerable */
|
|
186
|
+
return new RemoteObjectProperty(variable, value, /* enumerable */ true, /* writable */ false, /* isOwn */ true,
|
|
187
187
|
/* wasThrown */ false);
|
|
188
188
|
});
|
|
189
189
|
|
|
@@ -269,7 +269,7 @@ class SourceMapScopeRemoteObject extends RemoteObjectImpl {
|
|
|
269
269
|
}
|
|
270
270
|
|
|
271
271
|
static #unavailableProperty(name: string): RemoteObjectProperty {
|
|
272
|
-
return new RemoteObjectProperty(
|
|
273
|
-
|
|
272
|
+
return new RemoteObjectProperty(name, null, /* enumerable */ true, /* writeable */ false, /* isOwn */ true,
|
|
273
|
+
/* wasThrown */ false);
|
|
274
274
|
}
|
|
275
275
|
}
|
|
@@ -14,15 +14,18 @@ import {SourceMapScopeChainEntry} from './SourceMapScopeChainEntry.js';
|
|
|
14
14
|
|
|
15
15
|
export class SourceMapScopesInfo {
|
|
16
16
|
readonly #sourceMap: SourceMap;
|
|
17
|
-
readonly #originalScopes: Array<ScopesCodec.OriginalScope|null>;
|
|
17
|
+
readonly #originalScopes: Array<ScopesCodec.OriginalScope[]|null>;
|
|
18
18
|
readonly #generatedRanges: ScopesCodec.GeneratedRange[];
|
|
19
|
+
/** Whether the scope information was derived from the AST and mappings (see {@link createFromAst}). */
|
|
20
|
+
readonly #isFromAst: boolean;
|
|
19
21
|
|
|
20
22
|
#cachedVariablesAndBindingsPresent: boolean|null = null;
|
|
21
23
|
|
|
22
|
-
constructor(sourceMap: SourceMap, scopeInfo: ScopesCodec.ScopeInfo) {
|
|
24
|
+
constructor(sourceMap: SourceMap, scopeInfo: ScopesCodec.ScopeInfo, {isFromAst = false}: {isFromAst?: boolean} = {}) {
|
|
23
25
|
this.#sourceMap = sourceMap;
|
|
24
26
|
this.#originalScopes = scopeInfo.scopes;
|
|
25
27
|
this.#generatedRanges = scopeInfo.ranges;
|
|
28
|
+
this.#isFromAst = isFromAst;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
/**
|
|
@@ -35,20 +38,10 @@ export class SourceMapScopesInfo {
|
|
|
35
38
|
sourceMap: SourceMap, scopeTree: Formatter.FormatterWorkerPool.ScopeTreeNode,
|
|
36
39
|
text: TextUtils.Text.Text): SourceMapScopesInfo {
|
|
37
40
|
const numSourceUrls = sourceMap.sourceURLs().length;
|
|
38
|
-
const
|
|
39
|
-
for (let i = 0; i < numSourceUrls; i++) {
|
|
40
|
-
const scope: ScopesCodec.OriginalScope = {
|
|
41
|
-
start: {line: 0, column: 0},
|
|
42
|
-
end: {line: Number.POSITIVE_INFINITY, column: Number.POSITIVE_INFINITY},
|
|
43
|
-
isStackFrame: false,
|
|
44
|
-
variables: [],
|
|
45
|
-
children: [],
|
|
46
|
-
};
|
|
47
|
-
scopeBySourceUrl.push(scope);
|
|
48
|
-
}
|
|
41
|
+
const scopesBySourceUrl: ScopesCodec.OriginalScope[][] = Array.from({length: numSourceUrls}, () => []);
|
|
49
42
|
|
|
50
43
|
// Convert the entire scopeTree. Returns a root range that encompasses everything,
|
|
51
|
-
// and inserts scopes by sourceIndex into the above
|
|
44
|
+
// and inserts scopes by sourceIndex into the above scopesBySourceUrl.
|
|
52
45
|
const stack: Array<{
|
|
53
46
|
node: Formatter.FormatterWorkerPool.ScopeTreeNode,
|
|
54
47
|
parentRange?: ScopesCodec.GeneratedRange,
|
|
@@ -114,10 +107,8 @@ export class SourceMapScopesInfo {
|
|
|
114
107
|
|
|
115
108
|
let nextParentScopeHint = parentScopeHint;
|
|
116
109
|
if (canMapOriginalPosition && scope) {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
(parentScopeHint && containsOriginal(parentScopeHint, scope)) ? parentScopeHint : rootScope;
|
|
120
|
-
insertInScope(startSearchFrom, scope);
|
|
110
|
+
const startParent = (parentScopeHint && containsOriginal(parentScopeHint, scope)) ? parentScopeHint : undefined;
|
|
111
|
+
insertInScope(sourceIndex, startParent, scope);
|
|
121
112
|
nextParentScopeHint = scope;
|
|
122
113
|
}
|
|
123
114
|
|
|
@@ -126,20 +117,22 @@ export class SourceMapScopesInfo {
|
|
|
126
117
|
}
|
|
127
118
|
}
|
|
128
119
|
|
|
129
|
-
return new SourceMapScopesInfo(sourceMap, {scopes:
|
|
120
|
+
return new SourceMapScopesInfo(sourceMap, {scopes: scopesBySourceUrl, ranges: rootRange ? [rootRange] : []},
|
|
121
|
+
{isFromAst: true});
|
|
130
122
|
|
|
131
123
|
/**
|
|
132
124
|
* Finds the correct place in the tree to insert the new scope.
|
|
133
125
|
* Maintains the invariant that children are sorted and contained by their parent.
|
|
134
126
|
*/
|
|
135
|
-
function insertInScope(
|
|
136
|
-
|
|
127
|
+
function insertInScope(sourceIndex: number, parent: ScopesCodec.OriginalScope|undefined,
|
|
128
|
+
newScope: ScopesCodec.OriginalScope): void {
|
|
129
|
+
let children = parent ? parent.children : scopesBySourceUrl[sourceIndex];
|
|
137
130
|
// Check if the newScope fits strictly inside any of the existing children.
|
|
138
131
|
// We iterate to find the deepest parent to avoid Maximum Call Stack Size Exceeded
|
|
139
132
|
// errors on highly nested scripts.
|
|
140
133
|
while (true) {
|
|
141
134
|
let deeperParent: ScopesCodec.OriginalScope|null = null;
|
|
142
|
-
for (const child of
|
|
135
|
+
for (const child of children) {
|
|
143
136
|
if (containsOriginal(child, newScope)) {
|
|
144
137
|
deeperParent = child;
|
|
145
138
|
break;
|
|
@@ -147,17 +140,18 @@ export class SourceMapScopesInfo {
|
|
|
147
140
|
}
|
|
148
141
|
if (deeperParent) {
|
|
149
142
|
parent = deeperParent;
|
|
143
|
+
children = deeperParent.children;
|
|
150
144
|
} else {
|
|
151
145
|
break;
|
|
152
146
|
}
|
|
153
147
|
}
|
|
154
148
|
|
|
155
|
-
// When here, newScope belongs directly in parent.
|
|
156
|
-
// However, newScope might encompass some of
|
|
149
|
+
// When here, newScope belongs directly in parent (or at the root of the source file).
|
|
150
|
+
// However, newScope might encompass some of the existing children (due
|
|
157
151
|
// to compiler transform quirks or arbitrary insertion order). We must move
|
|
158
152
|
// those children inside newScope.
|
|
159
153
|
const childrenToKeep: ScopesCodec.OriginalScope[] = [];
|
|
160
|
-
for (const child of
|
|
154
|
+
for (const child of children) {
|
|
161
155
|
if (containsOriginal(newScope, child)) {
|
|
162
156
|
// child is actually inside newScope, so re-parent it.
|
|
163
157
|
newScope.children.push(child);
|
|
@@ -177,8 +171,12 @@ export class SourceMapScopesInfo {
|
|
|
177
171
|
childrenToKeep.splice(insertIndex, 0, newScope);
|
|
178
172
|
}
|
|
179
173
|
|
|
180
|
-
// Update parent's children to only be the ones that don't belong to newScope.
|
|
181
|
-
parent
|
|
174
|
+
// Update parent's children (or root scopes) to only be the ones that don't belong to newScope.
|
|
175
|
+
if (parent) {
|
|
176
|
+
parent.children = childrenToKeep;
|
|
177
|
+
} else {
|
|
178
|
+
scopesBySourceUrl[sourceIndex] = childrenToKeep;
|
|
179
|
+
}
|
|
182
180
|
newScope.parent = parent;
|
|
183
181
|
}
|
|
184
182
|
|
|
@@ -196,7 +194,7 @@ export class SourceMapScopesInfo {
|
|
|
196
194
|
}
|
|
197
195
|
}
|
|
198
196
|
|
|
199
|
-
addOriginalScopes(scopes: Array<ScopesCodec.OriginalScope|null>): void {
|
|
197
|
+
addOriginalScopes(scopes: Array<ScopesCodec.OriginalScope[]|null>): void {
|
|
200
198
|
for (const scope of scopes) {
|
|
201
199
|
this.#originalScopes.push(scope);
|
|
202
200
|
}
|
|
@@ -209,62 +207,41 @@ export class SourceMapScopesInfo {
|
|
|
209
207
|
}
|
|
210
208
|
|
|
211
209
|
hasOriginalScopes(sourceIdx: number): boolean {
|
|
212
|
-
return Boolean(this.#originalScopes[sourceIdx]);
|
|
210
|
+
return Boolean(this.#originalScopes[sourceIdx]?.length);
|
|
213
211
|
}
|
|
214
212
|
|
|
215
213
|
isEmpty(): boolean {
|
|
216
|
-
const noScopes = this.#originalScopes.every(
|
|
214
|
+
const noScopes = this.#originalScopes.every(scopes => scopes === null || scopes.length === 0);
|
|
217
215
|
return noScopes && !this.#generatedRanges.length;
|
|
218
216
|
}
|
|
219
217
|
|
|
220
|
-
addOriginalScopesAtIndex(sourceIdx: number,
|
|
221
|
-
if (!this.#originalScopes[sourceIdx]) {
|
|
222
|
-
this.#originalScopes[sourceIdx] =
|
|
218
|
+
addOriginalScopesAtIndex(sourceIdx: number, scopes: ScopesCodec.OriginalScope[]): void {
|
|
219
|
+
if (!this.#originalScopes[sourceIdx]?.length) {
|
|
220
|
+
this.#originalScopes[sourceIdx] = scopes;
|
|
223
221
|
} else {
|
|
224
222
|
throw new Error(`Trying to re-augment existing scopes for source at index: ${sourceIdx}`);
|
|
225
223
|
}
|
|
226
224
|
}
|
|
227
225
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
return this.#isOutlinedFrame(rangeChain);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
#isOutlinedFrame(rangeChain: ScopesCodec.GeneratedRange[]): boolean {
|
|
237
|
-
for (let i = rangeChain.length - 1; i >= 0; --i) {
|
|
238
|
-
if (rangeChain[i].isStackFrame) {
|
|
239
|
-
return rangeChain[i].isHidden;
|
|
240
|
-
}
|
|
226
|
+
#generatedFrameKind(rangeChain: ScopesCodec.GeneratedRange[]): GeneratedFrameKind {
|
|
227
|
+
const functionRange = rangeChain.findLast(range => range.isStackFrame);
|
|
228
|
+
if (!functionRange) {
|
|
229
|
+
// Top-level code.
|
|
230
|
+
return GeneratedFrameKind.VISIBLE;
|
|
241
231
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* @returns true, iff the range surrounding the provided position contains multiple
|
|
247
|
-
* inlined original functions.
|
|
248
|
-
*/
|
|
249
|
-
hasInlinedFrames(generatedLine: number, generatedColumn: number): boolean {
|
|
250
|
-
const rangeChain = this.#findGeneratedRangeChain(generatedLine, generatedColumn);
|
|
251
|
-
for (let i = rangeChain.length - 1; i >= 0; --i) {
|
|
252
|
-
if (rangeChain[i].isStackFrame) {
|
|
253
|
-
// We stop looking for inlined original functions once we reach the current frame.
|
|
254
|
-
return false;
|
|
255
|
-
}
|
|
256
|
-
if (rangeChain[i].callSite) {
|
|
257
|
-
return true;
|
|
258
|
-
}
|
|
232
|
+
if (!functionRange.originalScope) {
|
|
233
|
+
// For scope information derived from the AST, we merely failed to map the function.
|
|
234
|
+
return this.#isFromAst ? GeneratedFrameKind.VISIBLE : GeneratedFrameKind.HIDDEN;
|
|
259
235
|
}
|
|
260
|
-
return
|
|
236
|
+
return functionRange.isHidden ? GeneratedFrameKind.OUTLINED : GeneratedFrameKind.VISIBLE;
|
|
261
237
|
}
|
|
262
238
|
|
|
263
239
|
/**
|
|
264
240
|
* Given a generated position, this returns all the surrounding generated ranges from outer
|
|
265
|
-
* to inner.
|
|
241
|
+
* to inner. When `inlineFrameIndex > 0`, drops inner ranges up to the specified virtual
|
|
242
|
+
* call frame.
|
|
266
243
|
*/
|
|
267
|
-
#findGeneratedRangeChain(line: number, column: number): ScopesCodec.GeneratedRange[] {
|
|
244
|
+
#findGeneratedRangeChain(line: number, column: number, inlineFrameIndex = 0): ScopesCodec.GeneratedRange[] {
|
|
268
245
|
const result: ScopesCodec.GeneratedRange[] = [];
|
|
269
246
|
|
|
270
247
|
(function walkRanges(ranges: ScopesCodec.GeneratedRange[]) {
|
|
@@ -277,6 +254,17 @@ export class SourceMapScopesInfo {
|
|
|
277
254
|
}
|
|
278
255
|
})(this.#generatedRanges);
|
|
279
256
|
|
|
257
|
+
// Drop ranges in the chain until we reach our desired inlined range.
|
|
258
|
+
for (let inlineIndex = 0; inlineIndex < inlineFrameIndex;) {
|
|
259
|
+
const range = result.pop();
|
|
260
|
+
if (!range) {
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
if (range.callSite) {
|
|
264
|
+
++inlineIndex;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
280
268
|
return result;
|
|
281
269
|
}
|
|
282
270
|
|
|
@@ -295,12 +283,8 @@ export class SourceMapScopesInfo {
|
|
|
295
283
|
// We check whether any original scope has a non-empty list of variables, and
|
|
296
284
|
// generated ranges with a non-empty binding list.
|
|
297
285
|
|
|
298
|
-
function walkTree(nodes:
|
|
286
|
+
function walkTree(nodes: ScopesCodec.OriginalScope[]|ScopesCodec.GeneratedRange[]): boolean {
|
|
299
287
|
for (const node of nodes) {
|
|
300
|
-
if (!node) {
|
|
301
|
-
continue;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
288
|
if ('variables' in node && node.variables.length > 0) {
|
|
305
289
|
return true;
|
|
306
290
|
}
|
|
@@ -315,7 +299,7 @@ export class SourceMapScopesInfo {
|
|
|
315
299
|
}
|
|
316
300
|
return false;
|
|
317
301
|
}
|
|
318
|
-
return
|
|
302
|
+
return this.#originalScopes.some(scopes => scopes !== null && walkTree(scopes)) && walkTree(this.#generatedRanges);
|
|
319
303
|
}
|
|
320
304
|
|
|
321
305
|
/**
|
|
@@ -387,28 +371,14 @@ export class SourceMapScopesInfo {
|
|
|
387
371
|
return result;
|
|
388
372
|
}
|
|
389
373
|
|
|
390
|
-
/** Similar to #findGeneratedRangeChain, but takes inlineFrameIndex of virtual call frames into account */
|
|
391
374
|
#findGeneratedRangeChainForFrame(callFrame: CallFrame): ScopesCodec.GeneratedRange[] {
|
|
392
375
|
const {line, column} = scriptRelativePosition(callFrame.location());
|
|
393
|
-
|
|
394
|
-
if (callFrame.inlineFrameIndex === 0) {
|
|
395
|
-
return rangeChain;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
// Drop ranges in the chain until we reach our desired inlined range.
|
|
399
|
-
for (let inlineIndex = 0; inlineIndex < callFrame.inlineFrameIndex;) {
|
|
400
|
-
const range = rangeChain.pop();
|
|
401
|
-
if (range?.callSite) {
|
|
402
|
-
++inlineIndex;
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
return rangeChain;
|
|
376
|
+
return this.#findGeneratedRangeChain(line, column, callFrame.inlineFrameIndex);
|
|
407
377
|
}
|
|
408
378
|
|
|
409
|
-
resolveMappedVariablesAtPosition(line: number, column: number,
|
|
410
|
-
|
|
411
|
-
const rangeChain = this.#findGeneratedRangeChain(line, column);
|
|
379
|
+
resolveMappedVariablesAtPosition(line: number, column: number, ignoreInnerBlockScopes = false,
|
|
380
|
+
inlineFrameIndex = 0): Array<Map<string, string|null>>|null {
|
|
381
|
+
const rangeChain = this.#findGeneratedRangeChain(line, column, inlineFrameIndex);
|
|
412
382
|
const startScope = rangeChain.at(-1)?.originalScope;
|
|
413
383
|
const innerMostScope =
|
|
414
384
|
(startScope && ignoreInnerBlockScopes && this.#findFunctionScopeInOriginalScopeChain(startScope)) || startScope;
|
|
@@ -431,54 +401,53 @@ export class SourceMapScopesInfo {
|
|
|
431
401
|
/**
|
|
432
402
|
* Returns the authored function scope of the function containing the provided generated position.
|
|
433
403
|
*/
|
|
434
|
-
findOriginalFunctionScope(
|
|
404
|
+
findOriginalFunctionScope(position: ScopesCodec.Position):
|
|
435
405
|
{scope: ScopesCodec.OriginalScope, url?: Platform.DevToolsPath.UrlString}|null {
|
|
406
|
+
const rangeChain = this.#findGeneratedRangeChain(position.line, position.column);
|
|
407
|
+
const functionScope =
|
|
408
|
+
this.#findFunctionScopeInOriginalScopeChain(this.#innerMostOriginalScope(rangeChain, position));
|
|
409
|
+
return functionScope ? {scope: functionScope, url: this.#sourceURLOfScope(functionScope)} : null;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Returns the inner-most original scope containing the generated `position`. `rangeChain` must be the generated
|
|
414
|
+
* range chain of `position`.
|
|
415
|
+
*/
|
|
416
|
+
#innerMostOriginalScope(rangeChain: ScopesCodec.GeneratedRange[],
|
|
417
|
+
position: ScopesCodec.Position): ScopesCodec.OriginalScope|undefined {
|
|
436
418
|
// There are 2 approaches:
|
|
437
419
|
// 1) Find the inner-most generated range containing the provided generated position
|
|
438
|
-
// and use
|
|
420
|
+
// and use its OriginalScope.
|
|
439
421
|
// 2) Use the mappings to turn the generated position into an original position.
|
|
440
422
|
// Then find the inner-most original scope containing that original position.
|
|
441
|
-
// Then walk it outwards until we hit a function.
|
|
442
423
|
//
|
|
443
424
|
// Both approaches should yield the same result (assuming the mappings are spec compliant
|
|
444
425
|
// w.r.t. generated ranges). But in the case of "pasta" scopes and extension provided
|
|
445
426
|
// scope info, we only have the OriginalScope parts and mappings without GeneratedRanges.
|
|
446
|
-
|
|
447
|
-
let originalInnerMostScope: ScopesCodec.OriginalScope|undefined;
|
|
448
|
-
|
|
449
427
|
if (this.#generatedRanges.length > 0) {
|
|
450
|
-
|
|
451
|
-
originalInnerMostScope = rangeChain.at(-1)?.originalScope;
|
|
452
|
-
} else {
|
|
453
|
-
// No GeneratedRanges. Try to use mappings.
|
|
454
|
-
const entry = this.#sourceMap.findEntry(line, column);
|
|
455
|
-
if (entry?.sourceIndex === undefined) {
|
|
456
|
-
return null;
|
|
457
|
-
}
|
|
458
|
-
originalInnerMostScope =
|
|
459
|
-
this.#findOriginalScopeChain(
|
|
460
|
-
{sourceIndex: entry.sourceIndex, line: entry.sourceLineNumber, column: entry.sourceColumnNumber})
|
|
461
|
-
.at(-1);
|
|
428
|
+
return rangeChain.at(-1)?.originalScope;
|
|
462
429
|
}
|
|
463
430
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
const functionScope = this.#findFunctionScopeInOriginalScopeChain(originalInnerMostScope);
|
|
469
|
-
if (!functionScope) {
|
|
470
|
-
return null;
|
|
431
|
+
// No GeneratedRanges. Try to use mappings.
|
|
432
|
+
const entry = this.#sourceMap.findEntry(position.line, position.column);
|
|
433
|
+
if (entry?.sourceIndex === undefined) {
|
|
434
|
+
return undefined;
|
|
471
435
|
}
|
|
436
|
+
return this
|
|
437
|
+
.#findOriginalScopeChain(
|
|
438
|
+
{sourceIndex: entry.sourceIndex, line: entry.sourceLineNumber, column: entry.sourceColumnNumber})
|
|
439
|
+
.at(-1);
|
|
440
|
+
}
|
|
472
441
|
|
|
442
|
+
/** @returns the URL of the original source that `scope` belongs to. */
|
|
443
|
+
#sourceURLOfScope(scope: ScopesCodec.OriginalScope): Platform.DevToolsPath.UrlString|undefined {
|
|
473
444
|
// Find the root scope for some given original source, to get the source url.
|
|
474
|
-
let rootScope: ScopesCodec.OriginalScope =
|
|
445
|
+
let rootScope: ScopesCodec.OriginalScope = scope;
|
|
475
446
|
while (rootScope.parent) {
|
|
476
447
|
rootScope = rootScope.parent;
|
|
477
448
|
}
|
|
478
|
-
const sourceIndex = this.#originalScopes.
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
return functionScope ? {scope: functionScope, url} : null;
|
|
449
|
+
const sourceIndex = this.#originalScopes.findIndex(scopes => scopes?.includes(rootScope));
|
|
450
|
+
return sourceIndex !== -1 ? this.#sourceMap.sourceURLForSourceIndex(sourceIndex) : undefined;
|
|
482
451
|
}
|
|
483
452
|
|
|
484
453
|
/**
|
|
@@ -486,8 +455,8 @@ export class SourceMapScopesInfo {
|
|
|
486
455
|
* to inner.
|
|
487
456
|
*/
|
|
488
457
|
#findOriginalScopeChain({sourceIndex, line, column}: ScopesCodec.OriginalPosition): ScopesCodec.OriginalScope[] {
|
|
489
|
-
const
|
|
490
|
-
if (!
|
|
458
|
+
const scopes = this.#originalScopes[sourceIndex];
|
|
459
|
+
if (!scopes) {
|
|
491
460
|
return [];
|
|
492
461
|
}
|
|
493
462
|
|
|
@@ -500,7 +469,7 @@ export class SourceMapScopesInfo {
|
|
|
500
469
|
result.push(scope);
|
|
501
470
|
walkScopes(scope.children);
|
|
502
471
|
}
|
|
503
|
-
})(
|
|
472
|
+
})(scopes);
|
|
504
473
|
|
|
505
474
|
return result;
|
|
506
475
|
}
|
|
@@ -525,33 +494,54 @@ export class SourceMapScopesInfo {
|
|
|
525
494
|
}
|
|
526
495
|
|
|
527
496
|
/**
|
|
528
|
-
*
|
|
529
|
-
*
|
|
530
|
-
* @returns An empty array if no mapping at the call-site was found, or the resulting frames
|
|
531
|
-
* in top-to-bottom order in case of inlining.
|
|
532
|
-
* @throws If this range is marked "hidden". Outlining needs to be handled externally as
|
|
533
|
-
* outlined function segments in stack traces can span across bundles.
|
|
497
|
+
* Translates a single "raw frame" or call-site, including outlined functions. It's the caller's responsibility to
|
|
498
|
+
* merge outlined frames with their caller(s) (see {@link GeneratedFrameKind}).
|
|
534
499
|
*/
|
|
535
|
-
|
|
500
|
+
translateRawFrame(generatedLine: number, generatedColumn: number): RawFrameTranslation {
|
|
536
501
|
const rangeChain = this.#findGeneratedRangeChain(generatedLine, generatedColumn);
|
|
537
|
-
|
|
538
|
-
|
|
502
|
+
const kind = this.#generatedFrameKind(rangeChain);
|
|
503
|
+
if (kind === GeneratedFrameKind.HIDDEN) {
|
|
504
|
+
return {kind, frames: []};
|
|
539
505
|
}
|
|
506
|
+
const frame = this.#translateTopFrame(generatedLine, generatedColumn, rangeChain);
|
|
507
|
+
return {kind, frames: frame ? [frame, ...this.#translateInlinedCallers(rangeChain)] : []};
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* The top-most frame is translated the same, regardless of whether we have inlined functions: The name is the
|
|
512
|
+
* original function surrounding the generated position, and the location is the mapped generated position.
|
|
513
|
+
*
|
|
514
|
+
* If the generated position has no mapping, the generated ranges may still tell which authored function (or
|
|
515
|
+
* which file, for top-level code) the position belongs to. The frame then has no position.
|
|
516
|
+
*/
|
|
517
|
+
#translateTopFrame(generatedLine: number, generatedColumn: number,
|
|
518
|
+
rangeChain: ScopesCodec.GeneratedRange[]): TranslatedFrame|null {
|
|
519
|
+
const position = {line: generatedLine, column: generatedColumn};
|
|
520
|
+
const innerMostScope = this.#innerMostOriginalScope(rangeChain, position);
|
|
521
|
+
const functionScope = this.#findFunctionScopeInOriginalScopeChain(innerMostScope);
|
|
522
|
+
const name = functionScope ? (functionScope.name ?? '') : undefined;
|
|
540
523
|
|
|
541
524
|
const mapping = this.#sourceMap.findEntry(generatedLine, generatedColumn);
|
|
542
|
-
if (mapping?.sourceIndex
|
|
543
|
-
return
|
|
525
|
+
if (mapping?.sourceIndex !== undefined) {
|
|
526
|
+
return {
|
|
527
|
+
line: mapping.sourceLineNumber,
|
|
528
|
+
column: mapping.sourceColumnNumber,
|
|
529
|
+
name,
|
|
530
|
+
url: mapping.sourceURL,
|
|
531
|
+
functionStart: functionScope?.start,
|
|
532
|
+
};
|
|
544
533
|
}
|
|
534
|
+
if (!innerMostScope) {
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
return {name, url: this.#sourceURLOfScope(functionScope ?? innerMostScope), functionStart: functionScope?.start};
|
|
538
|
+
}
|
|
545
539
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
url: mapping.sourceURL,
|
|
552
|
-
}];
|
|
553
|
-
|
|
554
|
-
// Walk the range chain inside out until we find a generated function and for each inlined function add a frame.
|
|
540
|
+
/**
|
|
541
|
+
* Walk the range chain inside out until we find a generated function and for each inlined function add a frame.
|
|
542
|
+
*/
|
|
543
|
+
#translateInlinedCallers(rangeChain: ScopesCodec.GeneratedRange[]): TranslatedFrame[] {
|
|
544
|
+
const result: TranslatedFrame[] = [];
|
|
555
545
|
for (let i = rangeChain.length - 1; i >= 0 && !rangeChain[i].isStackFrame; --i) {
|
|
556
546
|
const range = rangeChain[i];
|
|
557
547
|
if (!range.callSite) {
|
|
@@ -559,11 +549,13 @@ export class SourceMapScopesInfo {
|
|
|
559
549
|
}
|
|
560
550
|
|
|
561
551
|
const originalScopeChain = this.#findOriginalScopeChain(range.callSite);
|
|
552
|
+
const functionScope = this.#findFunctionScopeInOriginalScopeChain(originalScopeChain.at(-1));
|
|
562
553
|
result.push({
|
|
563
554
|
line: range.callSite.line,
|
|
564
555
|
column: range.callSite.column,
|
|
565
|
-
name:
|
|
556
|
+
name: functionScope ? (functionScope.name ?? '') : undefined,
|
|
566
557
|
url: this.#sourceMap.sourceURLForSourceIndex(range.callSite.sourceIndex),
|
|
558
|
+
functionStart: functionScope?.start,
|
|
567
559
|
});
|
|
568
560
|
}
|
|
569
561
|
|
|
@@ -571,17 +563,61 @@ export class SourceMapScopesInfo {
|
|
|
571
563
|
}
|
|
572
564
|
}
|
|
573
565
|
|
|
566
|
+
/**
|
|
567
|
+
* Describes how the generated function surrounding a generated position shows up in stack traces.
|
|
568
|
+
*
|
|
569
|
+
* Compilers tend to introduce functions (and calls to them) that don't exist in the authored code. The scopes
|
|
570
|
+
* proposal distinguishes two cases:
|
|
571
|
+
*
|
|
572
|
+
* 1) The generated function contains authored code, e.g. a block scope that was turned into a function. The
|
|
573
|
+
* generated range is marked "hidden", but links to the original scope via its definition. We can pause
|
|
574
|
+
* in such a function, but the frame is merged with its caller(s) in stack traces: The outlined code
|
|
575
|
+
* logically belongs to the (authored) function that transitively calls it.
|
|
576
|
+
*
|
|
577
|
+
* 2) The generated function doesn't represent any authored code, e.g. a compiler helper. The generated range
|
|
578
|
+
* has no definition. The scopes spec is being updated to say that such a range can be ignored in stack
|
|
579
|
+
* traces, so we drop these frames.
|
|
580
|
+
*/
|
|
581
|
+
export const enum GeneratedFrameKind {
|
|
582
|
+
/** A regular (possibly with inlined functions) generated function, or top-level code. */
|
|
583
|
+
VISIBLE = 'VISIBLE',
|
|
584
|
+
/** A generated function marked as "hidden" that has a definition (case 1). */
|
|
585
|
+
OUTLINED = 'OUTLINED',
|
|
586
|
+
/** A generated function without a definition (case 2). */
|
|
587
|
+
HIDDEN = 'HIDDEN',
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/** See {@link SourceMapScopesInfo.translateRawFrame}. */
|
|
591
|
+
export interface RawFrameTranslation {
|
|
592
|
+
kind: GeneratedFrameKind;
|
|
593
|
+
/**
|
|
594
|
+
* [top, ...inlinedCallers] in top-to-bottom order. Empty for {@link GeneratedFrameKind.HIDDEN} frames, or if
|
|
595
|
+
* neither the mappings nor the generated ranges know anything about the generated position.
|
|
596
|
+
*
|
|
597
|
+
* For {@link GeneratedFrameKind.OUTLINED} frames, the top frame is named after the authored function the outlined
|
|
598
|
+
* code belongs to.
|
|
599
|
+
*/
|
|
600
|
+
frames: TranslatedFrame[];
|
|
601
|
+
}
|
|
602
|
+
|
|
574
603
|
/**
|
|
575
604
|
* Represents a stack frame in original terms. It closely aligns with StackTrace.StackTrace.Frame,
|
|
576
605
|
* but since we can't import that type here we mirror it here somewhat.
|
|
577
606
|
*
|
|
578
|
-
* Equivalent to Pick<StackTrace.StackTrace.Frame, 'line'|'column'|'name'|'url'
|
|
607
|
+
* Equivalent to Pick<StackTrace.StackTrace.Frame, 'line'|'column'|'name'|'url'>, except that the position is
|
|
608
|
+
* optional.
|
|
579
609
|
*/
|
|
580
610
|
export interface TranslatedFrame {
|
|
581
|
-
|
|
582
|
-
|
|
611
|
+
/**
|
|
612
|
+
* `line` and `column` are undefined iff the generated position has no mapping. The frame then only identifies
|
|
613
|
+
* the authored function: `name`, `functionStart` and the `url` of the function's source.
|
|
614
|
+
*/
|
|
615
|
+
line?: number;
|
|
616
|
+
column?: number;
|
|
583
617
|
name?: string;
|
|
584
618
|
url?: Platform.DevToolsPath.UrlString;
|
|
619
|
+
/** Start of the original function scope containing this frame's position. Undefined for top-level code. */
|
|
620
|
+
functionStart?: ScopesCodec.Position;
|
|
585
621
|
}
|
|
586
622
|
|
|
587
623
|
export function findExpression(range: ScopesCodec.GeneratedRange|undefined, index: number, line = 0,
|