mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-01 17:57:36 +08:00
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>
85 lines
3.1 KiB
JavaScript
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();
|