mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-10 21:54:47 +08:00
DevTools: use autocomplete's possibleSideEffect to bypass throwOnSideEffect
Allow Console to evaluate without throwOnSideEffect when the entire expression meets the same strict conditions used by JSAutocomplete. Bug: 810176 Change-Id: If5c80250cd75d81eec1e495d0414903213fac930 Reviewed-on: https://chromium-review.googlesource.com/1028934 Commit-Queue: Erik Luo <luoe@chromium.org> Reviewed-by: Dmitry Gozman <dgozman@chromium.org> Reviewed-by: Joel Einbinder <einbinder@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#555142} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: fcaafdd756b1aef4f8244474e37be9ee12c75284
This commit is contained in:
@@ -81,11 +81,14 @@ Console.ConsolePrompt = class extends UI.Widget {
|
||||
return;
|
||||
}
|
||||
|
||||
// Checking for possible side effects uses the same logic as JavaScriptAutocomplete.
|
||||
// This grows the set of previewable expressions without whitelisting.
|
||||
const hasPossibleSideEffects = await Formatter.formatterWorkerPool().hasPossibleSideEffects(text);
|
||||
const options = {
|
||||
expression: SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(text),
|
||||
includeCommandLineAPI: true,
|
||||
generatePreview: true,
|
||||
throwOnSideEffect: true,
|
||||
throwOnSideEffect: hasPossibleSideEffects,
|
||||
timeout: 500
|
||||
};
|
||||
const result = await executionContext.evaluate(options, true /* userGesture */, false /* awaitPromise */);
|
||||
|
||||
@@ -49,7 +49,7 @@ Formatter.FormatterWorkerPool = class {
|
||||
|
||||
this._workerTasks.set(worker, null);
|
||||
this._processNextTask();
|
||||
task.callback(event.data ? event.data : null);
|
||||
task.callback(event.data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -239,6 +239,14 @@ Formatter.FormatterWorkerPool = class {
|
||||
return /** @type {!Promise<?{baseExpression: string, possibleSideEffects:boolean}>} */ (
|
||||
this._runTask('findLastExpression', {content}));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} content
|
||||
* @return {!Promise<boolean>}
|
||||
*/
|
||||
hasPossibleSideEffects(content) {
|
||||
return /** @type {!Promise<boolean>} */ (this._runTask('hasPossibleSideEffects', {content}));
|
||||
}
|
||||
};
|
||||
|
||||
Formatter.FormatterWorkerPool.MaxWorkers = 2;
|
||||
|
||||
@@ -87,6 +87,9 @@ self.onmessage = function(event) {
|
||||
case 'findLastExpression':
|
||||
postMessage(FormatterWorker.findLastExpression(params.content));
|
||||
break;
|
||||
case 'hasPossibleSideEffects':
|
||||
postMessage(FormatterWorker.hasPossibleSideEffects(params.content));
|
||||
break;
|
||||
default:
|
||||
console.error('Unsupport method name: ' + method);
|
||||
}
|
||||
@@ -371,9 +374,18 @@ FormatterWorker.findLastExpression = function(content) {
|
||||
let baseExpression = parsedContent.substring(baseNode.start, parsedContent.length - suffix.length);
|
||||
if (baseExpression.startsWith('{'))
|
||||
baseExpression = `(${baseExpression})`;
|
||||
const possibleSideEffects = FormatterWorker._possibleSideEffects(/** @type {!ESTree.Node} */ (baseNode));
|
||||
return {baseExpression, possibleSideEffects};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!ESTree.Node} node
|
||||
* @return {boolean}
|
||||
*/
|
||||
FormatterWorker._possibleSideEffects = function(node) {
|
||||
const sideEffectFreeTypes = new Set([
|
||||
'MemberExpression', 'Identifier', 'BinaryExpression', 'Literal', 'TemplateLiteral', 'TemplateElement',
|
||||
'ObjectExpression', 'ArrayExpression', 'Property', 'ThisExpression'
|
||||
'ObjectExpression', 'ArrayExpression', 'Property', 'ThisExpression', 'Program', 'ExpressionStatement'
|
||||
]);
|
||||
let possibleSideEffects = false;
|
||||
const sideEffectwalker = new FormatterWorker.ESTreeWalker(node => {
|
||||
@@ -382,8 +394,25 @@ FormatterWorker.findLastExpression = function(content) {
|
||||
if (possibleSideEffects)
|
||||
return FormatterWorker.ESTreeWalker.SkipSubtree;
|
||||
});
|
||||
sideEffectwalker.walk(/** @type {!ESTree.Node} */ (baseNode));
|
||||
return {baseExpression, possibleSideEffects};
|
||||
sideEffectwalker.walk(node);
|
||||
return possibleSideEffects;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @return {boolean}
|
||||
*/
|
||||
FormatterWorker.hasPossibleSideEffects = function(text) {
|
||||
if (text.length > 10000)
|
||||
return true;
|
||||
let ast = null;
|
||||
try {
|
||||
ast = acorn.parse(text, {ecmaVersion: 9});
|
||||
} catch (e) {
|
||||
}
|
||||
if (!ast)
|
||||
return true;
|
||||
return FormatterWorker._possibleSideEffects(ast);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user