Commit 04bdec65 authored by lushnikov's avatar lushnikov Committed by Commit bot

DevTools: introduce API for the Common.FormatterWorkerPool.

Currently, the Common.FormatterWorkerPool provides two methods:
- runTask
- runChunkedTask

This is very low-level. In fact, FormatterWorkerPool is a front-end for
formatter workers; it makes sense to introduce an API which will describe
functionality of the worker.

BUG=none
R=dgozman

Review-Url: https://codereview.chromium.org/2570263002
Cr-Commit-Position: refs/heads/master@{#438699}
parent 314a23a1
......@@ -4,7 +4,6 @@
<script src="../../http/tests/inspector/network-test.js"></script>
<script>
function test() {
var worker = new Common.Worker("formatter_worker");
function check(jsonText)
{
var resultData = Network.JSONView._extractJSON(jsonText);
......@@ -13,12 +12,10 @@ function test() {
return;
}
worker.onmessage = success;
worker.postMessage({method: "relaxedJSONParser", params:{content: resultData.data}});
Common.formatterWorkerPool.parseJSONRelaxed(resultData.data).then(success);
function success(event)
function success(data)
{
var data = event.data;
if (data === null) {
failure();
return;
......@@ -60,7 +57,6 @@ function test() {
currentTestIndex++;
check(tests[currentTestIndex - 1]);
} else {
worker.terminate();
InspectorTest.completeTest();
}
}
......
......@@ -56,14 +56,13 @@ function test()
{
InspectorTest.addResult("Text:");
InspectorTest.addResult(" " + text + "\n");
Common.formatterWorkerPool.runTask("javaScriptIdentifiers", {content: text})
Common.formatterWorkerPool.javaScriptIdentifiers(text)
.then(onIdentifiers)
.then(next);
}
function onIdentifiers(event)
function onIdentifiers(ids)
{
var ids = event ? event.data : [];
InspectorTest.addResult("Identifiers:");
for (var id of ids)
InspectorTest.addResult(` id: ${id.name} offset: ${id.offset}`);
......
......@@ -489,7 +489,7 @@ Audits.AuditRules.UnusedCssRule = class extends Audits.AuditRule {
};
/**
* @typedef {!{sourceURL: string, rules: !Array.<!SDK.CSSParser.StyleRule>}}
* @typedef {!{sourceURL: string, rules: !Array.<!Common.FormatterWorkerPool.CSSStyleRule>}}
*/
Audits.AuditRules.ParsedStyleSheet;
......@@ -536,7 +536,7 @@ Audits.AuditRules.StyleSheetProcessor = class {
}
/**
* @param {!Array.<!SDK.CSSParser.Rule>} rules
* @param {!Array.<!Common.FormatterWorkerPool.CSSRule>} rules
*/
_onStyleSheetParsed(rules) {
if (this._progress.isCanceled()) {
......@@ -1232,7 +1232,7 @@ Audits.AuditRules.CSSRuleBase = class extends Audits.AuditRule {
/**
* @param {!Audits.AuditRules.ParsedStyleSheet} styleSheet
* @param {!SDK.CSSParser.StyleRule} rule
* @param {!Common.FormatterWorkerPool.CSSStyleRule} rule
* @param {!Audits.AuditRuleResult} result
*/
_visitRule(styleSheet, rule, result) {
......@@ -1261,7 +1261,7 @@ Audits.AuditRules.CSSRuleBase = class extends Audits.AuditRule {
/**
* @param {!Audits.AuditRules.ParsedStyleSheet} styleSheet
* @param {!SDK.CSSParser.StyleRule} rule
* @param {!Common.FormatterWorkerPool.CSSStyleRule} rule
* @param {!Audits.AuditRuleResult} result
*/
visitRule(styleSheet, rule, result) {
......@@ -1270,7 +1270,7 @@ Audits.AuditRules.CSSRuleBase = class extends Audits.AuditRule {
/**
* @param {!Audits.AuditRules.ParsedStyleSheet} styleSheet
* @param {!SDK.CSSParser.StyleRule} rule
* @param {!Common.FormatterWorkerPool.CSSStyleRule} rule
* @param {!Audits.AuditRuleResult} result
*/
didVisitRule(styleSheet, rule, result) {
......@@ -1279,8 +1279,8 @@ Audits.AuditRules.CSSRuleBase = class extends Audits.AuditRule {
/**
* @param {!Audits.AuditRules.ParsedStyleSheet} styleSheet
* @param {!SDK.CSSParser.StyleRule} rule
* @param {!SDK.CSSParser.Property} property
* @param {!Common.FormatterWorkerPool.CSSStyleRule} rule
* @param {!Common.FormatterWorkerPool.CSSProperty} property
* @param {!Audits.AuditRuleResult} result
*/
visitProperty(styleSheet, rule, property, result) {
......
......@@ -43,13 +43,13 @@ Common.FormatterWorkerPool = class {
_onWorkerMessage(worker, event) {
var task = this._workerTasks.get(worker);
if (task.isChunked && event.data && !event.data['isLastChunk']) {
task.callback(event);
task.callback(event.data);
return;
}
this._workerTasks.set(worker, null);
this._processNextTask();
task.callback(event.data ? event : null);
task.callback(event.data ? event.data : null);
}
/**
......@@ -71,20 +71,33 @@ Common.FormatterWorkerPool = class {
/**
* @param {string} methodName
* @param {!Object<string, string>} params
* @param {function(?MessageEvent)} callback
* @param {function(boolean, *)} callback
*/
runChunkedTask(methodName, params, callback) {
var task = new Common.FormatterWorkerPool.Task(methodName, params, callback, true);
_runChunkedTask(methodName, params, callback) {
var task = new Common.FormatterWorkerPool.Task(methodName, params, onData, true);
this._taskQueue.push(task);
this._processNextTask();
/**
* @param {?Object} data
*/
function onData(data) {
if (!data) {
callback(true, null);
return;
}
var isLastChunk = !!data['isLastChunk'];
var chunk = data['chunk'];
callback(isLastChunk, chunk);
}
}
/**
* @param {string} methodName
* @param {!Object<string, string>} params
* @return {!Promise<?MessageEvent>}
* @return {!Promise<*>}
*/
runTask(methodName, params) {
_runTask(methodName, params) {
var callback;
var promise = new Promise(fulfill => callback = fulfill);
var task = new Common.FormatterWorkerPool.Task(methodName, params, callback, false);
......@@ -92,6 +105,83 @@ Common.FormatterWorkerPool = class {
this._processNextTask();
return promise;
}
/**
* @param {string} content
* @return {!Promise<*>}
*/
parseJSONRelaxed(content) {
return this._runTask('parseJSONRelaxed', {content: content});
}
/**
* @param {string} content
* @return {!Promise<!Array<!Common.FormatterWorkerPool.SCSSRule>>}
*/
parseSCSS(content) {
return this._runTask('parseSCSS', {content: content}).then(rules => rules || []);
}
/**
* @param {string} mimeType
* @param {string} content
* @param {string} indentString
* @return {!Promise<!Common.FormatterWorkerPool.FormatResult>}
*/
format(mimeType, content, indentString) {
var parameters = {mimeType: mimeType, content: content, indentString: indentString};
return /** @type {!Promise<!Common.FormatterWorkerPool.FormatResult>} */ (this._runTask('format', parameters));
}
/**
* @param {string} content
* @return {!Promise<!Array<!{name: string, offset: number}>>}
*/
javaScriptIdentifiers(content) {
return this._runTask('javaScriptIdentifiers', {content: content}).then(ids => ids || []);
}
/**
* @param {string} content
* @return {!Promise<string>}
*/
evaluatableJavaScriptSubstring(content) {
return this._runTask('evaluatableJavaScriptSubstring', {content: content}).then(text => text || '');
}
/**
* @param {string} content
* @param {function(boolean, !Array<!Common.FormatterWorkerPool.CSSRule>)} callback
*/
parseCSS(content, callback) {
this._runChunkedTask('parseCSS', {content: content}, onDataChunk);
/**
* @param {boolean} isLastChunk
* @param {*} data
*/
function onDataChunk(isLastChunk, data) {
var rules = /** @type {!Array<!Common.FormatterWorkerPool.CSSRule>} */ (data || []);
callback(isLastChunk, rules);
}
}
/**
* @param {string} content
* @param {function(boolean, !Array<!Common.FormatterWorkerPool.JSOutlineItem>)} callback
*/
javaScriptOutline(content, callback) {
this._runChunkedTask('javaScriptOutline', {content: content}, onDataChunk);
/**
* @param {boolean} isLastChunk
* @param {*} data
*/
function onDataChunk(isLastChunk, data) {
var items = /** @type {!Array.<!Common.FormatterWorkerPool.JSOutlineItem>} */ (data || []);
callback(isLastChunk, items);
}
}
};
Common.FormatterWorkerPool.MaxWorkers = 2;
......@@ -114,5 +204,101 @@ Common.FormatterWorkerPool.Task = class {
}
};
Common.FormatterWorkerPool.FormatResult = class {
constructor() {
/** @type {string} */
this.content;
/** @type {!Common.FormatterWorkerPool.FormatMapping} */
this.mapping;
}
};
/** @typedef {{original: !Array<number>, formatted: !Array<number>}} */
Common.FormatterWorkerPool.FormatMapping;
Common.FormatterWorkerPool.JSOutlineItem = class {
constructor() {
/** @type {string} */
this.name;
/** @type {(string|undefined)} */
this.arguments;
/** @type {number} */
this.line;
/** @type {number} */
this.column;
}
};
/**
* @typedef {{startLine: number, startColumn: number, endLine: number, endColumn: number}}
*/
Common.FormatterWorkerPool.TextRange;
Common.FormatterWorkerPool.CSSProperty = class {
constructor() {
/** @type {string} */
this.name;
/** @type {!Common.FormatterWorkerPool.TextRange} */
this.nameRange;
/** @type {string} */
this.value;
/** @type {!Common.FormatterWorkerPool.TextRange} */
this.valueRange;
/** @type {!Common.FormatterWorkerPool.TextRange} */
this.range;
/** @type {(boolean|undefined)} */
this.disabled;
}
};
Common.FormatterWorkerPool.CSSStyleRule = class {
constructor() {
/** @type {string} */
this.selectorText;
/** @type {!Common.FormatterWorkerPool.TextRange} */
this.styleRange;
/** @type {number} */
this.lineNumber;
/** @type {number} */
this.columnNumber;
/** @type {!Array.<!Common.FormatterWorkerPool.CSSProperty>} */
this.properties;
}
};
/**
* @typedef {{atRule: string, lineNumber: number, columnNumber: number}}
*/
Common.FormatterWorkerPool.CSSAtRule;
/**
* @typedef {(Common.FormatterWorkerPool.CSSStyleRule|Common.FormatterWorkerPool.CSSAtRule)}
*/
Common.FormatterWorkerPool.CSSRule;
Common.FormatterWorkerPool.SCSSProperty = class {
constructor() {
/** @type {!Common.FormatterWorkerPool.TextRange} */
this.range;
/** @type {!Common.FormatterWorkerPool.TextRange} */
this.name;
/** @type {!Common.FormatterWorkerPool.TextRange} */
this.value;
/** @type {boolean} */
this.disabled;
}
};
Common.FormatterWorkerPool.SCSSRule = class {
constructor() {
/** @type {!Array<!Common.FormatterWorkerPool.TextRange>} */
this.selectors;
/** @type {!Array<!Common.FormatterWorkerPool.SCSSProperty>} */
this.properties;
/** @type {!Common.FormatterWorkerPool.TextRange} */
this.styleRange;
}
};
/** @type {!Common.FormatterWorkerPool} */
Common.formatterWorkerPool;
......@@ -78,8 +78,8 @@ self.onmessage = function(event) {
case 'evaluatableJavaScriptSubstring':
FormatterWorker.evaluatableJavaScriptSubstring(params.content);
break;
case 'relaxedJSONParser':
FormatterWorker.relaxedJSONParser(params.content);
case 'parseJSONRelaxed':
FormatterWorker.parseJSONRelaxed(params.content);
break;
default:
console.error('Unsupport method name: ' + method);
......@@ -89,7 +89,7 @@ self.onmessage = function(event) {
/**
* @param {string} content
*/
FormatterWorker.relaxedJSONParser = function(content) {
FormatterWorker.parseJSONRelaxed = function(content) {
postMessage(FormatterWorker.RelaxedJSONParser.parse(content));
};
......
......@@ -76,16 +76,16 @@ Network.JSONView = class extends UI.VBox {
returnObj = Network.JSONView._extractJSON(/** @type {string} */ (text));
if (!returnObj)
return Promise.resolve(/** @type {?Network.ParsedJSON} */ (null));
return Common.formatterWorkerPool.runTask('relaxedJSONParser', {content: returnObj.data}).then(handleReturnedJSON);
return Common.formatterWorkerPool.parseJSONRelaxed(returnObj.data).then(handleReturnedJSON);
/**
* @param {?MessageEvent} event
* @param {*} data
* @return {?Network.ParsedJSON}
*/
function handleReturnedJSON(event) {
if (!event || !event.data)
function handleReturnedJSON(data) {
if (!data)
return null;
returnObj.data = event.data;
returnObj.data = data;
return returnObj;
}
}
......
......@@ -12,19 +12,16 @@ Sass.SASSSupport.parseSCSS = function(url, content) {
var text = new Common.Text(content);
var document = new Sass.SASSSupport.ASTDocument(url, text);
return Common.formatterWorkerPool.runTask('parseSCSS', {content: content}).then(onParsed);
return Common.formatterWorkerPool.parseSCSS(content).then(onParsed);
/**
* @param {?MessageEvent} event
* @param {!Array<!Common.FormatterWorkerPool.SCSSRule>} rulePayloads
* @return {!Sass.SASSSupport.AST}
*/
function onParsed(event) {
if (!event)
return new Sass.SASSSupport.AST(document, []);
var data = /** @type {!Array<!Object>} */ (event.data);
function onParsed(rulePayloads) {
var rules = [];
for (var i = 0; i < data.length; ++i) {
var rulePayload = data[i];
for (var i = 0; i < rulePayloads.length; ++i) {
var rulePayload = rulePayloads[i];
var selectors = rulePayload.selectors.map(createTextNode);
var properties = rulePayload.properties.map(createProperty);
var range = Common.TextRange.fromObject(rulePayload.styleRange);
......
......@@ -16,7 +16,7 @@ SDK.CSSParser = class extends Common.Object {
/**
* @param {!SDK.CSSStyleSheetHeader} styleSheetHeader
* @param {function(!Array.<!SDK.CSSParser.Rule>)=} callback
* @param {function(!Array.<!Common.FormatterWorkerPool.CSSRule>)=} callback
*/
fetchAndParse(styleSheetHeader, callback) {
this._lock();
......@@ -26,7 +26,7 @@ SDK.CSSParser = class extends Common.Object {
/**
* @param {string} text
* @param {function(!Array.<!SDK.CSSParser.Rule>)=} callback
* @param {function(!Array.<!Common.FormatterWorkerPool.CSSRule>)=} callback
*/
parse(text, callback) {
this._lock();
......@@ -36,7 +36,7 @@ SDK.CSSParser = class extends Common.Object {
/**
* @param {string} text
* @return {!Promise<!Array.<!SDK.CSSParser.Rule>>}
* @return {!Promise<!Array.<!Common.FormatterWorkerPool.CSSRule>>}
*/
parsePromise(text) {
return new Promise(promiseConstructor.bind(this));
......@@ -59,7 +59,7 @@ SDK.CSSParser = class extends Common.Object {
}
/**
* @return {!Array.<!SDK.CSSParser.Rule>}
* @return {!Array.<!Common.FormatterWorkerPool.CSSRule>}
*/
rules() {
return this._rules;
......@@ -79,27 +79,18 @@ SDK.CSSParser = class extends Common.Object {
*/
_innerParse(text) {
this._rules = [];
var params = {content: text};
Common.formatterWorkerPool.runChunkedTask('parseCSS', params, this._onRuleChunk.bind(this));
Common.formatterWorkerPool.parseCSS(text || '', this._onRuleChunk.bind(this));
}
/**
* @param {?MessageEvent} event
* @param {boolean} isLastChunk
* @param {!Array.<!Common.FormatterWorkerPool.CSSRule>} rules
*/
_onRuleChunk(event) {
_onRuleChunk(isLastChunk, rules) {
if (this._terminated)
return;
if (!event) {
this._onFinishedParsing();
this.dispatchEventToListeners(SDK.CSSParser.Events.RulesParsed);
return;
}
var data = /** @type {!SDK.CSSParser.DataChunk} */ (event.data);
var chunk = data.chunk;
for (var i = 0; i < chunk.length; ++i)
this._rules.push(chunk[i]);
if (data.isLastChunk)
this._rules = this._rules.concat(rules);
if (isLastChunk)
this._onFinishedParsing();
this.dispatchEventToListeners(SDK.CSSParser.Events.RulesParsed);
}
......@@ -124,61 +115,3 @@ SDK.CSSParser = class extends Common.Object {
SDK.CSSParser.Events = {
RulesParsed: Symbol('RulesParsed')
};
/**
* @typedef {{isLastChunk: boolean, chunk: !Array.<!SDK.CSSParser.Rule>}}
*/
SDK.CSSParser.DataChunk;
/**
* @unrestricted
*/
SDK.CSSParser.StyleRule = class {
constructor() {
/** @type {string} */
this.selectorText;
/** @type {!SDK.CSSParser.Range} */
this.styleRange;
/** @type {number} */
this.lineNumber;
/** @type {number} */
this.columnNumber;
/** @type {!Array.<!SDK.CSSParser.Property>} */
this.properties;
}
};
/**
* @typedef {{atRule: string, lineNumber: number, columnNumber: number}}
*/
SDK.CSSParser.AtRule;
/**
* @typedef {(SDK.CSSParser.StyleRule|SDK.CSSParser.AtRule)}
*/
SDK.CSSParser.Rule;
/**
* @typedef {{startLine: number, startColumn: number, endLine: number, endColumn: number}}
*/
SDK.CSSParser.Range;
/**
* @unrestricted
*/
SDK.CSSParser.Property = class {
constructor() {
/** @type {string} */
this.name;
/** @type {!SDK.CSSParser.Range} */
this.nameRange;
/** @type {string} */
this.value;
/** @type {!SDK.CSSParser.Range} */
this.valueRange;
/** @type {!SDK.CSSParser.Range} */
this.range;
/** @type {(boolean|undefined)} */
this.disabled;
}
};
......@@ -17,8 +17,7 @@ Sources.JavaScriptOutlineDialog = class extends UI.FilteredListWidget.Delegate {
this._functionItems = [];
this._selectItemCallback = selectItemCallback;
Common.formatterWorkerPool.runChunkedTask(
'javaScriptOutline', {content: uiSourceCode.workingCopy()}, this._didBuildOutlineChunk.bind(this));
Common.formatterWorkerPool.javaScriptOutline(uiSourceCode.workingCopy(), this._didBuildOutlineChunk.bind(this));
}
/**
......@@ -32,22 +31,11 @@ Sources.JavaScriptOutlineDialog = class extends UI.FilteredListWidget.Delegate {
}
/**
* @param {?MessageEvent} event
* @param {boolean} isLastChunk
* @param {!Array<!Common.FormatterWorkerPool.JSOutlineItem>} items
*/
_didBuildOutlineChunk(event) {
if (!event) {
this.dispose();
this.refresh();
return;
}
var data = /** @type {!Sources.JavaScriptOutlineDialog.MessageEventData} */ (event.data);
var chunk = data.chunk;
for (var i = 0; i < chunk.length; ++i)
this._functionItems.push(chunk[i]);
if (data.isLastChunk)
this.dispose();
_didBuildOutlineChunk(isLastChunk, items) {
this._functionItems.push(...items);
this.refresh();
}
......@@ -109,16 +97,4 @@ Sources.JavaScriptOutlineDialog = class extends UI.FilteredListWidget.Delegate {
if (!isNaN(lineNumber) && lineNumber >= 0)
this._selectItemCallback(lineNumber, this._functionItems[itemIndex].column);
}
/**
* @override
*/
dispose() {
}
};
/**
* @typedef {{isLastChunk: boolean, chunk: !Array.<!{selectorText: string, lineNumber: number, columnNumber: number}>}}
*/
Sources.JavaScriptOutlineDialog.MessageEventData;
......@@ -46,7 +46,7 @@ Sources.Formatter.format = function(contentType, mimeType, content, callback) {
};
/**
* @param {!Array.<number>} lineEndings
* @param {!Array<number>} lineEndings
* @param {number} lineNumber
* @param {number} columnNumber
* @return {number}
......@@ -57,9 +57,9 @@ Sources.Formatter.locationToPosition = function(lineEndings, lineNumber, columnN
};
/**
* @param {!Array.<number>} lineEndings
* @param {!Array<number>} lineEndings
* @param {number} position
* @return {!Array.<number>}
* @return {!Array<number>}
*/
Sources.Formatter.positionToLocation = function(lineEndings, position) {
var lineNumber = lineEndings.upperBound(position - 1);
......@@ -85,27 +85,17 @@ Sources.ScriptFormatter = class {
this._callback = callback;
this._originalContent = content;
var parameters = {
mimeType: mimeType,
content: content,
indentString: Common.moduleSetting('textEditorIndent').get()
};
Common.formatterWorkerPool.runTask('format', parameters).then(this._didFormatContent.bind(this));
Common.formatterWorkerPool.format(mimeType, content, Common.moduleSetting('textEditorIndent').get())
.then(this._didFormatContent.bind(this));
}
/**
* @param {?MessageEvent} event
* @param {!Common.FormatterWorkerPool.FormatResult} formatResult
*/
_didFormatContent(event) {
var formattedContent = '';
var mapping = [];
if (event) {
formattedContent = event.data.content;
mapping = event.data['mapping'];
}
_didFormatContent(formatResult) {
var sourceMapping = new Sources.FormatterSourceMappingImpl(
this._originalContent.computeLineEndings(), formattedContent.computeLineEndings(), mapping);
this._callback(formattedContent, sourceMapping);
this._originalContent.computeLineEndings(), formatResult.content.computeLineEndings(), formatResult.mapping);
this._callback(formatResult.content, sourceMapping);
}
};
......@@ -124,11 +114,6 @@ Sources.ScriptIdentityFormatter = class {
}
};
/**
* @typedef {{original: !Array.<number>, formatted: !Array.<number>}}
*/
Sources.FormatterMappingPayload;
/**
* @interface
*/
......@@ -184,7 +169,7 @@ Sources.FormatterSourceMappingImpl = class {
/**
* @param {!Array.<number>} originalLineEndings
* @param {!Array.<number>} formattedLineEndings
* @param {!Sources.FormatterMappingPayload} mapping
* @param {!Common.FormatterWorkerPool.FormatMapping} mapping
*/
constructor(originalLineEndings, formattedLineEndings, mapping) {
this._originalLineEndings = originalLineEndings;
......
......@@ -51,7 +51,7 @@ Sources.SourceMapNamesResolver._scopeIdentifiers = function(scope) {
var scopeText = text.extract(scopeRange);
var scopeStart = text.toSourceRange(scopeRange).offset;
var prefix = 'function fui';
return Common.formatterWorkerPool.runTask('javaScriptIdentifiers', {content: prefix + scopeText})
return Common.formatterWorkerPool.javaScriptIdentifiers(prefix + scopeText)
.then(onIdentifiers.bind(null, text, scopeStart, prefix));
}
......@@ -59,11 +59,10 @@ Sources.SourceMapNamesResolver._scopeIdentifiers = function(scope) {
* @param {!Common.Text} text
* @param {number} scopeStart
* @param {string} prefix
* @param {?MessageEvent} event
* @param {!Array<!{name: string, offset: number}>} identifiers
* @return {!Array<!Sources.SourceMapNamesResolver.Identifier>}
*/
function onIdentifiers(text, scopeStart, prefix, event) {
var identifiers = event ? /** @type {!Array<!{name: string, offset: number}>} */ (event.data) : [];
function onIdentifiers(text, scopeStart, prefix, identifiers) {
var result = [];
var cursor = new Common.TextCursor(text.lineEndings());
var promises = [];
......@@ -282,15 +281,7 @@ Sources.SourceMapNamesResolver._resolveExpression = function(
var originalText = text.extract(textRange);
if (!originalText)
return Promise.resolve('');
return Common.formatterWorkerPool.runTask('evaluatableJavaScriptSubstring', {content: originalText}).then(onResult);
}
/**
* @param {?MessageEvent} event
* @return {string}
*/
function onResult(event) {
return event ? /** @type {string} */ (event.data) : '';
return Common.formatterWorkerPool.evaluatableJavaScriptSubstring(originalText);
}
};
......
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