Commit d7b32423 authored by Joel Einbinder's avatar Joel Einbinder Committed by Commit Bot

DevTools: Make snippets work wtih local overrides

Local network overrides was turning off automapping, but automapping is
needed for snippets to work.

Bug: 980083
Change-Id: I90b7043eb7a0ca7e1b8a280e3a5c569d527d2b3c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1713464
Commit-Queue: Joel Einbinder <einbinder@chromium.org>
Reviewed-by: default avatarAndrey Lushnikov <lushnikov@chromium.org>
Reviewed-by: default avatarErik Luo <luoe@chromium.org>
Cr-Commit-Position: refs/heads/master@{#680538}
parent b8fb65d2
...@@ -55,7 +55,7 @@ BindingsTestRunner.initializeTestMapping = function() { ...@@ -55,7 +55,7 @@ BindingsTestRunner.initializeTestMapping = function() {
class TestMapping { class TestMapping {
constructor(persistence) { constructor(persistence) {
this._persistence = persistence; this._persistence = persistence;
persistence.setAutomappingEnabled(false); persistence.addNetworkInterceptor(() => true);
this._bindings = new Set(); this._bindings = new Set();
} }
......
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
/**
* @implements {Persistence.MappingSystem}
* @unrestricted
*/
Persistence.Automapping = class { Persistence.Automapping = class {
/** /**
* @param {!Workspace.Workspace} workspace * @param {!Workspace.Workspace} workspace
...@@ -19,6 +15,10 @@ Persistence.Automapping = class { ...@@ -19,6 +15,10 @@ Persistence.Automapping = class {
this._onStatusRemoved = onStatusRemoved; this._onStatusRemoved = onStatusRemoved;
/** @type {!Set<!Persistence.AutomappingStatus>} */ /** @type {!Set<!Persistence.AutomappingStatus>} */
this._statuses = new Set(); this._statuses = new Set();
this._statusSymbol = Symbol('Automapping.Status');
this._processingPromiseSymbol = Symbol('Automapping.ProcessingPromise');
this._metadataSymbol = Symbol('Automapping.Metadata');
/** @type {!Map<string, !Workspace.UISourceCode>} */ /** @type {!Map<string, !Workspace.UISourceCode>} */
this._fileSystemUISourceCodes = new Map(); this._fileSystemUISourceCodes = new Map();
...@@ -29,22 +29,22 @@ Persistence.Automapping = class { ...@@ -29,22 +29,22 @@ Persistence.Automapping = class {
this._projectFoldersIndex = new Persistence.Automapping.FolderIndex(pathEncoder); this._projectFoldersIndex = new Persistence.Automapping.FolderIndex(pathEncoder);
this._activeFoldersIndex = new Persistence.Automapping.FolderIndex(pathEncoder); this._activeFoldersIndex = new Persistence.Automapping.FolderIndex(pathEncoder);
this._eventListeners = [ /** @type {!Array<function(!Workspace.UISourceCode):boolean>} */
this._interceptors = [];
this._workspace.addEventListener( this._workspace.addEventListener(
Workspace.Workspace.Events.UISourceCodeAdded, Workspace.Workspace.Events.UISourceCodeAdded,
event => this._onUISourceCodeAdded(/** @type {!Workspace.UISourceCode} */ (event.data))), event => this._onUISourceCodeAdded(/** @type {!Workspace.UISourceCode} */ (event.data)));
this._workspace.addEventListener( this._workspace.addEventListener(
Workspace.Workspace.Events.UISourceCodeRemoved, Workspace.Workspace.Events.UISourceCodeRemoved,
event => this._onUISourceCodeRemoved(/** @type {!Workspace.UISourceCode} */ (event.data))), event => this._onUISourceCodeRemoved(/** @type {!Workspace.UISourceCode} */ (event.data)));
this._workspace.addEventListener( this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRenamed, this._onUISourceCodeRenamed, this);
Workspace.Workspace.Events.UISourceCodeRenamed, this._onUISourceCodeRenamed, this),
this._workspace.addEventListener( this._workspace.addEventListener(
Workspace.Workspace.Events.ProjectAdded, Workspace.Workspace.Events.ProjectAdded,
event => this._onProjectAdded(/** @type {!Workspace.Project} */ (event.data)), this), event => this._onProjectAdded(/** @type {!Workspace.Project} */ (event.data)), this);
this._workspace.addEventListener( this._workspace.addEventListener(
Workspace.Workspace.Events.ProjectRemoved, Workspace.Workspace.Events.ProjectRemoved,
event => this._onProjectRemoved(/** @type {!Workspace.Project} */ (event.data)), this), event => this._onProjectRemoved(/** @type {!Workspace.Project} */ (event.data)), this);
];
for (const fileSystem of workspace.projects()) for (const fileSystem of workspace.projects())
this._onProjectAdded(fileSystem); this._onProjectAdded(fileSystem);
...@@ -52,7 +52,15 @@ Persistence.Automapping = class { ...@@ -52,7 +52,15 @@ Persistence.Automapping = class {
this._onUISourceCodeAdded(uiSourceCode); this._onUISourceCodeAdded(uiSourceCode);
} }
_scheduleRemap() { /**
* @param {function(!Workspace.UISourceCode):boolean} interceptor
*/
addNetworkInterceptor(interceptor) {
this._interceptors.push(interceptor);
this.scheduleRemap();
}
scheduleRemap() {
for (const status of this._statuses.valuesArray()) for (const status of this._statuses.valuesArray())
this._clearNetworkStatus(status.network); this._clearNetworkStatus(status.network);
this._scheduleSweep(); this._scheduleSweep();
...@@ -91,7 +99,7 @@ Persistence.Automapping = class { ...@@ -91,7 +99,7 @@ Persistence.Automapping = class {
for (const gitFolder of fileSystem.initialGitFolders()) for (const gitFolder of fileSystem.initialGitFolders())
this._projectFoldersIndex.removeFolder(gitFolder); this._projectFoldersIndex.removeFolder(gitFolder);
this._projectFoldersIndex.removeFolder(fileSystem.fileSystemPath()); this._projectFoldersIndex.removeFolder(fileSystem.fileSystemPath());
this._scheduleRemap(); this.scheduleRemap();
} }
/** /**
...@@ -105,7 +113,7 @@ Persistence.Automapping = class { ...@@ -105,7 +113,7 @@ Persistence.Automapping = class {
this._projectFoldersIndex.addFolder(gitFolder); this._projectFoldersIndex.addFolder(gitFolder);
this._projectFoldersIndex.addFolder(fileSystem.fileSystemPath()); this._projectFoldersIndex.addFolder(fileSystem.fileSystemPath());
project.uiSourceCodes().forEach(this._onUISourceCodeAdded.bind(this)); project.uiSourceCodes().forEach(this._onUISourceCodeAdded.bind(this));
this._scheduleRemap(); this.scheduleRemap();
} }
/** /**
...@@ -131,7 +139,7 @@ Persistence.Automapping = class { ...@@ -131,7 +139,7 @@ Persistence.Automapping = class {
if (uiSourceCode.project().type() === Workspace.projectTypes.FileSystem) { if (uiSourceCode.project().type() === Workspace.projectTypes.FileSystem) {
this._filesIndex.removePath(uiSourceCode.url()); this._filesIndex.removePath(uiSourceCode.url());
this._fileSystemUISourceCodes.delete(uiSourceCode.url()); this._fileSystemUISourceCodes.delete(uiSourceCode.url());
const status = uiSourceCode[Persistence.Automapping._status]; const status = uiSourceCode[this._statusSymbol];
if (status) if (status)
this._clearNetworkStatus(status.network); this._clearNetworkStatus(status.network);
} else if (uiSourceCode.project().type() === Workspace.projectTypes.Network) { } else if (uiSourceCode.project().type() === Workspace.projectTypes.Network) {
...@@ -150,7 +158,7 @@ Persistence.Automapping = class { ...@@ -150,7 +158,7 @@ Persistence.Automapping = class {
this._filesIndex.removePath(oldURL); this._filesIndex.removePath(oldURL);
this._fileSystemUISourceCodes.delete(oldURL); this._fileSystemUISourceCodes.delete(oldURL);
const status = uiSourceCode[Persistence.Automapping._status]; const status = uiSourceCode[this._statusSymbol];
if (status) if (status)
this._clearNetworkStatus(status.network); this._clearNetworkStatus(status.network);
...@@ -163,14 +171,15 @@ Persistence.Automapping = class { ...@@ -163,14 +171,15 @@ Persistence.Automapping = class {
* @param {!Workspace.UISourceCode} networkSourceCode * @param {!Workspace.UISourceCode} networkSourceCode
*/ */
_computeNetworkStatus(networkSourceCode) { _computeNetworkStatus(networkSourceCode) {
if (networkSourceCode[Persistence.Automapping._processingPromise] || if (networkSourceCode[this._processingPromiseSymbol] || networkSourceCode[this._statusSymbol])
networkSourceCode[Persistence.Automapping._status]) return;
if (this._interceptors.some(interceptor => interceptor(networkSourceCode)))
return; return;
if (networkSourceCode.url().startsWith('wasm://')) if (networkSourceCode.url().startsWith('wasm://'))
return; return;
const createBindingPromise = const createBindingPromise =
this._createBinding(networkSourceCode).then(validateStatus.bind(this)).then(onStatus.bind(this)); this._createBinding(networkSourceCode).then(validateStatus.bind(this)).then(onStatus.bind(this));
networkSourceCode[Persistence.Automapping._processingPromise] = createBindingPromise; networkSourceCode[this._processingPromiseSymbol] = createBindingPromise;
/** /**
* @param {?Persistence.AutomappingStatus} status * @param {?Persistence.AutomappingStatus} status
...@@ -180,7 +189,7 @@ Persistence.Automapping = class { ...@@ -180,7 +189,7 @@ Persistence.Automapping = class {
async function validateStatus(status) { async function validateStatus(status) {
if (!status) if (!status)
return null; return null;
if (networkSourceCode[Persistence.Automapping._processingPromise] !== createBindingPromise) if (networkSourceCode[this._processingPromiseSymbol] !== createBindingPromise)
return null; return null;
if (status.network.contentType().isFromSourceMap() || !status.fileSystem.contentType().isTextType()) if (status.network.contentType().isFromSourceMap() || !status.fileSystem.contentType().isTextType())
return status; return status;
...@@ -214,7 +223,7 @@ Persistence.Automapping = class { ...@@ -214,7 +223,7 @@ Persistence.Automapping = class {
if (fileSystemContent === null || networkContent === null) if (fileSystemContent === null || networkContent === null)
return null; return null;
if (networkSourceCode[Persistence.Automapping._processingPromise] !== createBindingPromise) if (networkSourceCode[this._processingPromiseSymbol] !== createBindingPromise)
return null; return null;
const target = Bindings.NetworkProject.targetForUISourceCode(status.network); const target = Bindings.NetworkProject.targetForUISourceCode(status.network);
...@@ -239,20 +248,20 @@ Persistence.Automapping = class { ...@@ -239,20 +248,20 @@ Persistence.Automapping = class {
* @this {Persistence.Automapping} * @this {Persistence.Automapping}
*/ */
function onStatus(status) { function onStatus(status) {
if (networkSourceCode[Persistence.Automapping._processingPromise] !== createBindingPromise) if (networkSourceCode[this._processingPromiseSymbol] !== createBindingPromise)
return; return;
networkSourceCode[Persistence.Automapping._processingPromise] = null; networkSourceCode[this._processingPromiseSymbol] = null;
if (!status || this._disposed) { if (!status) {
this._onBindingFailedForTest(); this._onBindingFailedForTest();
return; return;
} }
// TODO(lushnikov): remove this check once there's a single uiSourceCode per url. @see crbug.com/670180 // TODO(lushnikov): remove this check once there's a single uiSourceCode per url. @see crbug.com/670180
if (status.network[Persistence.Automapping._status] || status.fileSystem[Persistence.Automapping._status]) if (status.network[this._statusSymbol] || status.fileSystem[this._statusSymbol])
return; return;
this._statuses.add(status); this._statuses.add(status);
status.network[Persistence.Automapping._status] = status; status.network[this._statusSymbol] = status;
status.fileSystem[Persistence.Automapping._status] = status; status.fileSystem[this._statusSymbol] = status;
if (status.exactMatch) { if (status.exactMatch) {
const projectFolder = this._projectFoldersIndex.closestParentFolder(status.fileSystem.url()); const projectFolder = this._projectFoldersIndex.closestParentFolder(status.fileSystem.url());
const newFolderAdded = projectFolder ? this._activeFoldersIndex.addFolder(projectFolder) : false; const newFolderAdded = projectFolder ? this._activeFoldersIndex.addFolder(projectFolder) : false;
...@@ -276,17 +285,17 @@ Persistence.Automapping = class { ...@@ -276,17 +285,17 @@ Persistence.Automapping = class {
* @param {!Workspace.UISourceCode} networkSourceCode * @param {!Workspace.UISourceCode} networkSourceCode
*/ */
_clearNetworkStatus(networkSourceCode) { _clearNetworkStatus(networkSourceCode) {
if (networkSourceCode[Persistence.Automapping._processingPromise]) { if (networkSourceCode[this._processingPromiseSymbol]) {
networkSourceCode[Persistence.Automapping._processingPromise] = null; networkSourceCode[this._processingPromiseSymbol] = null;
return; return;
} }
const status = networkSourceCode[Persistence.Automapping._status]; const status = networkSourceCode[this._statusSymbol];
if (!status) if (!status)
return; return;
this._statuses.delete(status); this._statuses.delete(status);
status.network[Persistence.Automapping._status] = null; status.network[this._statusSymbol] = null;
status.fileSystem[Persistence.Automapping._status] = null; status.fileSystem[this._statusSymbol] = null;
if (status.exactMatch) { if (status.exactMatch) {
const projectFolder = this._projectFoldersIndex.closestParentFolder(status.fileSystem.url()); const projectFolder = this._projectFoldersIndex.closestParentFolder(status.fileSystem.url());
if (projectFolder) if (projectFolder)
...@@ -325,7 +334,7 @@ Persistence.Automapping = class { ...@@ -325,7 +334,7 @@ Persistence.Automapping = class {
*/ */
function onMetadatas() { function onMetadatas() {
const activeFiles = similarFiles.filter(file => !!this._activeFoldersIndex.closestParentFolder(file.url())); const activeFiles = similarFiles.filter(file => !!this._activeFoldersIndex.closestParentFolder(file.url()));
const networkMetadata = networkSourceCode[Persistence.Automapping._metadata]; const networkMetadata = networkSourceCode[this._metadataSymbol];
if (!networkMetadata || (!networkMetadata.modificationTime && typeof networkMetadata.contentSize !== 'number')) { if (!networkMetadata || (!networkMetadata.modificationTime && typeof networkMetadata.contentSize !== 'number')) {
// If networkSourceCode does not have metadata, try to match against active folders. // If networkSourceCode does not have metadata, try to match against active folders.
if (activeFiles.length !== 1) if (activeFiles.length !== 1)
...@@ -348,16 +357,9 @@ Persistence.Automapping = class { ...@@ -348,16 +357,9 @@ Persistence.Automapping = class {
* @return {!Promise} * @return {!Promise}
*/ */
_pullMetadatas(uiSourceCodes) { _pullMetadatas(uiSourceCodes) {
const promises = uiSourceCodes.map(file => fetchMetadata(file)); return Promise.all(uiSourceCodes.map(async file => {
return Promise.all(promises); file[this._metadataSymbol] = await file.requestMetadata();
}));
/**
* @param {!Workspace.UISourceCode} file
* @return {!Promise}
*/
function fetchMetadata(file) {
return file.requestMetadata().then(metadata => file[Persistence.Automapping._metadata] = metadata);
}
} }
/** /**
...@@ -367,7 +369,7 @@ Persistence.Automapping = class { ...@@ -367,7 +369,7 @@ Persistence.Automapping = class {
*/ */
_filterWithMetadata(files, networkMetadata) { _filterWithMetadata(files, networkMetadata) {
return files.filter(file => { return files.filter(file => {
const fileMetadata = file[Persistence.Automapping._metadata]; const fileMetadata = file[this._metadataSymbol];
if (!fileMetadata) if (!fileMetadata)
return false; return false;
// Allow a second of difference due to network timestamps lack of precision. // Allow a second of difference due to network timestamps lack of precision.
...@@ -377,24 +379,8 @@ Persistence.Automapping = class { ...@@ -377,24 +379,8 @@ Persistence.Automapping = class {
return timeMatches && contentMatches; return timeMatches && contentMatches;
}); });
} }
/**
* @override
*/
dispose() {
if (this._disposed)
return;
this._disposed = true;
Common.EventTarget.removeEventListeners(this._eventListeners);
for (const status of this._statuses.valuesArray())
this._clearNetworkStatus(status.network);
}
}; };
Persistence.Automapping._status = Symbol('Automapping.Status');
Persistence.Automapping._processingPromise = Symbol('Automapping.ProcessingPromise');
Persistence.Automapping._metadata = Symbol('Automapping.Metadata');
/** /**
* @unrestricted * @unrestricted
*/ */
......
...@@ -37,6 +37,8 @@ Persistence.NetworkPersistenceManager = class extends Common.Object { ...@@ -37,6 +37,8 @@ Persistence.NetworkPersistenceManager = class extends Common.Object {
Workspace.Workspace.Events.ProjectRemoved, Workspace.Workspace.Events.ProjectRemoved,
event => this._onProjectRemoved(/** @type {!Workspace.Project} */ (event.data))); event => this._onProjectRemoved(/** @type {!Workspace.Project} */ (event.data)));
Persistence.persistence.addNetworkInterceptor(this._canHandleNetworkUISourceCode.bind(this));
/** @type {!Array<!Common.EventTarget.EventDescriptor>} */ /** @type {!Array<!Common.EventTarget.EventDescriptor>} */
this._eventDescriptors = []; this._eventDescriptors = [];
this._enabledChanged(); this._enabledChanged();
...@@ -114,7 +116,7 @@ Persistence.NetworkPersistenceManager = class extends Common.Object { ...@@ -114,7 +116,7 @@ Persistence.NetworkPersistenceManager = class extends Common.Object {
this._project.uiSourceCodes().forEach(this._filesystemUISourceCodeRemoved.bind(this)); this._project.uiSourceCodes().forEach(this._filesystemUISourceCodeRemoved.bind(this));
this._networkUISourceCodeForEncodedPath.clear(); this._networkUISourceCodeForEncodedPath.clear();
} }
Persistence.persistence.setAutomappingEnabled(!this._active); Persistence.persistence.refreshAutomapping();
} }
/** /**
...@@ -287,11 +289,19 @@ Persistence.NetworkPersistenceManager = class extends Common.Object { ...@@ -287,11 +289,19 @@ Persistence.NetworkPersistenceManager = class extends Common.Object {
this._filesystemUISourceCodeAdded(uiSourceCode); this._filesystemUISourceCodeAdded(uiSourceCode);
} }
/**
* @param {!Workspace.UISourceCode} uiSourceCode
*/
_canHandleNetworkUISourceCode(uiSourceCode) {
return this._active && !uiSourceCode.url().startsWith('snippet://');
}
/** /**
* @param {!Workspace.UISourceCode} uiSourceCode * @param {!Workspace.UISourceCode} uiSourceCode
*/ */
_networkUISourceCodeAdded(uiSourceCode) { _networkUISourceCodeAdded(uiSourceCode) {
if (!this._active || uiSourceCode.project().type() !== Workspace.projectTypes.Network) if (uiSourceCode.project().type() !== Workspace.projectTypes.Network ||
!this._canHandleNetworkUISourceCode(uiSourceCode))
return; return;
const url = Common.ParsedURL.urlWithoutHash(uiSourceCode.url()); const url = Common.ParsedURL.urlWithoutHash(uiSourceCode.url());
this._networkUISourceCodeForEncodedPath.set(this._encodedPathFromUrl(url), uiSourceCode); this._networkUISourceCodeForEncodedPath.set(this._encodedPathFromUrl(url), uiSourceCode);
......
...@@ -22,23 +22,20 @@ Persistence.Persistence = class extends Common.Object { ...@@ -22,23 +22,20 @@ Persistence.Persistence = class extends Common.Object {
const linkDecorator = new Persistence.PersistenceUtils.LinkDecorator(this); const linkDecorator = new Persistence.PersistenceUtils.LinkDecorator(this);
Components.Linkifier.setLinkDecorator(linkDecorator); Components.Linkifier.setLinkDecorator(linkDecorator);
this._mapping = null;
this.setAutomappingEnabled(true); this._mapping =
new Persistence.Automapping(this._workspace, this._onStatusAdded.bind(this), this._onStatusRemoved.bind(this));
} }
/** /**
* @param {boolean} enabled * @param {function(!Workspace.UISourceCode):boolean} interceptor
*/ */
setAutomappingEnabled(enabled) { addNetworkInterceptor(interceptor) {
if (enabled === !!this._mapping) this._mapping.addNetworkInterceptor(interceptor);
return;
if (!enabled) {
this._mapping.dispose();
this._mapping = null;
} else {
this._mapping = new Persistence.Automapping(
this._workspace, this._onStatusAdded.bind(this), this._onStatusRemoved.bind(this));
} }
refreshAutomapping() {
this._mapping.scheduleRemap();
} }
/** /**
...@@ -387,13 +384,6 @@ Persistence.Persistence = class extends Common.Object { ...@@ -387,13 +384,6 @@ Persistence.Persistence = class extends Common.Object {
filePath += '/'; filePath += '/';
return this._filePathPrefixesToBindingCount.has(filePath); return this._filePathPrefixesToBindingCount.has(filePath);
} }
dispose() {
if (this._mapping) {
this._mapping.dispose();
this._mapping = null;
}
}
}; };
Persistence.Persistence._binding = Symbol('Persistence.Binding'); Persistence.Persistence._binding = Symbol('Persistence.Binding');
...@@ -449,14 +439,5 @@ Persistence.PersistenceBinding = class { ...@@ -449,14 +439,5 @@ Persistence.PersistenceBinding = class {
} }
}; };
/**
* @interface
*/
Persistence.MappingSystem = function() {};
Persistence.MappingSystem.prototype = {
dispose: function() {}
};
/** @type {!Persistence.Persistence} */ /** @type {!Persistence.Persistence} */
Persistence.persistence; Persistence.persistence;
Verifies that snippets still map when local overrides is on.
snippet:///my_snippet_name <=> snippet:///my_snippet_name
// Copyright 2019 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.
(async function() {
TestRunner.addResult(
'Verifies that snippets still map when local overrides is on.\n');
await TestRunner.loadModule('sources_test_runner');
await TestRunner.loadModule('bindings_test_runner');
await TestRunner.showPanel('sources');
await BindingsTestRunner.createOverrideProject('file:///tmp');
BindingsTestRunner.setOverridesEnabled(true);
const sourceCode = `'hello';`;
const projects =
Workspace.workspace.projectsForType(Workspace.projectTypes.FileSystem);
const snippetsProject = projects.find(
project => Persistence.FileSystemWorkspaceBinding.fileSystemType(
project) === 'snippets');
const uiSourceCode = await snippetsProject.createFile('');
uiSourceCode.setContent(sourceCode);
await Common.Revealer.reveal(uiSourceCode);
await uiSourceCode.rename('my_snippet_name');
const bindingPromise = Persistence.persistence.once(Persistence.Persistence.Events.BindingCreated);
Sources.SourcesPanel.instance()._runSnippet();
const binding = await bindingPromise;
TestRunner.addResult(binding.network.url() + ' <=> ' + binding.fileSystem.url());
TestRunner.completeTest();
})();
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment