Files
react-native-devtools-frontend/front_end/sources/ScriptOriginPlugin.js
T
Benedikt Meurer 6ef03671ae [wasm] Turn DebuggerLanguagePluginManager into a singleton.
The `DebuggerLanguagePluginManager` used to be per `DebuggerModel` (and
hence per target) instead of being a singleton, actually a 1-1 companion
of the `DebuggerWorkspaceBinding`. This caused a number of problems,
starting with the fact that we'd never remove raw modules (the debugging
information held inside of the extensions) that were referenced by any
target other than the "main" target. It also came with a couple of hairy
inherent race conditions, and mandated that all extensions would perform
reference counting.

This CL addresses these problems by having only a single instance of the
`DebuggerLanguagePluginManager`, which listens for targets appearing
and disappearing, and thus centralizing all the communication with the
language plugins. This reduces both the memory overhead for bookkeeping
and also addresses the race conditions when talking to the language
plugins, since all of this goes through a central bottleneck now. Also
removes the cyclic dependency between extensions/ and bindings/ modules.

Fixed: chromium:1122000
Bug: chromium:1148763
Change-Id: I0eeb4ae88bfa618c35f73c8644187423aae3bea3
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2537961
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Philip Pfaffe <pfaffe@chromium.org>
Auto-Submit: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Philip Pfaffe <pfaffe@chromium.org>
2020-11-17 10:02:18 +00:00

85 lines
3.1 KiB
JavaScript

// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as Bindings from '../bindings/bindings.js';
import * as Components from '../components/components.js';
import * as SDK from '../sdk/sdk.js'; // eslint-disable-line no-unused-vars
import * as SourceFrame from '../source_frame/source_frame.js'; // eslint-disable-line no-unused-vars
import * as UI from '../ui/ui.js';
import * as Workspace from '../workspace/workspace.js'; // eslint-disable-line no-unused-vars
import {Plugin} from './Plugin.js';
export class ScriptOriginPlugin extends Plugin {
/**
* @param {!SourceFrame.SourcesTextEditor.SourcesTextEditor} textEditor
* @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
*/
constructor(textEditor, uiSourceCode) {
super();
this._textEditor = textEditor;
this._uiSourceCode = uiSourceCode;
}
/**
* @override
* @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
* @return {boolean}
*/
static accepts(uiSourceCode) {
return uiSourceCode.contentType().hasScripts() || !!ScriptOriginPlugin._script(uiSourceCode);
}
/**
* @override
* @return {!Promise<!Array<!UI.Toolbar.ToolbarItem>>}
*/
async rightToolbarItems() {
const originURL = Bindings.CompilerScriptMapping.CompilerScriptMapping.uiSourceCodeOrigin(this._uiSourceCode);
if (originURL) {
const item =
UI.UIUtils.formatLocalized('(source mapped from %s)', [Components.Linkifier.Linkifier.linkifyURL(originURL)]);
return [new UI.Toolbar.ToolbarItem(item)];
}
const pluginManager = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().pluginManager;
if (pluginManager) {
for (const originScript of pluginManager.scriptsForUISourceCode(this._uiSourceCode)) {
if (originScript.hasSourceURL) {
const item = UI.UIUtils.formatLocalized(
'(provided via debug info by %s)', [Components.Linkifier.Linkifier.linkifyURL(originScript.sourceURL)]);
return [new UI.Toolbar.ToolbarItem(item)];
}
}
}
// Handle anonymous scripts with an originStackTrace.
const script = await ScriptOriginPlugin._script(this._uiSourceCode);
if (!script || !script.originStackTrace) {
return [];
}
const link = linkifier.linkifyStackTraceTopFrame(script.debuggerModel.target(), script.originStackTrace);
return [new UI.Toolbar.ToolbarItem(link)];
}
/**
* @param {!Workspace.UISourceCode.UISourceCode} uiSourceCode
* @return {!Promise<?SDK.Script.Script>}
*/
static async _script(uiSourceCode) {
const locations =
await Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().uiLocationToRawLocations(
uiSourceCode, 0, 0);
for (const location of locations) {
const script = location.script();
if (script && script.originStackTrace) {
return script;
}
}
return null;
}
}
export const linkifier = new Components.Linkifier.Linkifier();