chrome-devtools-frontend 1.0.1021582 → 1.0.1022059
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/.eslintignore +14 -1
- package/extension-api/ExtensionAPI.d.ts +54 -4
- package/front_end/.eslintrc.js +3 -1
- package/front_end/core/host/InspectorFrontendHostAPI.ts +1 -0
- package/front_end/core/host/UserMetrics.ts +18 -0
- package/front_end/core/i18n/locales/en-US.json +27 -0
- package/front_end/core/i18n/locales/en-XL.json +27 -0
- package/front_end/devtools_compatibility.js +1 -0
- package/front_end/legacy_test_runner/sources_test_runner/DebuggerTestRunner.js +4 -3
- package/front_end/models/bindings/DebuggerLanguagePlugins.ts +157 -117
- package/front_end/models/extensions/ExtensionAPI.ts +101 -13
- package/front_end/models/extensions/ExtensionServer.ts +63 -1
- package/front_end/models/extensions/LanguageExtensionEndpoint.ts +16 -3
- package/front_end/models/timeline_model/TimelineModel.ts +164 -7
- package/front_end/panels/application/AppManifestView.ts +13 -2
- package/front_end/panels/application/ApplicationPanelSidebar.ts +67 -5
- package/front_end/panels/elements/ElementsTreeOutline.ts +41 -7
- package/front_end/panels/elements/TopLayerContainer.ts +9 -1
- package/front_end/panels/elements/components/AdornerManager.ts +7 -0
- package/front_end/panels/elements/elementsTreeOutline.css +4 -0
- package/front_end/third_party/acorn/acorn.ts +1 -1
- package/front_end/third_party/chromium/client-variations/client-variations.ts +1 -1
- package/front_end/third_party/diff/DiffWrapper.ts +2 -0
- package/front_end/third_party/i18n/i18n-impl.ts +5 -1
- package/front_end/third_party/i18n/i18n.ts +1 -1
- package/front_end/third_party/i18n/locales.ts +1 -1
- package/front_end/third_party/marked/marked.ts +1 -1
- package/front_end/third_party/puppeteer/puppeteer.ts +6 -6
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspectorController.ts +23 -1
- package/front_end/ui/legacy/ReportView.ts +8 -0
- package/package.json +1 -1
- package/scripts/eslint_rules/lib/custom_element_definitions_location.js +28 -13
- package/scripts/eslint_rules/lib/es_modules_import.js +5 -1
- package/scripts/eslint_rules/tests/custom_element_definitions_location_test.js +9 -2
- package/scripts/eslint_rules/tests/es_modules_import_test.js +5 -0
@@ -14,6 +14,7 @@ import {ContentProviderBasedProject} from './ContentProviderBasedProject.js';
|
|
14
14
|
|
15
15
|
import type {DebuggerWorkspaceBinding} from './DebuggerWorkspaceBinding.js';
|
16
16
|
import {NetworkProject} from './NetworkProject.js';
|
17
|
+
import {assertNotNullOrUndefined} from '../../core/platform/platform.js';
|
17
18
|
|
18
19
|
const UIStrings = {
|
19
20
|
/**
|
@@ -218,7 +219,7 @@ async function getValueTreeForExpression(
|
|
218
219
|
try {
|
219
220
|
typeInfo = await plugin.getTypeInfo(expression, location);
|
220
221
|
} catch (e) {
|
221
|
-
FormattingError.
|
222
|
+
throw FormattingError.makeLocal(callFrame, e.message);
|
222
223
|
}
|
223
224
|
// If there's no type information we cannot represent this expression.
|
224
225
|
if (!typeInfo) {
|
@@ -454,7 +455,7 @@ class FormattingError extends Error {
|
|
454
455
|
this.exceptionDetails = exceptionDetails;
|
455
456
|
}
|
456
457
|
|
457
|
-
static
|
458
|
+
static makeLocal(callFrame: SDK.DebuggerModel.CallFrame, message: string): FormattingError {
|
458
459
|
const exception: Protocol.Runtime.RemoteObject = {
|
459
460
|
type: Protocol.Runtime.RemoteObjectType.Object,
|
460
461
|
subtype: Protocol.Runtime.RemoteObjectSubtype.Error,
|
@@ -463,7 +464,7 @@ class FormattingError extends Error {
|
|
463
464
|
const exceptionDetails: Protocol.Runtime
|
464
465
|
.ExceptionDetails = {text: 'Uncaught', exceptionId: -1, columnNumber: 0, lineNumber: 0, exception};
|
465
466
|
const errorObject = callFrame.debuggerModel.runtimeModel().createRemoteObject(exception);
|
466
|
-
|
467
|
+
return new FormattingError(errorObject, exceptionDetails);
|
467
468
|
}
|
468
469
|
}
|
469
470
|
|
@@ -623,12 +624,14 @@ class SourceScopeRemoteObject extends SDK.RemoteObject.RemoteObjectImpl {
|
|
623
624
|
variables: Chrome.DevTools.Variable[];
|
624
625
|
#callFrame: SDK.DebuggerModel.CallFrame;
|
625
626
|
#plugin: DebuggerLanguagePlugin;
|
627
|
+
stopId: StopId;
|
626
628
|
|
627
|
-
constructor(callFrame: SDK.DebuggerModel.CallFrame, plugin: DebuggerLanguagePlugin) {
|
629
|
+
constructor(callFrame: SDK.DebuggerModel.CallFrame, stopId: StopId, plugin: DebuggerLanguagePlugin) {
|
628
630
|
super(callFrame.debuggerModel.runtimeModel(), undefined, 'object', undefined, null);
|
629
631
|
this.variables = [];
|
630
632
|
this.#callFrame = callFrame;
|
631
633
|
this.#plugin = plugin;
|
634
|
+
this.stopId = stopId;
|
632
635
|
}
|
633
636
|
|
634
637
|
async doGetProperties(ownProperties: boolean, accessorPropertiesOnly: boolean, _generatePreview: boolean):
|
@@ -699,13 +702,13 @@ export class SourceScope implements SDK.DebuggerModel.ScopeChainEntry {
|
|
699
702
|
readonly #startLocationInternal: SDK.DebuggerModel.Location|null;
|
700
703
|
readonly #endLocationInternal: SDK.DebuggerModel.Location|null;
|
701
704
|
constructor(
|
702
|
-
callFrame: SDK.DebuggerModel.CallFrame, type: string, typeName: string, icon: string|undefined,
|
705
|
+
callFrame: SDK.DebuggerModel.CallFrame, stopId: StopId, type: string, typeName: string, icon: string|undefined,
|
703
706
|
plugin: DebuggerLanguagePlugin) {
|
704
707
|
this.#callFrameInternal = callFrame;
|
705
708
|
this.#typeInternal = type;
|
706
709
|
this.#typeNameInternal = typeName;
|
707
710
|
this.#iconInternal = icon;
|
708
|
-
this.#objectInternal = new SourceScopeRemoteObject(callFrame, plugin);
|
711
|
+
this.#objectInternal = new SourceScopeRemoteObject(callFrame, stopId, plugin);
|
709
712
|
this.#startLocationInternal = null;
|
710
713
|
this.#endLocationInternal = null;
|
711
714
|
}
|
@@ -764,6 +767,115 @@ export class SourceScope implements SDK.DebuggerModel.ScopeChainEntry {
|
|
764
767
|
}
|
765
768
|
}
|
766
769
|
|
770
|
+
export class ExtensionRemoteObject extends SDK.RemoteObject.RemoteObject {
|
771
|
+
private readonly extensionObject: Chrome.DevTools.RemoteObject;
|
772
|
+
private readonly plugin: DebuggerLanguagePlugin;
|
773
|
+
readonly callFrame: SDK.DebuggerModel.CallFrame;
|
774
|
+
constructor(
|
775
|
+
callFrame: SDK.DebuggerModel.CallFrame, extensionObject: Chrome.DevTools.RemoteObject,
|
776
|
+
plugin: DebuggerLanguagePlugin) {
|
777
|
+
super();
|
778
|
+
this.extensionObject = extensionObject;
|
779
|
+
this.plugin = plugin;
|
780
|
+
this.callFrame = callFrame;
|
781
|
+
}
|
782
|
+
|
783
|
+
get linearMemoryAddress(): number|undefined {
|
784
|
+
return this.extensionObject.linearMemoryAddress;
|
785
|
+
}
|
786
|
+
|
787
|
+
get objectId(): Protocol.Runtime.RemoteObjectId|undefined {
|
788
|
+
return this.extensionObject.objectId as Protocol.Runtime.RemoteObjectId;
|
789
|
+
}
|
790
|
+
|
791
|
+
get type(): string {
|
792
|
+
if (this.extensionObject.type === 'array' || this.extensionObject.type === 'null') {
|
793
|
+
return 'object';
|
794
|
+
}
|
795
|
+
return this.extensionObject.type;
|
796
|
+
}
|
797
|
+
|
798
|
+
get subtype(): string|undefined {
|
799
|
+
if (this.extensionObject.type === 'array' || this.extensionObject.type === 'null') {
|
800
|
+
return this.extensionObject.type;
|
801
|
+
}
|
802
|
+
return undefined;
|
803
|
+
}
|
804
|
+
|
805
|
+
get value(): unknown {
|
806
|
+
return this.extensionObject.value;
|
807
|
+
}
|
808
|
+
|
809
|
+
unserializableValue(): string|undefined {
|
810
|
+
return undefined;
|
811
|
+
}
|
812
|
+
|
813
|
+
get description(): string|undefined {
|
814
|
+
return this.extensionObject.description;
|
815
|
+
}
|
816
|
+
|
817
|
+
set description(description: string|undefined) {
|
818
|
+
}
|
819
|
+
|
820
|
+
get hasChildren(): boolean {
|
821
|
+
return this.extensionObject.hasChildren;
|
822
|
+
}
|
823
|
+
|
824
|
+
get preview(): Protocol.Runtime.ObjectPreview|undefined {
|
825
|
+
return undefined;
|
826
|
+
}
|
827
|
+
|
828
|
+
get className(): string|null {
|
829
|
+
return this.extensionObject.className ?? null;
|
830
|
+
}
|
831
|
+
|
832
|
+
arrayLength(): number {
|
833
|
+
return 0;
|
834
|
+
}
|
835
|
+
|
836
|
+
arrayBufferByteLength(): number {
|
837
|
+
return 0;
|
838
|
+
}
|
839
|
+
|
840
|
+
getOwnProperties(_generatePreview: boolean, _nonIndexedPropertiesOnly?: boolean):
|
841
|
+
Promise<SDK.RemoteObject.GetPropertiesResult> {
|
842
|
+
return this.getAllProperties(false, _generatePreview, _nonIndexedPropertiesOnly);
|
843
|
+
}
|
844
|
+
|
845
|
+
async getAllProperties(
|
846
|
+
_accessorPropertiesOnly: boolean, _generatePreview: boolean,
|
847
|
+
_nonIndexedPropertiesOnly?: boolean): Promise<SDK.RemoteObject.GetPropertiesResult> {
|
848
|
+
const {objectId} = this.extensionObject;
|
849
|
+
if (objectId) {
|
850
|
+
assertNotNullOrUndefined(this.plugin.getProperties);
|
851
|
+
const extensionObjectProperties = await this.plugin.getProperties(objectId);
|
852
|
+
const properties = extensionObjectProperties.map(
|
853
|
+
p => new SDK.RemoteObject.RemoteObjectProperty(
|
854
|
+
p.name, new ExtensionRemoteObject(this.callFrame, p.value, this.plugin)));
|
855
|
+
return {properties, internalProperties: null};
|
856
|
+
}
|
857
|
+
|
858
|
+
return {properties: null, internalProperties: null};
|
859
|
+
}
|
860
|
+
|
861
|
+
release(): void {
|
862
|
+
const {objectId} = this.extensionObject;
|
863
|
+
if (objectId) {
|
864
|
+
assertNotNullOrUndefined(this.plugin.releaseObject);
|
865
|
+
void this.plugin.releaseObject(objectId);
|
866
|
+
}
|
867
|
+
}
|
868
|
+
|
869
|
+
debuggerModel(): SDK.DebuggerModel.DebuggerModel {
|
870
|
+
return this.callFrame.debuggerModel;
|
871
|
+
}
|
872
|
+
|
873
|
+
runtimeModel(): SDK.RuntimeModel.RuntimeModel {
|
874
|
+
return this.callFrame.debuggerModel.runtimeModel();
|
875
|
+
}
|
876
|
+
}
|
877
|
+
|
878
|
+
export type StopId = bigint;
|
767
879
|
export class DebuggerLanguagePluginManager implements
|
768
880
|
SDK.TargetManager.SDKModelObserver<SDK.DebuggerModel.DebuggerModel> {
|
769
881
|
readonly #workspace: Workspace.Workspace.WorkspaceImpl;
|
@@ -776,6 +888,9 @@ export class DebuggerLanguagePluginManager implements
|
|
776
888
|
scripts: Array<SDK.Script.Script>,
|
777
889
|
addRawModulePromise: Promise<Array<Platform.DevToolsPath.UrlString>|{missingSymbolFiles: string[]}>,
|
778
890
|
}>;
|
891
|
+
private readonly callFrameByStopId: Map<StopId, SDK.DebuggerModel.CallFrame> = new Map();
|
892
|
+
private readonly stopIdByCallFrame: Map<SDK.DebuggerModel.CallFrame, StopId> = new Map();
|
893
|
+
private nextStopId: StopId = 0n;
|
779
894
|
|
780
895
|
constructor(
|
781
896
|
targetManager: SDK.TargetManager.TargetManager, workspace: Workspace.Workspace.WorkspaceImpl,
|
@@ -818,10 +933,27 @@ export class DebuggerLanguagePluginManager implements
|
|
818
933
|
const {exception: object, exceptionDetails} = error;
|
819
934
|
return {object, exceptionDetails};
|
820
935
|
}
|
821
|
-
|
936
|
+
const {exception: object, exceptionDetails} = FormattingError.makeLocal(callFrame, error.message);
|
937
|
+
return {object, exceptionDetails};
|
822
938
|
}
|
823
939
|
}
|
824
940
|
|
941
|
+
stopIdForCallFrame(callFrame: SDK.DebuggerModel.CallFrame): StopId {
|
942
|
+
let stopId = this.stopIdByCallFrame.get(callFrame);
|
943
|
+
if (stopId !== undefined) {
|
944
|
+
return stopId;
|
945
|
+
}
|
946
|
+
|
947
|
+
stopId = this.nextStopId++;
|
948
|
+
this.stopIdByCallFrame.set(callFrame, stopId);
|
949
|
+
this.callFrameByStopId.set(stopId, callFrame);
|
950
|
+
return stopId;
|
951
|
+
}
|
952
|
+
|
953
|
+
callFrameForStopId(stopId: StopId): SDK.DebuggerModel.CallFrame|undefined {
|
954
|
+
return this.callFrameByStopId.get(stopId);
|
955
|
+
}
|
956
|
+
|
825
957
|
private expandCallFrames(callFrames: SDK.DebuggerModel.CallFrame[]): Promise<SDK.DebuggerModel.CallFrame[]> {
|
826
958
|
return Promise
|
827
959
|
.all(callFrames.map(async callFrame => {
|
@@ -850,6 +982,7 @@ export class DebuggerLanguagePluginManager implements
|
|
850
982
|
this.#debuggerModelToData.set(debuggerModel, new ModelData(debuggerModel, this.#workspace));
|
851
983
|
debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this.globalObjectCleared, this);
|
852
984
|
debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this.parsedScriptSource, this);
|
985
|
+
debuggerModel.addEventListener(SDK.DebuggerModel.Events.DebuggerResumed, this.debuggerResumed, this);
|
853
986
|
debuggerModel.setEvaluateOnCallFrameCallback(this.evaluateOnCallFrame.bind(this));
|
854
987
|
debuggerModel.setExpandCallFramesCallback(this.expandCallFrames.bind(this));
|
855
988
|
}
|
@@ -857,6 +990,7 @@ export class DebuggerLanguagePluginManager implements
|
|
857
990
|
modelRemoved(debuggerModel: SDK.DebuggerModel.DebuggerModel): void {
|
858
991
|
debuggerModel.removeEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this.globalObjectCleared, this);
|
859
992
|
debuggerModel.removeEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this.parsedScriptSource, this);
|
993
|
+
debuggerModel.removeEventListener(SDK.DebuggerModel.Events.DebuggerResumed, this.debuggerResumed, this);
|
860
994
|
debuggerModel.setEvaluateOnCallFrameCallback(null);
|
861
995
|
debuggerModel.setExpandCallFramesCallback(null);
|
862
996
|
const modelData = this.#debuggerModelToData.get(debuggerModel);
|
@@ -1144,6 +1278,17 @@ export class DebuggerLanguagePluginManager implements
|
|
1144
1278
|
}
|
1145
1279
|
}
|
1146
1280
|
|
1281
|
+
private debuggerResumed(event: Common.EventTarget.EventTargetEvent<SDK.DebuggerModel.DebuggerModel>): void {
|
1282
|
+
const resumedFrames =
|
1283
|
+
Array.from(this.callFrameByStopId.values()).filter(callFrame => callFrame.debuggerModel === event.data);
|
1284
|
+
for (const callFrame of resumedFrames) {
|
1285
|
+
const stopId = this.stopIdByCallFrame.get(callFrame);
|
1286
|
+
assertNotNullOrUndefined(stopId);
|
1287
|
+
this.stopIdByCallFrame.delete(callFrame);
|
1288
|
+
this.callFrameByStopId.delete(stopId);
|
1289
|
+
}
|
1290
|
+
}
|
1291
|
+
|
1147
1292
|
getSourcesForScript(script: SDK.Script.Script):
|
1148
1293
|
Promise<Array<Platform.DevToolsPath.UrlString>|{missingSymbolFiles: string[]}|undefined> {
|
1149
1294
|
const rawModuleId = rawModuleIdForScript(script);
|
@@ -1167,6 +1312,8 @@ export class DebuggerLanguagePluginManager implements
|
|
1167
1312
|
inlineFrameIndex: callFrame.inlineFrameIndex,
|
1168
1313
|
};
|
1169
1314
|
|
1315
|
+
const stopId = this.stopIdForCallFrame(callFrame);
|
1316
|
+
|
1170
1317
|
try {
|
1171
1318
|
const sourceMapping = await plugin.rawLocationToSourceLocation(location);
|
1172
1319
|
if (sourceMapping.length === 0) {
|
@@ -1178,7 +1325,7 @@ export class DebuggerLanguagePluginManager implements
|
|
1178
1325
|
let scope = scopes.get(variable.scope);
|
1179
1326
|
if (!scope) {
|
1180
1327
|
const {type, typeName, icon} = await plugin.getScopeInfo(variable.scope);
|
1181
|
-
scope = new SourceScope(callFrame, type, typeName, icon, plugin);
|
1328
|
+
scope = new SourceScope(callFrame, stopId, type, typeName, icon, plugin);
|
1182
1329
|
scopes.set(variable.scope, scope);
|
1183
1330
|
}
|
1184
1331
|
scope.object().variables.push(variable);
|
@@ -1379,114 +1526,7 @@ class ModelData {
|
|
1379
1526
|
}
|
1380
1527
|
}
|
1381
1528
|
|
1382
|
-
export
|
1529
|
+
export interface DebuggerLanguagePlugin extends Chrome.DevTools.LanguageExtensionPlugin {
|
1383
1530
|
name: string;
|
1384
|
-
|
1385
|
-
this.name = name;
|
1386
|
-
}
|
1387
|
-
|
1388
|
-
handleScript(_script: SDK.Script.Script): boolean {
|
1389
|
-
throw new Error('Not implemented yet');
|
1390
|
-
}
|
1391
|
-
|
1392
|
-
dispose(): void {
|
1393
|
-
}
|
1394
|
-
|
1395
|
-
/** Notify the #plugin about a new script
|
1396
|
-
*/
|
1397
|
-
async addRawModule(_rawModuleId: string, _symbolsURL: string, _rawModule: Chrome.DevTools.RawModule):
|
1398
|
-
Promise<string[]|{missingSymbolFiles: string[]}> {
|
1399
|
-
throw new Error('Not implemented yet');
|
1400
|
-
}
|
1401
|
-
|
1402
|
-
/** Find #locations in raw modules from a #location in a source file
|
1403
|
-
*/
|
1404
|
-
async sourceLocationToRawLocation(_sourceLocation: Chrome.DevTools.SourceLocation):
|
1405
|
-
Promise<Chrome.DevTools.RawLocationRange[]> {
|
1406
|
-
throw new Error('Not implemented yet');
|
1407
|
-
}
|
1408
|
-
|
1409
|
-
/** Find #locations in source files from a #location in a raw module
|
1410
|
-
*/
|
1411
|
-
async rawLocationToSourceLocation(_rawLocation: Chrome.DevTools.RawLocation):
|
1412
|
-
Promise<Chrome.DevTools.SourceLocation[]> {
|
1413
|
-
throw new Error('Not implemented yet');
|
1414
|
-
}
|
1415
|
-
|
1416
|
-
/** Return detailed information about a scope
|
1417
|
-
*/
|
1418
|
-
async getScopeInfo(_type: string): Promise<Chrome.DevTools.ScopeInfo> {
|
1419
|
-
throw new Error('Not implemented yet');
|
1420
|
-
}
|
1421
|
-
|
1422
|
-
/** List all variables in lexical scope at a given #location in a raw module
|
1423
|
-
*/
|
1424
|
-
async listVariablesInScope(_rawLocation: Chrome.DevTools.RawLocation): Promise<Chrome.DevTools.Variable[]> {
|
1425
|
-
throw new Error('Not implemented yet');
|
1426
|
-
}
|
1427
|
-
|
1428
|
-
/**
|
1429
|
-
* Notifies the #plugin that a script is removed.
|
1430
|
-
*/
|
1431
|
-
removeRawModule(_rawModuleId: string): Promise<void> {
|
1432
|
-
throw new Error('Not implemented yet');
|
1433
|
-
}
|
1434
|
-
|
1435
|
-
getTypeInfo(_expression: string, _context: Chrome.DevTools.RawLocation): Promise<{
|
1436
|
-
typeInfos: Array<Chrome.DevTools.TypeInfo>,
|
1437
|
-
base: Chrome.DevTools.EvalBase,
|
1438
|
-
}|null> {
|
1439
|
-
throw new Error('Not implemented yet');
|
1440
|
-
}
|
1441
|
-
|
1442
|
-
getFormatter(
|
1443
|
-
_expressionOrField: string|{
|
1444
|
-
base: Chrome.DevTools.EvalBase,
|
1445
|
-
field: Array<Chrome.DevTools.FieldInfo>,
|
1446
|
-
},
|
1447
|
-
_context: Chrome.DevTools.RawLocation): Promise<{
|
1448
|
-
js: string,
|
1449
|
-
}|null> {
|
1450
|
-
throw new Error('Not implemented yet');
|
1451
|
-
}
|
1452
|
-
|
1453
|
-
getInspectableAddress(_field: {
|
1454
|
-
base: Chrome.DevTools.EvalBase,
|
1455
|
-
field: Array<Chrome.DevTools.FieldInfo>,
|
1456
|
-
}): Promise<{
|
1457
|
-
js: string,
|
1458
|
-
}> {
|
1459
|
-
throw new Error('Not implemented yet');
|
1460
|
-
}
|
1461
|
-
|
1462
|
-
/**
|
1463
|
-
* Find #locations in source files from a #location in a raw module
|
1464
|
-
*/
|
1465
|
-
async getFunctionInfo(_rawLocation: Chrome.DevTools.RawLocation):
|
1466
|
-
Promise<{frames: Array<Chrome.DevTools.FunctionInfo>}|{missingSymbolFiles: string[]}> {
|
1467
|
-
throw new Error('Not implemented yet');
|
1468
|
-
}
|
1469
|
-
|
1470
|
-
/**
|
1471
|
-
* Find #locations in raw modules corresponding to the inline function
|
1472
|
-
* that rawLocation is in. Used for stepping out of an inline function.
|
1473
|
-
*/
|
1474
|
-
async getInlinedFunctionRanges(_rawLocation: Chrome.DevTools.RawLocation):
|
1475
|
-
Promise<Chrome.DevTools.RawLocationRange[]> {
|
1476
|
-
throw new Error('Not implemented yet');
|
1477
|
-
}
|
1478
|
-
|
1479
|
-
/**
|
1480
|
-
* Find #locations in raw modules corresponding to inline functions
|
1481
|
-
* called by the function or inline frame that rawLocation is in.
|
1482
|
-
* Used for stepping over inline functions.
|
1483
|
-
*/
|
1484
|
-
async getInlinedCalleesRanges(_rawLocation: Chrome.DevTools.RawLocation):
|
1485
|
-
Promise<Chrome.DevTools.RawLocationRange[]> {
|
1486
|
-
throw new Error('Not implemented yet');
|
1487
|
-
}
|
1488
|
-
|
1489
|
-
async getMappedLines(_rawModuleId: string, _sourceFileURL: string): Promise<number[]|undefined> {
|
1490
|
-
throw new Error('Not implemented yet');
|
1491
|
-
}
|
1531
|
+
handleScript(script: SDK.Script.Script): boolean;
|
1492
1532
|
}
|
@@ -86,6 +86,10 @@ export namespace PrivateAPI {
|
|
86
86
|
Unsubscribe = 'unsubscribe',
|
87
87
|
UpdateButton = 'updateButton',
|
88
88
|
RegisterLanguageExtensionPlugin = 'registerLanguageExtensionPlugin',
|
89
|
+
GetWasmLinearMemory = 'getWasmLinearMemory',
|
90
|
+
GetWasmLocal = 'getWasmLocal',
|
91
|
+
GetWasmGlobal = 'getWasmGlobal',
|
92
|
+
GetWasmOp = 'getWasmOp',
|
89
93
|
RegisterRecorderExtensionPlugin = 'registerRecorderExtensionPlugin',
|
90
94
|
}
|
91
95
|
|
@@ -103,6 +107,9 @@ export namespace PrivateAPI {
|
|
103
107
|
GetInlinedFunctionRanges = 'getInlinedFunctionRanges',
|
104
108
|
GetInlinedCalleesRanges = 'getInlinedCalleesRanges',
|
105
109
|
GetMappedLines = 'getMappedLines',
|
110
|
+
FormatValue = 'formatValue',
|
111
|
+
GetProperties = 'getProperties',
|
112
|
+
ReleaseObject = 'releaseObject',
|
106
113
|
}
|
107
114
|
|
108
115
|
export const enum LanguageExtensionPluginEvents {
|
@@ -197,6 +204,23 @@ export namespace PrivateAPI {
|
|
197
204
|
};
|
198
205
|
type GetHARRequest = {command: Commands.GetHAR};
|
199
206
|
type GetPageResourcesRequest = {command: Commands.GetPageResources};
|
207
|
+
type GetWasmLinearMemoryRequest = {
|
208
|
+
command: Commands.GetWasmLinearMemory,
|
209
|
+
offset: number,
|
210
|
+
length: number,
|
211
|
+
stopId: unknown,
|
212
|
+
};
|
213
|
+
type GetWasmLocalRequest = {
|
214
|
+
command: Commands.GetWasmLocal,
|
215
|
+
local: number,
|
216
|
+
stopId: unknown,
|
217
|
+
};
|
218
|
+
type GetWasmGlobalRequest = {
|
219
|
+
command: Commands.GetWasmGlobal,
|
220
|
+
global: number,
|
221
|
+
stopId: unknown,
|
222
|
+
};
|
223
|
+
type GetWasmOpRequest = {command: Commands.GetWasmOp, op: number, stopId: unknown};
|
200
224
|
|
201
225
|
export type ServerRequests = RegisterRecorderExtensionPluginRequest|RegisterLanguageExtensionPluginRequest|
|
202
226
|
SubscribeRequest|UnsubscribeRequest|AddRequestHeadersRequest|ApplyStyleSheetRequest|CreatePanelRequest|
|
@@ -204,7 +228,8 @@ export namespace PrivateAPI {
|
|
204
228
|
CreateSidebarPaneRequest|SetSidebarHeightRequest|SetSidebarContentRequest|SetSidebarPageRequest|
|
205
229
|
OpenResourceRequest|SetOpenResourceHandlerRequest|SetThemeChangeHandlerRequest|ReloadRequest|
|
206
230
|
EvaluateOnInspectedPageRequest|GetRequestContentRequest|GetResourceContentRequest|SetResourceContentRequest|
|
207
|
-
AddTraceProviderRequest|ForwardKeyboardEventRequest|GetHARRequest|GetPageResourcesRequest
|
231
|
+
AddTraceProviderRequest|ForwardKeyboardEventRequest|GetHARRequest|GetPageResourcesRequest|
|
232
|
+
GetWasmLinearMemoryRequest|GetWasmLocalRequest|GetWasmGlobalRequest|GetWasmOpRequest;
|
208
233
|
export type ExtensionServerRequestMessage = PrivateAPI.ServerRequests&{requestId?: number};
|
209
234
|
|
210
235
|
type AddRawModuleRequest = {
|
@@ -267,11 +292,24 @@ export namespace PrivateAPI {
|
|
267
292
|
method: LanguageExtensionPluginCommands.GetMappedLines,
|
268
293
|
parameters: {rawModuleId: string, sourceFileURL: string},
|
269
294
|
};
|
295
|
+
type FormatValueRequest = {
|
296
|
+
method: LanguageExtensionPluginCommands.FormatValue,
|
297
|
+
parameters: {expression: string, context: PublicAPI.Chrome.DevTools.RawLocation, stopId: number},
|
298
|
+
};
|
299
|
+
type GetPropertiesRequest = {
|
300
|
+
method: LanguageExtensionPluginCommands.GetProperties,
|
301
|
+
parameters: {objectId: PublicAPI.Chrome.DevTools.RemoteObjectId},
|
302
|
+
};
|
303
|
+
type ReleaseObjectRequest = {
|
304
|
+
method: LanguageExtensionPluginCommands.ReleaseObject,
|
305
|
+
parameters: {objectId: PublicAPI.Chrome.DevTools.RemoteObjectId},
|
306
|
+
};
|
270
307
|
|
271
|
-
export type LanguageExtensionRequests =
|
272
|
-
RawLocationToSourceLocationRequest|GetScopeInfoRequest|
|
273
|
-
GetTypeInfoRequest|GetFormatterRequest|
|
274
|
-
GetInlinedFunctionRangesRequest|
|
308
|
+
export type LanguageExtensionRequests =
|
309
|
+
AddRawModuleRequest|SourceLocationToRawLocationRequest|RawLocationToSourceLocationRequest|GetScopeInfoRequest|
|
310
|
+
ListVariablesInScopeRequest|RemoveRawModuleRequest|GetTypeInfoRequest|GetFormatterRequest|
|
311
|
+
GetInspectableAddressRequest|GetFunctionInfoRequest|GetInlinedFunctionRangesRequest|
|
312
|
+
GetInlinedCalleesRangesRequest|GetMappedLinesRequest|FormatValueRequest|GetPropertiesRequest|ReleaseObjectRequest;
|
275
313
|
|
276
314
|
type StringifyRequest = {
|
277
315
|
method: RecorderExtensionPluginCommands.Stringify,
|
@@ -331,8 +369,8 @@ namespace APIImpl {
|
|
331
369
|
registerHandler(command: string, handler: (request: {arguments: unknown[]}) => unknown): void;
|
332
370
|
unregisterHandler(command: string): void;
|
333
371
|
hasHandler(command: string): boolean;
|
334
|
-
sendRequest(
|
335
|
-
void;
|
372
|
+
sendRequest<ResponseT>(
|
373
|
+
request: PrivateAPI.ServerRequests, callback?: ((response: ResponseT) => unknown), transfers?: unknown[]): void;
|
336
374
|
nextObjectId(): string;
|
337
375
|
}
|
338
376
|
|
@@ -767,8 +805,7 @@ self.injectedExtensionAPI = function(
|
|
767
805
|
this._plugins = new Map();
|
768
806
|
}
|
769
807
|
|
770
|
-
(LanguageServicesAPIImpl.prototype as
|
771
|
-
Pick<APIImpl.LanguageExtensions, 'registerLanguageExtensionPlugin'|'unregisterLanguageExtensionPlugin'>) = {
|
808
|
+
(LanguageServicesAPIImpl.prototype as PublicAPI.Chrome.DevTools.LanguageExtensions) = {
|
772
809
|
registerLanguageExtensionPlugin: async function(
|
773
810
|
this: APIImpl.LanguageExtensions, plugin: PublicAPI.Chrome.DevTools.LanguageExtensionPlugin, pluginName: string,
|
774
811
|
supportedScriptTypes: PublicAPI.Chrome.DevTools.SupportedScriptTypes): Promise<void> {
|
@@ -822,8 +859,31 @@ self.injectedExtensionAPI = function(
|
|
822
859
|
return plugin.getMappedLines(request.parameters.rawModuleId, request.parameters.sourceFileURL);
|
823
860
|
}
|
824
861
|
return Promise.resolve(undefined);
|
862
|
+
case PrivateAPI.LanguageExtensionPluginCommands.FormatValue:
|
863
|
+
if ('evaluate' in plugin && plugin.evaluate) {
|
864
|
+
return plugin.evaluate(
|
865
|
+
request.parameters.expression, request.parameters.context, request.parameters.stopId);
|
866
|
+
}
|
867
|
+
return Promise.resolve(undefined);
|
868
|
+
case PrivateAPI.LanguageExtensionPluginCommands.GetProperties:
|
869
|
+
if ('getProperties' in plugin && plugin.getProperties) {
|
870
|
+
return plugin.getProperties(request.parameters.objectId);
|
871
|
+
}
|
872
|
+
if (!('evaluate' in plugin &&
|
873
|
+
plugin.evaluate)) { // If evalute is defined but the remote objects methods aren't, that's a bug
|
874
|
+
return Promise.resolve(undefined);
|
875
|
+
}
|
876
|
+
break;
|
877
|
+
case PrivateAPI.LanguageExtensionPluginCommands.ReleaseObject:
|
878
|
+
if ('releaseObject' in plugin && plugin.releaseObject) {
|
879
|
+
return plugin.releaseObject(request.parameters.objectId);
|
880
|
+
}
|
881
|
+
if (!('evaluate' in plugin) &&
|
882
|
+
plugin.evaluate) { // If evalute is defined but the remote objects methods aren't, that's a bug
|
883
|
+
return Promise.resolve(undefined);
|
884
|
+
}
|
885
|
+
break;
|
825
886
|
}
|
826
|
-
// @ts-expect-error
|
827
887
|
throw new Error(`Unknown language plugin method ${request.method}`);
|
828
888
|
}
|
829
889
|
|
@@ -849,6 +909,33 @@ self.injectedExtensionAPI = function(
|
|
849
909
|
port.postMessage({event: PrivateAPI.LanguageExtensionPluginEvents.UnregisteredLanguageExtensionPlugin});
|
850
910
|
port.close();
|
851
911
|
},
|
912
|
+
|
913
|
+
getWasmLinearMemory: async function(
|
914
|
+
this: APIImpl.LanguageExtensions, offset: number, length: number, stopId: number): Promise<ArrayBuffer> {
|
915
|
+
const result = await new Promise(
|
916
|
+
resolve => extensionServer.sendRequest(
|
917
|
+
{command: PrivateAPI.Commands.GetWasmLinearMemory, offset, length, stopId}, resolve));
|
918
|
+
if (Array.isArray(result)) {
|
919
|
+
return new Uint8Array(result).buffer;
|
920
|
+
}
|
921
|
+
return new ArrayBuffer(0);
|
922
|
+
},
|
923
|
+
getWasmLocal: async function(
|
924
|
+
this: APIImpl.LanguageExtensions, local: number, stopId: number): Promise<PublicAPI.Chrome.DevTools.WasmValue> {
|
925
|
+
return new Promise(
|
926
|
+
resolve => extensionServer.sendRequest({command: PrivateAPI.Commands.GetWasmLocal, local, stopId}, resolve));
|
927
|
+
},
|
928
|
+
getWasmGlobal: async function(this: APIImpl.LanguageExtensions, global: number, stopId: number):
|
929
|
+
Promise<PublicAPI.Chrome.DevTools.WasmValue> {
|
930
|
+
return new Promise(
|
931
|
+
resolve =>
|
932
|
+
extensionServer.sendRequest({command: PrivateAPI.Commands.GetWasmGlobal, global, stopId}, resolve));
|
933
|
+
},
|
934
|
+
getWasmOp: async function(this: APIImpl.LanguageExtensions, op: number, stopId: number):
|
935
|
+
Promise<PublicAPI.Chrome.DevTools.WasmValue> {
|
936
|
+
return new Promise(
|
937
|
+
resolve => extensionServer.sendRequest({command: PrivateAPI.Commands.GetWasmOp, op, stopId}, resolve));
|
938
|
+
},
|
852
939
|
};
|
853
940
|
|
854
941
|
function declareInterfaceClass<ImplT extends APIImpl.Callable>(implConstructor: ImplT): (
|
@@ -1241,11 +1328,12 @@ self.injectedExtensionAPI = function(
|
|
1241
1328
|
APIImpl.ExtensionServerClient,
|
1242
1329
|
'sendRequest'|'hasHandler'|'registerHandler'|'unregisterHandler'|'nextObjectId'|'_registerCallback'|
|
1243
1330
|
'_onCallback'|'_onMessage'>) = {
|
1244
|
-
sendRequest: function(
|
1331
|
+
sendRequest: function<ResponseT>(
|
1245
1332
|
this: APIImpl.ExtensionServerClient, message: PrivateAPI.ServerRequests,
|
1246
|
-
callback?: (response:
|
1333
|
+
callback?: (response: ResponseT) => unknown, transfers?: Transferable[]): void {
|
1247
1334
|
if (typeof callback === 'function') {
|
1248
|
-
(message as PrivateAPI.ExtensionServerRequestMessage).requestId =
|
1335
|
+
(message as PrivateAPI.ExtensionServerRequestMessage).requestId =
|
1336
|
+
this._registerCallback(callback as (response: unknown) => unknown);
|
1249
1337
|
}
|
1250
1338
|
// @ts-expect-error
|
1251
1339
|
this._port.postMessage(message, transfers);
|
@@ -55,6 +55,7 @@ import {LanguageExtensionEndpoint} from './LanguageExtensionEndpoint.js';
|
|
55
55
|
import {RecorderExtensionEndpoint} from './RecorderExtensionEndpoint.js';
|
56
56
|
import {PrivateAPI} from './ExtensionAPI.js';
|
57
57
|
import {RecorderPluginManager} from './RecorderPluginManager.js';
|
58
|
+
import type {Chrome} from '../../../extension-api/ExtensionAPI.js'; // eslint-disable-line rulesdir/es_modules_import
|
58
59
|
|
59
60
|
const extensionOrigins: WeakMap<MessagePort, Platform.DevToolsPath.UrlString> = new WeakMap();
|
60
61
|
|
@@ -140,6 +141,10 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
140
141
|
this.registerHandler(PrivateAPI.Commands.UpdateButton, this.onUpdateButton.bind(this));
|
141
142
|
this.registerHandler(
|
142
143
|
PrivateAPI.Commands.RegisterLanguageExtensionPlugin, this.registerLanguageExtensionEndpoint.bind(this));
|
144
|
+
this.registerHandler(PrivateAPI.Commands.GetWasmLinearMemory, this.onGetWasmLinearMemory.bind(this));
|
145
|
+
this.registerHandler(PrivateAPI.Commands.GetWasmGlobal, this.onGetWasmGlobal.bind(this));
|
146
|
+
this.registerHandler(PrivateAPI.Commands.GetWasmLocal, this.onGetWasmLocal.bind(this));
|
147
|
+
this.registerHandler(PrivateAPI.Commands.GetWasmOp, this.onGetWasmOp.bind(this));
|
143
148
|
this.registerHandler(
|
144
149
|
PrivateAPI.Commands.RegisterRecorderExtensionPlugin, this.registerRecorderExtensionEndpoint.bind(this));
|
145
150
|
window.addEventListener('message', this.onWindowMessage.bind(this), false); // Only for main window.
|
@@ -204,7 +209,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
204
209
|
private registerLanguageExtensionEndpoint(
|
205
210
|
message: PrivateAPI.ExtensionServerRequestMessage, _shared_port: MessagePort): Record {
|
206
211
|
if (message.command !== PrivateAPI.Commands.RegisterLanguageExtensionPlugin) {
|
207
|
-
return this.status.E_BADARG('command', `expected ${PrivateAPI.Commands.
|
212
|
+
return this.status.E_BADARG('command', `expected ${PrivateAPI.Commands.RegisterLanguageExtensionPlugin}`);
|
208
213
|
}
|
209
214
|
const {pluginManager} = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance();
|
210
215
|
if (!pluginManager) {
|
@@ -219,6 +224,63 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
219
224
|
return this.status.OK();
|
220
225
|
}
|
221
226
|
|
227
|
+
private async loadWasmValue<T>(expression: string, stopId: unknown): Promise<Record|T> {
|
228
|
+
const {pluginManager} = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance();
|
229
|
+
if (!pluginManager) {
|
230
|
+
return this.status.E_FAILED('WebAssembly DWARF support needs to be enabled to use this extension');
|
231
|
+
}
|
232
|
+
|
233
|
+
const callFrame = pluginManager.callFrameForStopId(stopId as Bindings.DebuggerLanguagePlugins.StopId);
|
234
|
+
if (!callFrame) {
|
235
|
+
return this.status.E_BADARG('stopId', 'Unknown stop id');
|
236
|
+
}
|
237
|
+
const result = await callFrame.debuggerModel.agent.invoke_evaluateOnCallFrame({
|
238
|
+
callFrameId: callFrame.id,
|
239
|
+
expression,
|
240
|
+
silent: true,
|
241
|
+
returnByValue: true,
|
242
|
+
throwOnSideEffect: true,
|
243
|
+
});
|
244
|
+
|
245
|
+
if (!result.exceptionDetails && !result.getError()) {
|
246
|
+
return result.result.value;
|
247
|
+
}
|
248
|
+
|
249
|
+
return this.status.E_FAILED('Failed');
|
250
|
+
}
|
251
|
+
|
252
|
+
private async onGetWasmLinearMemory(message: PrivateAPI.ExtensionServerRequestMessage): Promise<Record|number[]> {
|
253
|
+
if (message.command !== PrivateAPI.Commands.GetWasmLinearMemory) {
|
254
|
+
return this.status.E_BADARG('command', `expected ${PrivateAPI.Commands.GetWasmLinearMemory}`);
|
255
|
+
}
|
256
|
+
return await this.loadWasmValue<number[]>(
|
257
|
+
`[].slice.call(new Uint8Array(memories[0].buffer, ${Number(message.offset)}, ${Number(message.length)}))`,
|
258
|
+
message.stopId);
|
259
|
+
}
|
260
|
+
|
261
|
+
private async onGetWasmGlobal(message: PrivateAPI.ExtensionServerRequestMessage):
|
262
|
+
Promise<Record|Chrome.DevTools.WasmValue> {
|
263
|
+
if (message.command !== PrivateAPI.Commands.GetWasmGlobal) {
|
264
|
+
return this.status.E_BADARG('command', `expected ${PrivateAPI.Commands.GetWasmGlobal}`);
|
265
|
+
}
|
266
|
+
return this.loadWasmValue(`globals[${Number(message.global)}]`, message.stopId);
|
267
|
+
}
|
268
|
+
|
269
|
+
private async onGetWasmLocal(message: PrivateAPI.ExtensionServerRequestMessage):
|
270
|
+
Promise<Record|Chrome.DevTools.WasmValue> {
|
271
|
+
if (message.command !== PrivateAPI.Commands.GetWasmLocal) {
|
272
|
+
return this.status.E_BADARG('command', `expected ${PrivateAPI.Commands.GetWasmLocal}`);
|
273
|
+
}
|
274
|
+
return this.loadWasmValue(`locals[${Number(message.local)}]`, message.stopId);
|
275
|
+
}
|
276
|
+
private async onGetWasmOp(message: PrivateAPI.ExtensionServerRequestMessage):
|
277
|
+
Promise<Record|Chrome.DevTools.WasmValue> {
|
278
|
+
if (message.command !== PrivateAPI.Commands.GetWasmOp) {
|
279
|
+
return this.status.E_BADARG('command', `expected ${PrivateAPI.Commands.GetWasmOp}`);
|
280
|
+
}
|
281
|
+
return this.loadWasmValue(`stack[${Number(message.op)}]`, message.stopId);
|
282
|
+
}
|
283
|
+
|
222
284
|
private registerRecorderExtensionEndpoint(
|
223
285
|
message: PrivateAPI.ExtensionServerRequestMessage, _shared_port: MessagePort): Record {
|
224
286
|
if (message.command !== PrivateAPI.Commands.RegisterRecorderExtensionPlugin) {
|