chrome-devtools-frontend 1.0.1009983 → 1.0.1010492
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/extension-api/ExtensionAPI.d.ts +5 -5
- package/front_end/core/host/UserMetrics.ts +3 -1
- package/front_end/core/i18n/locales/en-US.json +13 -4
- package/front_end/core/i18n/locales/en-XL.json +13 -4
- package/front_end/core/sdk/DebuggerModel.ts +12 -3
- package/front_end/core/sdk/EmulationModel.ts +9 -3
- package/front_end/models/bindings/BreakpointManager.ts +1 -1
- package/front_end/models/bindings/DebuggerLanguagePlugins.ts +72 -65
- package/front_end/models/bindings/ResourceScriptMapping.ts +12 -0
- package/front_end/models/extensions/ExtensionAPI.ts +3 -3
- package/front_end/models/extensions/ExtensionServer.ts +2 -2
- package/front_end/models/extensions/RecorderExtensionEndpoint.ts +5 -5
- package/front_end/panels/console/ConsoleViewMessage.ts +2 -1
- package/front_end/panels/sources/CallStackSidebarPane.ts +11 -4
- package/front_end/panels/sources/DebuggerPlugin.ts +51 -1
- package/front_end/ui/legacy/Infobar.ts +1 -0
- package/front_end/ui/legacy/infobar.css +17 -0
- package/package.json +1 -1
@@ -181,7 +181,8 @@ export namespace Chrome {
|
|
181
181
|
* A new raw module has been loaded. If the raw wasm module references an external debug info module, its URL will be
|
182
182
|
* passed as symbolsURL.
|
183
183
|
*/
|
184
|
-
addRawModule(rawModuleId: string, symbolsURL: string|undefined, rawModule: RawModule):
|
184
|
+
addRawModule(rawModuleId: string, symbolsURL: string|undefined, rawModule: RawModule):
|
185
|
+
Promise<string[]|{missingSymbolFiles: string[]}>;
|
185
186
|
|
186
187
|
/**
|
187
188
|
* Find locations in raw modules from a location in a source file.
|
@@ -242,9 +243,8 @@ export namespace Chrome {
|
|
242
243
|
/**
|
243
244
|
* Find locations in source files from a location in a raw module
|
244
245
|
*/
|
245
|
-
getFunctionInfo(rawLocation: RawLocation):
|
246
|
-
|
247
|
-
}>;
|
246
|
+
getFunctionInfo(rawLocation: RawLocation):
|
247
|
+
Promise<{frames: Array<FunctionInfo>}|{missingSymbolFiles: Array<string>}>;
|
248
248
|
|
249
249
|
/**
|
250
250
|
* Find locations in raw modules corresponding to the inline function
|
@@ -279,7 +279,7 @@ export namespace Chrome {
|
|
279
279
|
}
|
280
280
|
|
281
281
|
export interface RecorderExtensions {
|
282
|
-
registerRecorderExtensionPlugin(plugin: RecorderExtensionPlugin, pluginName: string,
|
282
|
+
registerRecorderExtensionPlugin(plugin: RecorderExtensionPlugin, pluginName: string, mediaType: string):
|
283
283
|
Promise<void>;
|
284
284
|
unregisterRecorderExtensionPlugin(plugin: RecorderExtensionPlugin): Promise<void>;
|
285
285
|
}
|
@@ -939,7 +939,9 @@ export enum RecordingEdited {
|
|
939
939
|
export enum RecordingExported {
|
940
940
|
ToPuppeteer = 1,
|
941
941
|
ToJSON = 2,
|
942
|
-
|
942
|
+
ToPuppeteerReplay = 3,
|
943
|
+
ToExtension = 4,
|
944
|
+
MaxValue = 5,
|
943
945
|
}
|
944
946
|
|
945
947
|
/* eslint-disable @typescript-eslint/naming-convention */
|
@@ -1241,6 +1241,9 @@
|
|
1241
1241
|
"models/bindings/ContentProviderBasedProject.ts | unknownErrorLoadingFile": {
|
1242
1242
|
"message": "Unknown error loading file"
|
1243
1243
|
},
|
1244
|
+
"models/bindings/DebuggerLanguagePlugins.ts | debugSymbolsIncomplete": {
|
1245
|
+
"message": "The debug information for function {PH1} is incomplete"
|
1246
|
+
},
|
1244
1247
|
"models/bindings/DebuggerLanguagePlugins.ts | errorInDebuggerLanguagePlugin": {
|
1245
1248
|
"message": "Error in debugger language plugin: {PH1}"
|
1246
1249
|
},
|
@@ -1248,7 +1251,7 @@
|
|
1248
1251
|
"message": "[{PH1}] Failed to load debug symbols for {PH2} ({PH3})"
|
1249
1252
|
},
|
1250
1253
|
"models/bindings/DebuggerLanguagePlugins.ts | failedToLoadDebugSymbolsForFunction": {
|
1251
|
-
"message": "
|
1254
|
+
"message": "No debug information for function \"{PH1}\""
|
1252
1255
|
},
|
1253
1256
|
"models/bindings/DebuggerLanguagePlugins.ts | loadedDebugSymbolsForButDidnt": {
|
1254
1257
|
"message": "[{PH1}] Loaded debug symbols for {PH2}, but didn't find any source files"
|
@@ -1262,9 +1265,6 @@
|
|
1262
1265
|
"models/bindings/DebuggerLanguagePlugins.ts | loadingDebugSymbolsForVia": {
|
1263
1266
|
"message": "[{PH1}] Loading debug symbols for {PH2} (via {PH3})..."
|
1264
1267
|
},
|
1265
|
-
"models/bindings/DebuggerLanguagePlugins.ts | symbolFileNotFound": {
|
1266
|
-
"message": "Symbol file \"{PH1}\" not found"
|
1267
|
-
},
|
1268
1268
|
"models/bindings/ResourceScriptMapping.ts | liveEditCompileFailed": {
|
1269
1269
|
"message": "LiveEdit compile failed: {PH1}"
|
1270
1270
|
},
|
@@ -9518,6 +9518,9 @@
|
|
9518
9518
|
"panels/sources/CallStackSidebarPane.ts | copyStackTrace": {
|
9519
9519
|
"message": "Copy stack trace"
|
9520
9520
|
},
|
9521
|
+
"panels/sources/CallStackSidebarPane.ts | debugFileNotFound": {
|
9522
|
+
"message": "Failed to load debug file \"{PH1}\"."
|
9523
|
+
},
|
9521
9524
|
"panels/sources/CallStackSidebarPane.ts | notPaused": {
|
9522
9525
|
"message": "Not paused"
|
9523
9526
|
},
|
@@ -9653,6 +9656,12 @@
|
|
9653
9656
|
"panels/sources/DebuggerPlugin.ts | configure": {
|
9654
9657
|
"message": "Configure"
|
9655
9658
|
},
|
9659
|
+
"panels/sources/DebuggerPlugin.ts | debugFileNotFound": {
|
9660
|
+
"message": "Failed to load debug file \"{PH1}\"."
|
9661
|
+
},
|
9662
|
+
"panels/sources/DebuggerPlugin.ts | debugInfoNotFound": {
|
9663
|
+
"message": "Failed to load any debug info for {PH1}."
|
9664
|
+
},
|
9656
9665
|
"panels/sources/DebuggerPlugin.ts | disableBreakpoint": {
|
9657
9666
|
"message": "{n, plural, =1 {Disable breakpoint} other {Disable all breakpoints in line}}"
|
9658
9667
|
},
|
@@ -1241,6 +1241,9 @@
|
|
1241
1241
|
"models/bindings/ContentProviderBasedProject.ts | unknownErrorLoadingFile": {
|
1242
1242
|
"message": "Ûńk̂ńôẃn̂ ér̂ŕôŕ l̂óâd́îńĝ f́îĺê"
|
1243
1243
|
},
|
1244
|
+
"models/bindings/DebuggerLanguagePlugins.ts | debugSymbolsIncomplete": {
|
1245
|
+
"message": "T̂h́ê d́êb́ûǵ îńf̂ór̂ḿât́îón̂ f́ôŕ f̂ún̂ćt̂íôń {PH1} îś îńĉóm̂ṕl̂ét̂é"
|
1246
|
+
},
|
1244
1247
|
"models/bindings/DebuggerLanguagePlugins.ts | errorInDebuggerLanguagePlugin": {
|
1245
1248
|
"message": "Êŕr̂ór̂ ín̂ d́êb́ûǵĝér̂ ĺâńĝúâǵê ṕl̂úĝín̂: {PH1}"
|
1246
1249
|
},
|
@@ -1248,7 +1251,7 @@
|
|
1248
1251
|
"message": "[{PH1}] F̂áîĺêd́ t̂ó l̂óâd́ d̂éb̂úĝ śŷḿb̂ól̂ś f̂ór̂ {PH2} ({PH3})"
|
1249
1252
|
},
|
1250
1253
|
"models/bindings/DebuggerLanguagePlugins.ts | failedToLoadDebugSymbolsForFunction": {
|
1251
|
-
"message": "
|
1254
|
+
"message": "N̂ó d̂éb̂úĝ ín̂f́ôŕm̂át̂íôń f̂ór̂ f́ûńĉt́îón̂ \"{PH1}\""
|
1252
1255
|
},
|
1253
1256
|
"models/bindings/DebuggerLanguagePlugins.ts | loadedDebugSymbolsForButDidnt": {
|
1254
1257
|
"message": "[{PH1}] L̂óâd́êd́ d̂éb̂úĝ śŷḿb̂ól̂ś f̂ór̂ {PH2}, b́ût́ d̂íd̂ń't̂ f́îńd̂ án̂ý ŝóûŕĉé f̂íl̂éŝ"
|
@@ -1262,9 +1265,6 @@
|
|
1262
1265
|
"models/bindings/DebuggerLanguagePlugins.ts | loadingDebugSymbolsForVia": {
|
1263
1266
|
"message": "[{PH1}] L̂óâd́îńĝ d́êb́ûǵ ŝým̂b́ôĺŝ f́ôŕ {PH2} (v̂íâ {PH3})..."
|
1264
1267
|
},
|
1265
|
-
"models/bindings/DebuggerLanguagePlugins.ts | symbolFileNotFound": {
|
1266
|
-
"message": "Ŝým̂b́ôĺ f̂íl̂é \"{PH1}\" n̂ót̂ f́ôún̂d́"
|
1267
|
-
},
|
1268
1268
|
"models/bindings/ResourceScriptMapping.ts | liveEditCompileFailed": {
|
1269
1269
|
"message": "LiveEdit ĉóm̂ṕîĺê f́âíl̂éd̂: {PH1}"
|
1270
1270
|
},
|
@@ -9518,6 +9518,9 @@
|
|
9518
9518
|
"panels/sources/CallStackSidebarPane.ts | copyStackTrace": {
|
9519
9519
|
"message": "Ĉóp̂ý ŝt́âćk̂ t́r̂áĉé"
|
9520
9520
|
},
|
9521
|
+
"panels/sources/CallStackSidebarPane.ts | debugFileNotFound": {
|
9522
|
+
"message": "F̂áîĺêd́ t̂ó l̂óâd́ d̂éb̂úĝ f́îĺê \"{PH1}\"."
|
9523
|
+
},
|
9521
9524
|
"panels/sources/CallStackSidebarPane.ts | notPaused": {
|
9522
9525
|
"message": "N̂ót̂ ṕâúŝéd̂"
|
9523
9526
|
},
|
@@ -9653,6 +9656,12 @@
|
|
9653
9656
|
"panels/sources/DebuggerPlugin.ts | configure": {
|
9654
9657
|
"message": "Ĉón̂f́îǵûŕê"
|
9655
9658
|
},
|
9659
|
+
"panels/sources/DebuggerPlugin.ts | debugFileNotFound": {
|
9660
|
+
"message": "F̂áîĺêd́ t̂ó l̂óâd́ d̂éb̂úĝ f́îĺê \"{PH1}\"."
|
9661
|
+
},
|
9662
|
+
"panels/sources/DebuggerPlugin.ts | debugInfoNotFound": {
|
9663
|
+
"message": "F̂áîĺêd́ t̂ó l̂óâd́ âńŷ d́êb́ûǵ îńf̂ó f̂ór̂ {PH1}."
|
9664
|
+
},
|
9656
9665
|
"panels/sources/DebuggerPlugin.ts | disableBreakpoint": {
|
9657
9666
|
"message": "{n, plural, =1 {D̂íŝáb̂ĺê b́r̂éâḱp̂óîńt̂} other {D́îśâb́l̂é âĺl̂ b́r̂éâḱp̂óîńt̂ś îń l̂ín̂é}}"
|
9658
9667
|
},
|
@@ -1242,6 +1242,11 @@ export class BreakLocation extends Location {
|
|
1242
1242
|
}
|
1243
1243
|
}
|
1244
1244
|
|
1245
|
+
export interface MissingDebugInfoDetails {
|
1246
|
+
details: string;
|
1247
|
+
resources: string[];
|
1248
|
+
}
|
1249
|
+
|
1245
1250
|
export class CallFrame {
|
1246
1251
|
debuggerModel: DebuggerModel;
|
1247
1252
|
readonly #scriptInternal: Script;
|
@@ -1253,7 +1258,7 @@ export class CallFrame {
|
|
1253
1258
|
readonly #functionNameInternal: string;
|
1254
1259
|
readonly #functionLocationInternal: Location|undefined;
|
1255
1260
|
#returnValueInternal: RemoteObject|null;
|
1256
|
-
|
1261
|
+
#missingDebugInfoDetails: MissingDebugInfoDetails|null = null;
|
1257
1262
|
|
1258
1263
|
readonly canBeRestarted: boolean;
|
1259
1264
|
|
@@ -1299,8 +1304,12 @@ export class CallFrame {
|
|
1299
1304
|
return new CallFrame(this.debuggerModel, this.#scriptInternal, this.payload, inlineFrameIndex, name);
|
1300
1305
|
}
|
1301
1306
|
|
1302
|
-
|
1303
|
-
this
|
1307
|
+
setMissingDebugInfoDetails(details: MissingDebugInfoDetails): void {
|
1308
|
+
this.#missingDebugInfoDetails = details;
|
1309
|
+
}
|
1310
|
+
|
1311
|
+
get missingDebugInfoDetails(): MissingDebugInfoDetails|null {
|
1312
|
+
return this.#missingDebugInfoDetails;
|
1304
1313
|
}
|
1305
1314
|
|
1306
1315
|
get script(): Script {
|
@@ -21,6 +21,7 @@ export class EmulationModel extends SDKModel<void> {
|
|
21
21
|
readonly #mediaConfiguration: Map<string, string>;
|
22
22
|
#touchEnabled: boolean;
|
23
23
|
#touchMobile: boolean;
|
24
|
+
#touchEmulationAllowed: boolean;
|
24
25
|
#customTouchEnabled: boolean;
|
25
26
|
#touchConfiguration: {
|
26
27
|
enabled: boolean,
|
@@ -176,6 +177,7 @@ export class EmulationModel extends SDKModel<void> {
|
|
176
177
|
updateDisabledImageFormats();
|
177
178
|
}
|
178
179
|
|
180
|
+
this.#touchEmulationAllowed = true;
|
179
181
|
this.#touchEnabled = false;
|
180
182
|
this.#touchMobile = false;
|
181
183
|
this.#customTouchEnabled = false;
|
@@ -185,6 +187,10 @@ export class EmulationModel extends SDKModel<void> {
|
|
185
187
|
};
|
186
188
|
}
|
187
189
|
|
190
|
+
setTouchEmulationAllowed(touchEmulationAllowed: boolean): void {
|
191
|
+
this.#touchEmulationAllowed = touchEmulationAllowed;
|
192
|
+
}
|
193
|
+
|
188
194
|
supportsDeviceEmulation(): boolean {
|
189
195
|
return this.target().hasAllCapabilities(Capability.DeviceEmulation);
|
190
196
|
}
|
@@ -322,13 +328,13 @@ export class EmulationModel extends SDKModel<void> {
|
|
322
328
|
}
|
323
329
|
|
324
330
|
async emulateTouch(enabled: boolean, mobile: boolean): Promise<void> {
|
325
|
-
this.#touchEnabled = enabled;
|
326
|
-
this.#touchMobile = mobile;
|
331
|
+
this.#touchEnabled = enabled && this.#touchEmulationAllowed;
|
332
|
+
this.#touchMobile = mobile && this.#touchEmulationAllowed;
|
327
333
|
await this.updateTouch();
|
328
334
|
}
|
329
335
|
|
330
336
|
async overrideEmulateTouch(enabled: boolean): Promise<void> {
|
331
|
-
this.#customTouchEnabled = enabled;
|
337
|
+
this.#customTouchEnabled = enabled && this.#touchEmulationAllowed;
|
332
338
|
await this.updateTouch();
|
333
339
|
}
|
334
340
|
|
@@ -153,7 +153,7 @@ export class BreakpointManager extends Common.ObjectWrapper.ObjectWrapper<EventT
|
|
153
153
|
const {pluginManager} = this.debuggerWorkspaceBinding;
|
154
154
|
if (pluginManager) {
|
155
155
|
const sourceUrls = await pluginManager.getSourcesForScript(script);
|
156
|
-
if (sourceUrls) {
|
156
|
+
if (Array.isArray(sourceUrls)) {
|
157
157
|
for (const sourceURL of sourceUrls) {
|
158
158
|
if (this.#hasBreakpointsForUrl(sourceURL)) {
|
159
159
|
const uiSourceCode =
|
@@ -59,12 +59,12 @@ const UIStrings = {
|
|
59
59
|
*@description Error message that is displayed in UI debugging information cannot be found for a call frame
|
60
60
|
*@example {main} PH1
|
61
61
|
*/
|
62
|
-
failedToLoadDebugSymbolsForFunction: '
|
62
|
+
failedToLoadDebugSymbolsForFunction: 'No debug information for function "{PH1}"',
|
63
63
|
/**
|
64
64
|
*@description Error message that is displayed in UI when a file needed for debugging information for a call frame is missing
|
65
|
-
*@example {
|
65
|
+
*@example {mainp.debug.wasm.dwp} PH1
|
66
66
|
*/
|
67
|
-
|
67
|
+
debugSymbolsIncomplete: 'The debug information for function {PH1} is incomplete',
|
68
68
|
};
|
69
69
|
const str_ = i18n.i18n.registerUIStrings('models/bindings/DebuggerLanguagePlugins.ts', UIStrings);
|
70
70
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
@@ -766,7 +766,7 @@ export class DebuggerLanguagePluginManager implements
|
|
766
766
|
rawModuleId: string,
|
767
767
|
plugin: DebuggerLanguagePlugin,
|
768
768
|
scripts: Array<SDK.Script.Script>,
|
769
|
-
addRawModulePromise: Promise<Array<Platform.DevToolsPath.UrlString
|
769
|
+
addRawModulePromise: Promise<Array<Platform.DevToolsPath.UrlString>|{missingSymbolFiles: string[]}>,
|
770
770
|
}>;
|
771
771
|
|
772
772
|
constructor(
|
@@ -819,17 +819,19 @@ export class DebuggerLanguagePluginManager implements
|
|
819
819
|
.all(callFrames.map(async callFrame => {
|
820
820
|
const functionInfo = await this.getFunctionInfo(callFrame.script, callFrame.location());
|
821
821
|
if (functionInfo) {
|
822
|
-
|
823
|
-
|
824
|
-
return frames.map(({name}, index) => callFrame.createVirtualCallFrame(index, name));
|
822
|
+
if ('frames' in functionInfo && functionInfo.frames.length) {
|
823
|
+
return functionInfo.frames.map(({name}, index) => callFrame.createVirtualCallFrame(index, name));
|
825
824
|
}
|
826
|
-
if (missingSymbolFiles && missingSymbolFiles.length) {
|
827
|
-
|
828
|
-
|
829
|
-
}
|
825
|
+
if ('missingSymbolFiles' in functionInfo && functionInfo.missingSymbolFiles.length) {
|
826
|
+
const resources = functionInfo.missingSymbolFiles;
|
827
|
+
const details = i18nString(UIStrings.debugSymbolsIncomplete, {PH1: callFrame.functionName});
|
828
|
+
callFrame.setMissingDebugInfoDetails({details, resources});
|
829
|
+
} else {
|
830
|
+
callFrame.setMissingDebugInfoDetails({
|
831
|
+
resources: [],
|
832
|
+
details: i18nString(UIStrings.failedToLoadDebugSymbolsForFunction, {PH1: callFrame.functionName}),
|
833
|
+
});
|
830
834
|
}
|
831
|
-
callFrame.addWarning(
|
832
|
-
i18nString(UIStrings.failedToLoadDebugSymbolsForFunction, {PH1: callFrame.functionName}));
|
833
835
|
}
|
834
836
|
return callFrame;
|
835
837
|
}))
|
@@ -1069,40 +1071,45 @@ export class DebuggerLanguagePluginManager implements
|
|
1069
1071
|
const rawModuleId = rawModuleIdForScript(script);
|
1070
1072
|
let rawModuleHandle = this.#rawModuleHandles.get(rawModuleId);
|
1071
1073
|
if (!rawModuleHandle) {
|
1072
|
-
const sourceFileURLsPromise =
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1074
|
+
const sourceFileURLsPromise =
|
1075
|
+
(async(): Promise<Platform.DevToolsPath.UrlString[]|{missingSymbolFiles: string[]}> => {
|
1076
|
+
const console = Common.Console.Console.instance();
|
1077
|
+
const url = script.sourceURL;
|
1078
|
+
const symbolsUrl = (script.debugSymbols && script.debugSymbols.externalURL) || '';
|
1079
|
+
if (symbolsUrl) {
|
1080
|
+
console.log(
|
1081
|
+
i18nString(UIStrings.loadingDebugSymbolsForVia, {PH1: plugin.name, PH2: url, PH3: symbolsUrl}));
|
1082
|
+
} else {
|
1083
|
+
console.log(i18nString(UIStrings.loadingDebugSymbolsFor, {PH1: plugin.name, PH2: url}));
|
1084
|
+
}
|
1085
|
+
try {
|
1086
|
+
const code = (!symbolsUrl && url.startsWith('wasm://')) ? await script.getWasmBytecode() : undefined;
|
1087
|
+
const addModuleResult = await plugin.addRawModule(rawModuleId, symbolsUrl, {url, code});
|
1088
|
+
// Check that the handle isn't stale by now. This works because the code that assigns to
|
1089
|
+
// `rawModuleHandle` below will run before this code because of the `await` in the preceding
|
1090
|
+
// line. This is primarily to avoid logging the message below, which would give the developer
|
1091
|
+
// the misleading information that we're done, while in reality it was a stale call that finished.
|
1092
|
+
if (rawModuleHandle !== this.#rawModuleHandles.get(rawModuleId)) {
|
1093
|
+
return [];
|
1094
|
+
}
|
1095
|
+
if ('missingSymbolFiles' in addModuleResult) {
|
1096
|
+
return {missingSymbolFiles: addModuleResult.missingSymbolFiles};
|
1097
|
+
}
|
1098
|
+
const sourceFileURLs = addModuleResult as Platform.DevToolsPath.UrlString[];
|
1099
|
+
if (sourceFileURLs.length === 0) {
|
1100
|
+
console.warn(i18nString(UIStrings.loadedDebugSymbolsForButDidnt, {PH1: plugin.name, PH2: url}));
|
1101
|
+
} else {
|
1102
|
+
console.log(i18nString(
|
1103
|
+
UIStrings.loadedDebugSymbolsForFound, {PH1: plugin.name, PH2: url, PH3: sourceFileURLs.length}));
|
1104
|
+
}
|
1105
|
+
return sourceFileURLs;
|
1106
|
+
} catch (error) {
|
1107
|
+
console.error(i18nString(
|
1108
|
+
UIStrings.failedToLoadDebugSymbolsFor, {PH1: plugin.name, PH2: url, PH3: error.message}));
|
1109
|
+
this.#rawModuleHandles.delete(rawModuleId);
|
1110
|
+
return [];
|
1111
|
+
}
|
1112
|
+
})();
|
1106
1113
|
rawModuleHandle = {rawModuleId, plugin, scripts: [script], addRawModulePromise: sourceFileURLsPromise};
|
1107
1114
|
this.#rawModuleHandles.set(rawModuleId, rawModuleHandle);
|
1108
1115
|
} else {
|
@@ -1114,12 +1121,14 @@ export class DebuggerLanguagePluginManager implements
|
|
1114
1121
|
// for the DebuggerModel again, which may disappear
|
1115
1122
|
// in the meantime...
|
1116
1123
|
void rawModuleHandle.addRawModulePromise.then(sourceFileURLs => {
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
modelData
|
1122
|
-
|
1124
|
+
if (!('missingSymbolFiles' in sourceFileURLs)) {
|
1125
|
+
// The script might have disappeared meanwhile...
|
1126
|
+
if (script.debuggerModel.scriptForId(script.scriptId) === script) {
|
1127
|
+
const modelData = this.#debuggerModelToData.get(script.debuggerModel);
|
1128
|
+
if (modelData) { // The DebuggerModel could have disappeared meanwhile...
|
1129
|
+
modelData.addSourceFiles(script, sourceFileURLs);
|
1130
|
+
void this.#debuggerWorkspaceBinding.updateLocations(script);
|
1131
|
+
}
|
1123
1132
|
}
|
1124
1133
|
}
|
1125
1134
|
});
|
@@ -1127,7 +1136,8 @@ export class DebuggerLanguagePluginManager implements
|
|
1127
1136
|
}
|
1128
1137
|
}
|
1129
1138
|
|
1130
|
-
getSourcesForScript(script: SDK.Script.Script):
|
1139
|
+
getSourcesForScript(script: SDK.Script.Script):
|
1140
|
+
Promise<Array<Platform.DevToolsPath.UrlString>|{missingSymbolFiles: string[]}|undefined> {
|
1131
1141
|
const rawModuleId = rawModuleIdForScript(script);
|
1132
1142
|
const rawModuleHandle = this.#rawModuleHandles.get(rawModuleId);
|
1133
1143
|
if (rawModuleHandle) {
|
@@ -1173,10 +1183,8 @@ export class DebuggerLanguagePluginManager implements
|
|
1173
1183
|
}
|
1174
1184
|
}
|
1175
1185
|
|
1176
|
-
async getFunctionInfo(script: SDK.Script.Script, location: SDK.DebuggerModel.Location):
|
1177
|
-
|
1178
|
-
missingSymbolFiles?: Array<string>,
|
1179
|
-
}|null> {
|
1186
|
+
async getFunctionInfo(script: SDK.Script.Script, location: SDK.DebuggerModel.Location):
|
1187
|
+
Promise<{frames: Array<Chrome.DevTools.FunctionInfo>}|{missingSymbolFiles: string[]}|null> {
|
1180
1188
|
const {rawModuleId, plugin} = await this.rawModuleIdAndPluginForScript(script);
|
1181
1189
|
if (!plugin) {
|
1182
1190
|
return null;
|
@@ -1189,7 +1197,8 @@ export class DebuggerLanguagePluginManager implements
|
|
1189
1197
|
};
|
1190
1198
|
|
1191
1199
|
try {
|
1192
|
-
|
1200
|
+
const functionInfo = await plugin.getFunctionInfo(rawLocation);
|
1201
|
+
return functionInfo;
|
1193
1202
|
} catch (error) {
|
1194
1203
|
Common.Console.Console.instance().warn(i18nString(UIStrings.errorInDebuggerLanguagePlugin, {PH1: error.message}));
|
1195
1204
|
return {frames: []};
|
@@ -1362,7 +1371,7 @@ class ModelData {
|
|
1362
1371
|
}
|
1363
1372
|
}
|
1364
1373
|
|
1365
|
-
export class DebuggerLanguagePlugin {
|
1374
|
+
export class DebuggerLanguagePlugin implements Chrome.DevTools.LanguageExtensionPlugin {
|
1366
1375
|
name: string;
|
1367
1376
|
constructor(name: string) {
|
1368
1377
|
this.name = name;
|
@@ -1378,7 +1387,7 @@ export class DebuggerLanguagePlugin {
|
|
1378
1387
|
/** Notify the #plugin about a new script
|
1379
1388
|
*/
|
1380
1389
|
async addRawModule(_rawModuleId: string, _symbolsURL: string, _rawModule: Chrome.DevTools.RawModule):
|
1381
|
-
Promise<string[]> {
|
1390
|
+
Promise<string[]|{missingSymbolFiles: string[]}> {
|
1382
1391
|
throw new Error('Not implemented yet');
|
1383
1392
|
}
|
1384
1393
|
|
@@ -1445,10 +1454,8 @@ export class DebuggerLanguagePlugin {
|
|
1445
1454
|
/**
|
1446
1455
|
* Find #locations in source files from a #location in a raw module
|
1447
1456
|
*/
|
1448
|
-
async getFunctionInfo(_rawLocation: Chrome.DevTools.RawLocation):
|
1449
|
-
|
1450
|
-
missingSymbolFiles?: Array<string>,
|
1451
|
-
}> {
|
1457
|
+
async getFunctionInfo(_rawLocation: Chrome.DevTools.RawLocation):
|
1458
|
+
Promise<{frames: Array<Chrome.DevTools.FunctionInfo>}|{missingSymbolFiles: string[]}> {
|
1452
1459
|
throw new Error('Not implemented yet');
|
1453
1460
|
}
|
1454
1461
|
|
@@ -423,6 +423,18 @@ export class ResourceScriptFile extends Common.ObjectWrapper.ObjectWrapper<Resou
|
|
423
423
|
return this.scriptInternal !== undefined && Boolean(this.scriptInternal.sourceMapURL);
|
424
424
|
}
|
425
425
|
|
426
|
+
async missingSymbolFiles(): Promise<string[]|null> {
|
427
|
+
if (!this.scriptInternal) {
|
428
|
+
return null;
|
429
|
+
}
|
430
|
+
const {pluginManager} = this.#resourceScriptMapping.debuggerWorkspaceBinding;
|
431
|
+
if (!pluginManager) {
|
432
|
+
return null;
|
433
|
+
}
|
434
|
+
const sources = await pluginManager.getSourcesForScript(this.scriptInternal);
|
435
|
+
return sources && 'missingSymbolFiles' in sources ? sources.missingSymbolFiles : null;
|
436
|
+
}
|
437
|
+
|
426
438
|
get script(): SDK.Script.Script|null {
|
427
439
|
return this.scriptInternal || null;
|
428
440
|
}
|
@@ -133,7 +133,7 @@ export namespace PrivateAPI {
|
|
133
133
|
type RegisterRecorderExtensionPluginRequest = {
|
134
134
|
command: Commands.RegisterRecorderExtensionPlugin,
|
135
135
|
pluginName: string,
|
136
|
-
|
136
|
+
mediaType: string,
|
137
137
|
port: MessagePort,
|
138
138
|
};
|
139
139
|
type SubscribeRequest = {command: Commands.Subscribe, type: string};
|
@@ -713,7 +713,7 @@ self.injectedExtensionAPI = function(
|
|
713
713
|
Pick<APIImpl.RecorderExtensions, 'registerRecorderExtensionPlugin'|'unregisterRecorderExtensionPlugin'>) = {
|
714
714
|
registerRecorderExtensionPlugin: async function(
|
715
715
|
this: APIImpl.RecorderExtensions, plugin: PublicAPI.Chrome.DevTools.RecorderExtensionPlugin, pluginName: string,
|
716
|
-
|
716
|
+
mediaType: string): Promise<void> {
|
717
717
|
if (this._plugins.has(plugin)) {
|
718
718
|
throw new Error(`Tried to register plugin '${pluginName}' twice`);
|
719
719
|
}
|
@@ -744,7 +744,7 @@ self.injectedExtensionAPI = function(
|
|
744
744
|
{
|
745
745
|
command: PrivateAPI.Commands.RegisterRecorderExtensionPlugin,
|
746
746
|
pluginName,
|
747
|
-
|
747
|
+
mediaType,
|
748
748
|
port: channel.port2,
|
749
749
|
},
|
750
750
|
() => resolve(), [channel.port2]);
|
@@ -224,8 +224,8 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
224
224
|
if (message.command !== PrivateAPI.Commands.RegisterRecorderExtensionPlugin) {
|
225
225
|
return this.status.E_BADARG('command', `expected ${PrivateAPI.Commands.RegisterRecorderExtensionPlugin}`);
|
226
226
|
}
|
227
|
-
const {pluginName,
|
228
|
-
RecorderPluginManager.instance().addPlugin(new RecorderExtensionEndpoint(pluginName,
|
227
|
+
const {pluginName, mediaType, port} = message;
|
228
|
+
RecorderPluginManager.instance().addPlugin(new RecorderExtensionEndpoint(pluginName, mediaType, port));
|
229
229
|
return this.status.OK();
|
230
230
|
}
|
231
231
|
|
@@ -8,20 +8,20 @@ import {RecorderPluginManager} from './RecorderPluginManager.js';
|
|
8
8
|
|
9
9
|
export class RecorderExtensionEndpoint extends ExtensionEndpoint {
|
10
10
|
private readonly name: string;
|
11
|
-
private readonly
|
11
|
+
private readonly mediaType: string;
|
12
12
|
|
13
|
-
constructor(name: string,
|
13
|
+
constructor(name: string, mediaType: string, port: MessagePort) {
|
14
14
|
super(port);
|
15
15
|
this.name = name;
|
16
|
-
this.
|
16
|
+
this.mediaType = mediaType;
|
17
17
|
}
|
18
18
|
|
19
19
|
getName(): string {
|
20
20
|
return this.name;
|
21
21
|
}
|
22
22
|
|
23
|
-
|
24
|
-
return this.
|
23
|
+
getMediaType(): string {
|
24
|
+
return this.mediaType;
|
25
25
|
}
|
26
26
|
|
27
27
|
protected handleEvent({event}: {event: string}): void {
|
@@ -1397,7 +1397,8 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
|
|
1397
1397
|
if (scripts.length) {
|
1398
1398
|
const location =
|
1399
1399
|
new SDK.DebuggerModel.Location(debuggerModel, scripts[0].scriptId, lineNumber || 0, columnNumber);
|
1400
|
-
|
1400
|
+
const functionInfo = await debuggerWorkspaceBinding.pluginManager.getFunctionInfo(scripts[0], location);
|
1401
|
+
return functionInfo && 'frames' in functionInfo ? functionInfo : {frames: []};
|
1401
1402
|
}
|
1402
1403
|
}
|
1403
1404
|
|
@@ -86,6 +86,11 @@ const UIStrings = {
|
|
86
86
|
*@description Text in Call Stack Sidebar Pane of the Sources panel when some call frames have warnings
|
87
87
|
*/
|
88
88
|
callFrameWarnings: 'Some call frames have warnings',
|
89
|
+
/**
|
90
|
+
*@description Error message that is displayed in UI when a file needed for debugging information for a call frame is missing
|
91
|
+
*@example {src/myapp.debug.wasm.dwp} PH1
|
92
|
+
*/
|
93
|
+
debugFileNotFound: 'Failed to load debug file "{PH1}".',
|
89
94
|
/**
|
90
95
|
* @description A contex menu item in the Call Stack Sidebar Pane. "Restart" is a verb and
|
91
96
|
* "frame" is a noun. "Frame" refers to an individual item in the call stack, i.e. a call frame.
|
@@ -204,8 +209,8 @@ export class CallStackSidebarPane extends UI.View.SimpleView implements UI.Conte
|
|
204
209
|
return item;
|
205
210
|
});
|
206
211
|
itemPromises.push(itemPromise);
|
207
|
-
|
208
|
-
uniqueWarnings.add(
|
212
|
+
if (frame.missingDebugInfoDetails) {
|
213
|
+
uniqueWarnings.add(frame.missingDebugInfoDetails.details);
|
209
214
|
}
|
210
215
|
}
|
211
216
|
const items = await Promise.all(itemPromises);
|
@@ -316,9 +321,11 @@ export class CallStackSidebarPane extends UI.View.SimpleView implements UI.Conte
|
|
316
321
|
element.appendChild(UI.Icon.Icon.create('smallicon-thick-right-arrow', 'selected-call-frame-icon'));
|
317
322
|
element.tabIndex = item === this.list.selectedItem() ? 0 : -1;
|
318
323
|
|
319
|
-
if (callframe && callframe.
|
324
|
+
if (callframe && callframe.missingDebugInfoDetails) {
|
320
325
|
const icon = UI.Icon.Icon.create('smallicon-warning', 'call-frame-warning-icon');
|
321
|
-
|
326
|
+
const messages =
|
327
|
+
callframe.missingDebugInfoDetails.resources.map(r => i18nString(UIStrings.debugFileNotFound, {PH1: r}));
|
328
|
+
UI.Tooltip.Tooltip.install(icon, [callframe.missingDebugInfoDetails.details, ...messages].join('\n'));
|
322
329
|
element.appendChild(icon);
|
323
330
|
}
|
324
331
|
return element;
|
@@ -141,6 +141,16 @@ const UIStrings = {
|
|
141
141
|
*@description Text in Debugger Plugin of the Sources panel
|
142
142
|
*/
|
143
143
|
theDebuggerWillSkipStepping: 'The debugger will skip stepping through this script, and will not stop on exceptions.',
|
144
|
+
/**
|
145
|
+
*@description Error message that is displayed in UI when a file needed for debugging information for a call frame is missing
|
146
|
+
*@example {src/myapp.debug.wasm.dwp} PH1
|
147
|
+
*/
|
148
|
+
debugFileNotFound: 'Failed to load debug file "{PH1}".',
|
149
|
+
/**
|
150
|
+
*@description Error message that is displayed when no debug info could be loaded
|
151
|
+
*@example {app.wasm} PH1
|
152
|
+
*/
|
153
|
+
debugInfoNotFound: 'Failed to load any debug info for {PH1}.',
|
144
154
|
};
|
145
155
|
const str_ = i18n.i18n.registerUIStrings('panels/sources/DebuggerPlugin.ts', UIStrings);
|
146
156
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
@@ -194,6 +204,7 @@ export class DebuggerPlugin extends Plugin {
|
|
194
204
|
private prettyPrintInfobar!: UI.Infobar.Infobar|null;
|
195
205
|
private refreshBreakpointsTimeout: undefined|number = undefined;
|
196
206
|
private activeBreakpointDialog: BreakpointEditDialog|null = null;
|
207
|
+
private missingDebugInfoBar: UI.Infobar.Infobar|null = null;
|
197
208
|
|
198
209
|
constructor(
|
199
210
|
uiSourceCode: Workspace.UISourceCode.UISourceCode,
|
@@ -237,7 +248,6 @@ export class DebuggerPlugin extends Plugin {
|
|
237
248
|
|
238
249
|
this.ignoreListInfobar = null;
|
239
250
|
this.showIgnoreListInfobarIfNeeded();
|
240
|
-
|
241
251
|
for (const scriptFile of this.scriptFileForDebuggerModel.values()) {
|
242
252
|
scriptFile.checkMapping();
|
243
253
|
}
|
@@ -332,6 +342,9 @@ export class DebuggerPlugin extends Plugin {
|
|
332
342
|
editor.dispatch({effects: SourceFrame.SourceFrame.addNonBreakableLines.of(linePositions)});
|
333
343
|
}
|
334
344
|
}, console.error);
|
345
|
+
if (this.missingDebugInfoBar) {
|
346
|
+
this.attachInfobar(this.missingDebugInfoBar);
|
347
|
+
}
|
335
348
|
if (!this.muted) {
|
336
349
|
void this.refreshBreakpoints();
|
337
350
|
}
|
@@ -1350,6 +1363,42 @@ export class DebuggerPlugin extends Plugin {
|
|
1350
1363
|
if (newScriptFile.hasSourceMapURL()) {
|
1351
1364
|
this.showSourceMapInfobar();
|
1352
1365
|
}
|
1366
|
+
|
1367
|
+
void newScriptFile.missingSymbolFiles().then(resources => {
|
1368
|
+
if (resources) {
|
1369
|
+
const details = i18nString(UIStrings.debugInfoNotFound, {PH1: newScriptFile.uiSourceCode.url()});
|
1370
|
+
this.updateMissingDebugInfoInfobar({resources, details});
|
1371
|
+
} else {
|
1372
|
+
this.updateMissingDebugInfoInfobar(null);
|
1373
|
+
}
|
1374
|
+
});
|
1375
|
+
}
|
1376
|
+
|
1377
|
+
private updateMissingDebugInfoInfobar(warning: SDK.DebuggerModel.MissingDebugInfoDetails|null): void {
|
1378
|
+
if (this.missingDebugInfoBar) {
|
1379
|
+
return;
|
1380
|
+
}
|
1381
|
+
if (warning === null) {
|
1382
|
+
this.removeInfobar(this.missingDebugInfoBar);
|
1383
|
+
this.missingDebugInfoBar = null;
|
1384
|
+
return;
|
1385
|
+
}
|
1386
|
+
this.missingDebugInfoBar = UI.Infobar.Infobar.create(UI.Infobar.Type.Error, warning.details, []);
|
1387
|
+
if (!this.missingDebugInfoBar) {
|
1388
|
+
return;
|
1389
|
+
}
|
1390
|
+
for (const resource of warning.resources) {
|
1391
|
+
const detailsRow =
|
1392
|
+
this.missingDebugInfoBar?.createDetailsRowMessage(i18nString(UIStrings.debugFileNotFound, {PH1: resource}));
|
1393
|
+
if (detailsRow) {
|
1394
|
+
detailsRow.classList.add('infobar-selectable');
|
1395
|
+
}
|
1396
|
+
}
|
1397
|
+
this.missingDebugInfoBar.setCloseCallback(() => {
|
1398
|
+
this.removeInfobar(this.missingDebugInfoBar);
|
1399
|
+
this.missingDebugInfoBar = null;
|
1400
|
+
});
|
1401
|
+
this.attachInfobar(this.missingDebugInfoBar);
|
1353
1402
|
}
|
1354
1403
|
|
1355
1404
|
private showSourceMapInfobar(): void {
|
@@ -1481,6 +1530,7 @@ export class DebuggerPlugin extends Plugin {
|
|
1481
1530
|
const uiLocation = await liveLocation.uiLocation();
|
1482
1531
|
if (uiLocation && uiLocation.uiSourceCode.url() === this.uiSourceCode.url()) {
|
1483
1532
|
this.setExecutionLocation(uiLocation);
|
1533
|
+
this.updateMissingDebugInfoInfobar(callFrame.missingDebugInfoDetails);
|
1484
1534
|
} else {
|
1485
1535
|
this.setExecutionLocation(null);
|
1486
1536
|
}
|
@@ -24,6 +24,14 @@
|
|
24
24
|
background-color: var(--override-infobar-warning-background);
|
25
25
|
}
|
26
26
|
|
27
|
+
.infobar-error {
|
28
|
+
--override-infobar-error-background: var(--color-error-background);
|
29
|
+
--override-infobar-error-text: var(--color-error-text);
|
30
|
+
|
31
|
+
background-color: var(--override-infobar-error-background);
|
32
|
+
color: var(--override-infobar-error-text);
|
33
|
+
}
|
34
|
+
|
27
35
|
.-theme-with-dark-background .infobar-warning,
|
28
36
|
:host-context(.-theme-with-dark-background) .infobar-warning {
|
29
37
|
--override-infobar-warning-background: rgb(63 52 2);
|
@@ -75,6 +83,10 @@
|
|
75
83
|
margin: 4px;
|
76
84
|
}
|
77
85
|
|
86
|
+
.infobar-selectable {
|
87
|
+
user-select: text;
|
88
|
+
}
|
89
|
+
|
78
90
|
.infobar-button {
|
79
91
|
color: var(--color-text-secondary);
|
80
92
|
cursor: pointer;
|
@@ -93,6 +105,11 @@
|
|
93
105
|
background-color: var(--override-warning-icon-color);
|
94
106
|
}
|
95
107
|
|
108
|
+
.error-icon {
|
109
|
+
background-image: var(--image-file-error_icon);
|
110
|
+
background-size: contain;
|
111
|
+
}
|
112
|
+
|
96
113
|
.-theme-with-dark-background .warning-icon,
|
97
114
|
:host-context(.-theme-with-dark-background) .warning-icon {
|
98
115
|
--override-warning-icon-color: rgb(245 182 10);
|
package/package.json
CHANGED