зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1568823 - Simplify parser.js and rename to parser-helper r=nchevobbe
Depends on D39335 Looking in details at get(), the implementation can also be simplified Differential Revision: https://phabricator.services.mozilla.com/D39338 --HG-- rename : devtools/shared/webconsole/parser.js => devtools/shared/webconsole/parser-helper.js extra : moz-landing-system : lando
This commit is contained in:
Родитель
5689ca6238
Коммит
0ab30c1e08
|
@ -11,8 +11,8 @@ const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
|||
if (!isWorker) {
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"Parser",
|
||||
"devtools/shared/webconsole/parser",
|
||||
"getSyntaxTrees",
|
||||
"devtools/shared/webconsole/parser-helper",
|
||||
true
|
||||
);
|
||||
}
|
||||
|
@ -399,13 +399,10 @@ function JSPropertyProvider({
|
|||
// Don't run this is a worker, migrating to acorn should allow this
|
||||
// to run in a worker - Bug 1217198.
|
||||
if (!isWorker && lastCompletionCharIndex > 0) {
|
||||
const parser = new Parser();
|
||||
parser.logExceptions = false;
|
||||
const parsedExpression = completionPart.slice(0, lastCompletionCharIndex);
|
||||
const syntaxTree = parser.get(parsedExpression);
|
||||
const lastTree = syntaxTree.getLastSyntaxTree();
|
||||
const lastBody =
|
||||
lastTree && lastTree.AST.body[lastTree.AST.body.length - 1];
|
||||
const syntaxTrees = getSyntaxTrees(parsedExpression);
|
||||
const lastTree = syntaxTrees[syntaxTrees.length - 1];
|
||||
const lastBody = lastTree && lastTree.body[lastTree.body.length - 1];
|
||||
|
||||
// Finding the last expression since we've sliced up until the dot.
|
||||
// If there were parse errors this won't exist.
|
||||
|
|
|
@ -27,6 +27,6 @@ ReservedWordsGenerated.inputs = ['/js/src/frontend/ReservedWords.h']
|
|||
DevToolsModules(
|
||||
'js-property-provider.js',
|
||||
'network-helper.js',
|
||||
'parser.js',
|
||||
'parser-helper.js',
|
||||
'throttle.js',
|
||||
)
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"Reflect",
|
||||
"resource://gre/modules/reflect.jsm",
|
||||
true
|
||||
);
|
||||
|
||||
/**
|
||||
* Gets a collection of parser methods for a specified source.
|
||||
*
|
||||
* @param string source
|
||||
* The source text content.
|
||||
* @param boolean logExceptions
|
||||
*/
|
||||
function getSyntaxTrees(source, logExceptions) {
|
||||
// The source may not necessarily be JS, in which case we need to extract
|
||||
// all the scripts. Fastest/easiest way is with a regular expression.
|
||||
// Don't worry, the rules of using a <script> tag are really strict,
|
||||
// this will work.
|
||||
const regexp = /<script[^>]*?(?:>([^]*?)<\/script\s*>|\/>)/gim;
|
||||
const syntaxTrees = [];
|
||||
const scriptMatches = [];
|
||||
let scriptMatch;
|
||||
|
||||
if (source.match(/^\s*</)) {
|
||||
// First non whitespace character is <, so most definitely HTML.
|
||||
while ((scriptMatch = regexp.exec(source))) {
|
||||
// Contents are captured at index 1 or nothing: Self-closing scripts
|
||||
// won't capture code content
|
||||
scriptMatches.push(scriptMatch[1] || "");
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no script matches, send the whole source directly to the
|
||||
// reflection API to generate the AST nodes.
|
||||
if (!scriptMatches.length) {
|
||||
// Reflect.parse throws when encounters a syntax error.
|
||||
try {
|
||||
syntaxTrees.push(Reflect.parse(source));
|
||||
} catch (e) {
|
||||
if (logExceptions) {
|
||||
DevToolsUtils.reportException("Parser:get", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Generate the AST nodes for each script.
|
||||
for (const script of scriptMatches) {
|
||||
// Reflect.parse throws when encounters a syntax error.
|
||||
try {
|
||||
syntaxTrees.push(Reflect.parse(script));
|
||||
} catch (e) {
|
||||
if (logExceptions) {
|
||||
DevToolsUtils.reportException("Parser:get", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return syntaxTrees;
|
||||
}
|
||||
|
||||
exports.getSyntaxTrees = getSyntaxTrees;
|
|
@ -1,153 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"Reflect",
|
||||
"resource://gre/modules/reflect.jsm",
|
||||
true
|
||||
);
|
||||
|
||||
/**
|
||||
* A JS parser using the reflection API.
|
||||
*/
|
||||
const Parser = function Parser() {
|
||||
this._cache = new Map();
|
||||
this.errors = [];
|
||||
this.logExceptions = true;
|
||||
};
|
||||
|
||||
Parser.prototype = {
|
||||
/**
|
||||
* Gets a collection of parser methods for a specified source.
|
||||
*
|
||||
* @param string source
|
||||
* The source text content.
|
||||
* @param string url [optional]
|
||||
* The source url. The AST nodes will be cached, so you can use this
|
||||
* identifier to avoid parsing the whole source again.
|
||||
*/
|
||||
get(source, url = "") {
|
||||
// Try to use the cached AST nodes, to avoid useless parsing operations.
|
||||
if (this._cache.has(url)) {
|
||||
return this._cache.get(url);
|
||||
}
|
||||
|
||||
// The source may not necessarily be JS, in which case we need to extract
|
||||
// all the scripts. Fastest/easiest way is with a regular expression.
|
||||
// Don't worry, the rules of using a <script> tag are really strict,
|
||||
// this will work.
|
||||
const regexp = /<script[^>]*?(?:>([^]*?)<\/script\s*>|\/>)/gim;
|
||||
const syntaxTrees = [];
|
||||
const scriptMatches = [];
|
||||
let scriptMatch;
|
||||
|
||||
if (source.match(/^\s*</)) {
|
||||
// First non whitespace character is <, so most definitely HTML.
|
||||
while ((scriptMatch = regexp.exec(source))) {
|
||||
// Contents are captured at index 1 or nothing: Self-closing scripts
|
||||
// won't capture code content
|
||||
scriptMatches.push(scriptMatch[1] || "");
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no script matches, send the whole source directly to the
|
||||
// reflection API to generate the AST nodes.
|
||||
if (!scriptMatches.length) {
|
||||
// Reflect.parse throws when encounters a syntax error.
|
||||
try {
|
||||
const nodes = Reflect.parse(source);
|
||||
const length = source.length;
|
||||
syntaxTrees.push(new SyntaxTree(nodes, url, length));
|
||||
} catch (e) {
|
||||
this.errors.push(e);
|
||||
if (this.logExceptions) {
|
||||
DevToolsUtils.reportException(url, e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Generate the AST nodes for each script.
|
||||
for (const script of scriptMatches) {
|
||||
// Reflect.parse throws when encounters a syntax error.
|
||||
try {
|
||||
const nodes = Reflect.parse(script);
|
||||
const offset = source.indexOf(script);
|
||||
const length = script.length;
|
||||
syntaxTrees.push(new SyntaxTree(nodes, url, length, offset));
|
||||
} catch (e) {
|
||||
this.errors.push(e);
|
||||
if (this.logExceptions) {
|
||||
DevToolsUtils.reportException(url, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const pool = new SyntaxTreesPool(syntaxTrees, url);
|
||||
|
||||
// Cache the syntax trees pool by the specified url. This is entirely
|
||||
// optional, but it's strongly encouraged to cache ASTs because
|
||||
// generating them can be costly with big/complex sources.
|
||||
if (url) {
|
||||
this._cache.set(url, pool);
|
||||
}
|
||||
|
||||
return pool;
|
||||
},
|
||||
|
||||
_cache: null,
|
||||
errors: null,
|
||||
};
|
||||
|
||||
exports.Parser = Parser;
|
||||
|
||||
/**
|
||||
* A pool handling a collection of AST nodes generated by the reflection API.
|
||||
*
|
||||
* @param object syntaxTrees
|
||||
* A collection of AST nodes generated for a source.
|
||||
* @param string url [optional]
|
||||
* The source url.
|
||||
*/
|
||||
function SyntaxTreesPool(syntaxTrees, url = "<unknown>") {
|
||||
this._trees = syntaxTrees;
|
||||
this._url = url;
|
||||
this._cache = new Map();
|
||||
}
|
||||
|
||||
SyntaxTreesPool.prototype = {
|
||||
/**
|
||||
* @return SyntaxTree
|
||||
* The last tree in this._trees
|
||||
*/
|
||||
getLastSyntaxTree() {
|
||||
return this._trees[this._trees.length - 1];
|
||||
},
|
||||
|
||||
_trees: null,
|
||||
_cache: null,
|
||||
};
|
||||
|
||||
/**
|
||||
* A collection of AST nodes generated by the reflection API.
|
||||
*
|
||||
* @param object nodes
|
||||
* The AST nodes.
|
||||
* @param string url
|
||||
* The source url.
|
||||
* @param number length
|
||||
* The total number of chars of the parsed script in the parent source.
|
||||
* @param number offset [optional]
|
||||
* The char offset of the parsed script in the parent source.
|
||||
*/
|
||||
function SyntaxTree(nodes, url, length, offset = 0) {
|
||||
this.AST = nodes;
|
||||
this.url = url;
|
||||
this.length = length;
|
||||
this.offset = offset;
|
||||
}
|
Загрузка…
Ссылка в новой задаче