зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1800629: Remove custom builders from Reflect.parse r=arai
Differential Revision: https://phabricator.services.mozilla.com/D167215
This commit is contained in:
Родитель
7a0e2975cb
Коммит
05efdc5e45
|
@ -46,7 +46,7 @@ using mozilla::DebugOnly;
|
|||
|
||||
enum ASTType {
|
||||
AST_ERROR = -1,
|
||||
#define ASTDEF(ast, str, method) ast,
|
||||
#define ASTDEF(ast, str) ast,
|
||||
#include "jsast.tbl"
|
||||
#undef ASTDEF
|
||||
AST_LIMIT
|
||||
|
@ -205,13 +205,7 @@ static const char* const unopNames[] = {
|
|||
};
|
||||
|
||||
static const char* const nodeTypeNames[] = {
|
||||
#define ASTDEF(ast, str, method) str,
|
||||
#include "jsast.tbl"
|
||||
#undef ASTDEF
|
||||
nullptr};
|
||||
|
||||
static const char* const callbackNames[] = {
|
||||
#define ASTDEF(ast, str, method) method,
|
||||
#define ASTDEF(ast, str) str,
|
||||
#include "jsast.tbl"
|
||||
#undef ASTDEF
|
||||
nullptr};
|
||||
|
@ -264,11 +258,7 @@ static bool GetPropertyDefault(JSContext* cx, HandleObject obj, HandleId id,
|
|||
enum class GeneratorStyle { None, ES6 };
|
||||
|
||||
/*
|
||||
* Builder class that constructs JavaScript AST node objects. See:
|
||||
*
|
||||
* https://developer.mozilla.org/en/SpiderMonkey/Parser_API
|
||||
*
|
||||
* Bug 569487: generalize builder interface
|
||||
* Builder class that constructs JavaScript AST node objects.
|
||||
*/
|
||||
class NodeBuilder {
|
||||
using CallbackArray = RootedValueArray<AST_LIMIT>;
|
||||
|
@ -276,24 +266,15 @@ class NodeBuilder {
|
|||
JSContext* cx;
|
||||
FrontendContext* fc;
|
||||
frontend::Parser<frontend::FullParseHandler, char16_t>* parser;
|
||||
bool saveLoc; /* save source location information? */
|
||||
char const* src; /* source filename or null */
|
||||
RootedValue srcval; /* source filename JS value or null */
|
||||
CallbackArray callbacks; /* user-specified callbacks */
|
||||
RootedValue userv; /* user-specified builder object or null */
|
||||
bool saveLoc; /* save source location information? */
|
||||
char const* src; /* source filename or null */
|
||||
RootedValue srcval; /* source filename JS value or null */
|
||||
|
||||
public:
|
||||
NodeBuilder(JSContext* c, FrontendContext* f, bool l, char const* s)
|
||||
: cx(c),
|
||||
fc(f),
|
||||
parser(nullptr),
|
||||
saveLoc(l),
|
||||
src(s),
|
||||
srcval(c),
|
||||
callbacks(cx),
|
||||
userv(c) {}
|
||||
: cx(c), fc(f), parser(nullptr), saveLoc(l), src(s), srcval(c) {}
|
||||
|
||||
[[nodiscard]] bool init(HandleObject userobj = nullptr) {
|
||||
[[nodiscard]] bool init() {
|
||||
if (src) {
|
||||
if (!atomValue(src, &srcval)) {
|
||||
return false;
|
||||
|
@ -302,43 +283,6 @@ class NodeBuilder {
|
|||
srcval.setNull();
|
||||
}
|
||||
|
||||
if (!userobj) {
|
||||
userv.setNull();
|
||||
for (unsigned i = 0; i < AST_LIMIT; i++) {
|
||||
callbacks[i].setNull();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
userv.setObject(*userobj);
|
||||
|
||||
RootedValue nullVal(cx, NullValue());
|
||||
RootedValue funv(cx);
|
||||
for (unsigned i = 0; i < AST_LIMIT; i++) {
|
||||
const char* name = callbackNames[i];
|
||||
Rooted<JSAtom*> atom(cx, Atomize(cx, name, strlen(name)));
|
||||
if (!atom) {
|
||||
return false;
|
||||
}
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
if (!GetPropertyDefault(cx, userobj, id, nullVal, &funv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (funv.isNullOrUndefined()) {
|
||||
callbacks[i].setNull();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!funv.isObject() || !funv.toObject().is<JSFunction>()) {
|
||||
ReportValueError(cx, JSMSG_NOT_FUNCTION, JSDVG_SEARCH_STACK, funv,
|
||||
nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
callbacks[i].set(funv);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -347,56 +291,6 @@ class NodeBuilder {
|
|||
}
|
||||
|
||||
private:
|
||||
[[nodiscard]] bool callbackHelper(HandleValue fun, const InvokeArgs& args,
|
||||
size_t i, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
// The end of the implementation of callback(). All arguments except
|
||||
// loc have already been stored in range [0, i).
|
||||
if (saveLoc) {
|
||||
if (!newNodeLoc(pos, args[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return js::Call(cx, fun, userv, args, dst);
|
||||
}
|
||||
|
||||
// Helper function for callback(). Note that all Arguments must be types
|
||||
// that convert to HandleValue, so this isn't as template-y as it seems,
|
||||
// just variadic.
|
||||
template <typename... Arguments>
|
||||
[[nodiscard]] bool callbackHelper(HandleValue fun, const InvokeArgs& args,
|
||||
size_t i, HandleValue head,
|
||||
Arguments&&... tail) {
|
||||
// Recursive loop to store the arguments into args. This eventually
|
||||
// bottoms out in a call to the non-template callbackHelper() above.
|
||||
args[i].set(head);
|
||||
return callbackHelper(fun, args, i + 1, std::forward<Arguments>(tail)...);
|
||||
}
|
||||
|
||||
// Invoke a user-defined callback. The actual signature is:
|
||||
//
|
||||
// bool callback(HandleValue fun, HandleValue... args, TokenPos* pos,
|
||||
// MutableHandleValue dst);
|
||||
template <typename... Arguments>
|
||||
[[nodiscard]] bool callback(HandleValue fun, Arguments&&... args) {
|
||||
InvokeArgs iargs(cx);
|
||||
if (!iargs.init(cx, sizeof...(args) - 2 + size_t(saveLoc))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return callbackHelper(fun, iargs, 0, std::forward<Arguments>(args)...);
|
||||
}
|
||||
|
||||
// WARNING: Returning a Handle is non-standard, but it works in this case
|
||||
// because both |v| and |UndefinedHandleValue| are definitely rooted on a
|
||||
// previous stack frame (i.e. we're just choosing between two
|
||||
// already-rooted values).
|
||||
HandleValue opt(HandleValue v) {
|
||||
MOZ_ASSERT_IF(v.isMagic(), v.whyMagic() == JS_SERIALIZE_NO_NODE);
|
||||
return v.isMagic(JS_SERIALIZE_NO_NODE) ? JS::UndefinedHandleValue : v;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool atomValue(const char* s, MutableHandleValue dst) {
|
||||
/*
|
||||
* Bug 575416: instead of Atomize, lookup constant atoms in tbl file
|
||||
|
@ -465,11 +359,6 @@ class NodeBuilder {
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[type]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, array, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(type, pos, propName, array, dst);
|
||||
}
|
||||
|
||||
|
@ -892,93 +781,48 @@ bool NodeBuilder::blockStatement(NodeVector& elts, TokenPos* pos,
|
|||
|
||||
bool NodeBuilder::expressionStatement(HandleValue expr, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_EXPR_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, expr, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_EXPR_STMT, pos, "expression", expr, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::emptyStatement(TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_EMPTY_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_EMPTY_STMT, pos, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::ifStatement(HandleValue test, HandleValue cons,
|
||||
HandleValue alt, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_IF_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, test, cons, opt(alt), pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_IF_STMT, pos, "test", test, "consequent", cons,
|
||||
"alternate", alt, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::breakStatement(HandleValue label, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_BREAK_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, opt(label), pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_BREAK_STMT, pos, "label", label, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::continueStatement(HandleValue label, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_CONTINUE_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, opt(label), pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_CONTINUE_STMT, pos, "label", label, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::labeledStatement(HandleValue label, HandleValue stmt,
|
||||
TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_LAB_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, label, stmt, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_LAB_STMT, pos, "label", label, "body", stmt, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::throwStatement(HandleValue arg, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_THROW_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, arg, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_THROW_STMT, pos, "argument", arg, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::returnStatement(HandleValue arg, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_RETURN_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, opt(arg), pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_RETURN_STMT, pos, "argument", arg, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::forStatement(HandleValue init, HandleValue test,
|
||||
HandleValue update, HandleValue stmt,
|
||||
TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_FOR_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, opt(init), opt(test), opt(update), stmt, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_FOR_STMT, pos, "init", init, "test", test, "update",
|
||||
update, "body", stmt, dst);
|
||||
}
|
||||
|
@ -986,13 +830,6 @@ bool NodeBuilder::forStatement(HandleValue init, HandleValue test,
|
|||
bool NodeBuilder::forInStatement(HandleValue var, HandleValue expr,
|
||||
HandleValue stmt, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_FOR_IN_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
RootedValue isForEach(
|
||||
cx, JS::FalseValue()); // obsolete E4X `for each` statement
|
||||
return callback(cb, var, expr, stmt, isForEach, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_FOR_IN_STMT, pos, "left", var, "right", expr, "body", stmt,
|
||||
dst);
|
||||
}
|
||||
|
@ -1000,42 +837,22 @@ bool NodeBuilder::forInStatement(HandleValue var, HandleValue expr,
|
|||
bool NodeBuilder::forOfStatement(HandleValue var, HandleValue expr,
|
||||
HandleValue stmt, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_FOR_OF_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, var, expr, stmt, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_FOR_OF_STMT, pos, "left", var, "right", expr, "body", stmt,
|
||||
dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::withStatement(HandleValue expr, HandleValue stmt,
|
||||
TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_WITH_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, expr, stmt, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_WITH_STMT, pos, "object", expr, "body", stmt, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::whileStatement(HandleValue test, HandleValue stmt,
|
||||
TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_WHILE_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, test, stmt, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_WHILE_STMT, pos, "test", test, "body", stmt, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::doWhileStatement(HandleValue stmt, HandleValue test,
|
||||
TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_DO_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, stmt, test, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_DO_STMT, pos, "body", stmt, "test", test, dst);
|
||||
}
|
||||
|
||||
|
@ -1048,12 +865,6 @@ bool NodeBuilder::switchStatement(HandleValue disc, NodeVector& elts,
|
|||
}
|
||||
|
||||
RootedValue lexicalVal(cx, BooleanValue(lexical));
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_SWITCH_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, disc, array, lexicalVal, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_SWITCH_STMT, pos, "discriminant", disc, "cases", array,
|
||||
"lexical", lexicalVal, dst);
|
||||
}
|
||||
|
@ -1061,21 +872,11 @@ bool NodeBuilder::switchStatement(HandleValue disc, NodeVector& elts,
|
|||
bool NodeBuilder::tryStatement(HandleValue body, HandleValue handler,
|
||||
HandleValue finally, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_TRY_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, body, handler, opt(finally), pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_TRY_STMT, pos, "block", body, "handler", handler,
|
||||
"finalizer", finally, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::debuggerStatement(TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_DEBUGGER_STMT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_DEBUGGER_STMT, pos, dst);
|
||||
}
|
||||
|
||||
|
@ -1089,11 +890,6 @@ bool NodeBuilder::binaryExpression(BinaryOperator op, HandleValue left,
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_BINARY_EXPR]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, opName, left, right, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_BINARY_EXPR, pos, "operator", opName, "left", left,
|
||||
"right", right, dst);
|
||||
}
|
||||
|
@ -1107,11 +903,6 @@ bool NodeBuilder::unaryExpression(UnaryOperator unop, HandleValue expr,
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_UNARY_EXPR]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, opName, expr, pos, dst);
|
||||
}
|
||||
|
||||
RootedValue trueVal(cx, BooleanValue(true));
|
||||
return newNode(AST_UNARY_EXPR, pos, "operator", opName, "argument", expr,
|
||||
"prefix", trueVal, dst);
|
||||
|
@ -1127,11 +918,6 @@ bool NodeBuilder::assignmentExpression(AssignmentOperator aop, HandleValue lhs,
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_ASSIGN_EXPR]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, opName, lhs, rhs, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_ASSIGN_EXPR, pos, "operator", opName, "left", lhs, "right",
|
||||
rhs, dst);
|
||||
}
|
||||
|
@ -1145,11 +931,6 @@ bool NodeBuilder::updateExpression(HandleValue expr, bool incr, bool prefix,
|
|||
|
||||
RootedValue prefixVal(cx, BooleanValue(prefix));
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_UPDATE_EXPR]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, expr, opName, prefixVal, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_UPDATE_EXPR, pos, "operator", opName, "argument", expr,
|
||||
"prefix", prefixVal, dst);
|
||||
}
|
||||
|
@ -1178,11 +959,6 @@ bool NodeBuilder::logicalExpression(ParseNodeKind pnk, HandleValue left,
|
|||
MOZ_CRASH("Unexpected ParseNodeKind: Must be `Or`, `And`, or `Coalesce`");
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_LOGICAL_EXPR]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, opName, left, right, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_LOGICAL_EXPR, pos, "operator", opName, "left", left,
|
||||
"right", right, dst);
|
||||
}
|
||||
|
@ -1190,11 +966,6 @@ bool NodeBuilder::logicalExpression(ParseNodeKind pnk, HandleValue left,
|
|||
bool NodeBuilder::conditionalExpression(HandleValue test, HandleValue cons,
|
||||
HandleValue alt, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_COND_EXPR]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, test, cons, alt, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_COND_EXPR, pos, "test", test, "consequent", cons,
|
||||
"alternate", alt, dst);
|
||||
}
|
||||
|
@ -1212,11 +983,6 @@ bool NodeBuilder::callExpression(HandleValue callee, NodeVector& args,
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_CALL_EXPR]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, callee, array, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(isOptional ? AST_OPT_CALL_EXPR : AST_CALL_EXPR, pos, "callee",
|
||||
callee, "arguments", array, dst);
|
||||
}
|
||||
|
@ -1228,11 +994,6 @@ bool NodeBuilder::newExpression(HandleValue callee, NodeVector& args,
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_NEW_EXPR]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, callee, array, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_NEW_EXPR, pos, "callee", callee, "arguments", array, dst);
|
||||
}
|
||||
|
||||
|
@ -1242,11 +1003,6 @@ bool NodeBuilder::memberExpression(bool computed, HandleValue expr,
|
|||
bool isOptional /* = false */) {
|
||||
RootedValue computedVal(cx, BooleanValue(computed));
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_MEMBER_EXPR]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, computedVal, expr, member, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(isOptional ? AST_OPT_MEMBER_EXPR : AST_MEMBER_EXPR, pos,
|
||||
"object", expr, "property", member, "computed", computedVal,
|
||||
dst);
|
||||
|
@ -1319,22 +1075,12 @@ bool NodeBuilder::propertyPattern(HandleValue key, HandleValue patt,
|
|||
|
||||
RootedValue isShorthandVal(cx, BooleanValue(isShorthand));
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_PROP_PATT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, key, patt, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_PROP_PATT, pos, "key", key, "value", patt, "kind",
|
||||
kindName, "shorthand", isShorthandVal, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::prototypeMutation(HandleValue val, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_PROTOTYPEMUTATION]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, val, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_PROTOTYPEMUTATION, pos, "value", val, dst);
|
||||
}
|
||||
|
||||
|
@ -1353,11 +1099,6 @@ bool NodeBuilder::propertyInitializer(HandleValue key, HandleValue val,
|
|||
RootedValue isShorthandVal(cx, BooleanValue(isShorthand));
|
||||
RootedValue isMethodVal(cx, BooleanValue(isMethod));
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_PROPERTY]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, kindName, key, val, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_PROPERTY, pos, "key", key, "value", val, "kind", kindName,
|
||||
"method", isMethodVal, "shorthand", isShorthandVal, dst);
|
||||
}
|
||||
|
@ -1380,19 +1121,12 @@ bool NodeBuilder::tupleExpression(NodeVector& elts, TokenPos* pos,
|
|||
#endif
|
||||
|
||||
bool NodeBuilder::thisExpression(TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_THIS_EXPR]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_THIS_EXPR, pos, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::yieldExpression(HandleValue arg, YieldKind kind,
|
||||
TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_YIELD_EXPR]);
|
||||
RootedValue delegateVal(cx);
|
||||
|
||||
switch (kind) {
|
||||
case Delegating:
|
||||
delegateVal = BooleanValue(true);
|
||||
|
@ -1401,10 +1135,6 @@ bool NodeBuilder::yieldExpression(HandleValue arg, YieldKind kind,
|
|||
delegateVal = BooleanValue(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, opt(arg), delegateVal, pos, dst);
|
||||
}
|
||||
return newNode(AST_YIELD_EXPR, pos, "argument", arg, "delegate", delegateVal,
|
||||
dst);
|
||||
}
|
||||
|
@ -1416,22 +1146,12 @@ bool NodeBuilder::moduleRequest(HandleValue moduleSpec, NodeVector& assertions,
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_MODULE_REQUEST]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, array, moduleSpec, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_MODULE_REQUEST, pos, "source", moduleSpec, "assertions",
|
||||
array, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::importAssertion(HandleValue key, HandleValue value,
|
||||
TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_IMPORT_ASSERTION]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, key, value, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_IMPORT_ASSERTION, pos, "key", key, "value", value, dst);
|
||||
}
|
||||
|
||||
|
@ -1442,11 +1162,6 @@ bool NodeBuilder::importDeclaration(NodeVector& elts, HandleValue moduleRequest,
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_IMPORT_DECL]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, array, moduleRequest, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_IMPORT_DECL, pos, "specifiers", array, "moduleRequest",
|
||||
moduleRequest, dst);
|
||||
}
|
||||
|
@ -1454,11 +1169,6 @@ bool NodeBuilder::importDeclaration(NodeVector& elts, HandleValue moduleRequest,
|
|||
bool NodeBuilder::importSpecifier(HandleValue importName,
|
||||
HandleValue bindingName, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_IMPORT_SPEC]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, importName, bindingName, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_IMPORT_SPEC, pos, "id", importName, "name", bindingName,
|
||||
dst);
|
||||
}
|
||||
|
@ -1466,11 +1176,6 @@ bool NodeBuilder::importSpecifier(HandleValue importName,
|
|||
bool NodeBuilder::importNamespaceSpecifier(HandleValue bindingName,
|
||||
TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_IMPORT_NAMESPACE_SPEC]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, bindingName, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_IMPORT_NAMESPACE_SPEC, pos, "name", bindingName, dst);
|
||||
}
|
||||
|
||||
|
@ -1483,12 +1188,6 @@ bool NodeBuilder::exportDeclaration(HandleValue decl, NodeVector& elts,
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_EXPORT_DECL]);
|
||||
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, decl, array, moduleRequest, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_EXPORT_DECL, pos, "declaration", decl, "specifiers", array,
|
||||
"moduleRequest", moduleRequest, "isDefault", isDefault, dst);
|
||||
}
|
||||
|
@ -1496,11 +1195,6 @@ bool NodeBuilder::exportDeclaration(HandleValue decl, NodeVector& elts,
|
|||
bool NodeBuilder::exportSpecifier(HandleValue bindingName,
|
||||
HandleValue exportName, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_EXPORT_SPEC]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, bindingName, exportName, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_EXPORT_SPEC, pos, "id", bindingName, "name", exportName,
|
||||
dst);
|
||||
}
|
||||
|
@ -1508,20 +1202,10 @@ bool NodeBuilder::exportSpecifier(HandleValue bindingName,
|
|||
bool NodeBuilder::exportNamespaceSpecifier(HandleValue exportName,
|
||||
TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_EXPORT_NAMESPACE_SPEC]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, exportName, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_EXPORT_NAMESPACE_SPEC, pos, "name", exportName, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::exportBatchSpecifier(TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_EXPORT_BATCH_SPEC]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_EXPORT_BATCH_SPEC, pos, dst);
|
||||
}
|
||||
|
||||
|
@ -1537,22 +1221,12 @@ bool NodeBuilder::variableDeclaration(NodeVector& elts, VarDeclKind kind,
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_VAR_DECL]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, kindName, array, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_VAR_DECL, pos, "kind", kindName, "declarations", array,
|
||||
dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::variableDeclarator(HandleValue id, HandleValue init,
|
||||
TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_VAR_DTOR]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, id, opt(init), pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_VAR_DTOR, pos, "id", id, "init", init, dst);
|
||||
}
|
||||
|
||||
|
@ -1563,41 +1237,21 @@ bool NodeBuilder::switchCase(HandleValue expr, NodeVector& elts, TokenPos* pos,
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_CASE]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, opt(expr), array, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_CASE, pos, "test", expr, "consequent", array, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::catchClause(HandleValue var, HandleValue body, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_CATCH]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, opt(var), body, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_CATCH, pos, "param", var, "body", body, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::literal(HandleValue val, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_LITERAL]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, val, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_LITERAL, pos, "value", val, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::identifier(HandleValue name, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_IDENTIFIER]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, name, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_IDENTIFIER, pos, "name", name, dst);
|
||||
}
|
||||
|
||||
|
@ -1629,12 +1283,6 @@ bool NodeBuilder::function(ASTType type, TokenPos* pos, HandleValue id,
|
|||
RootedValue isAsyncVal(cx, BooleanValue(isAsync));
|
||||
RootedValue isExpressionVal(cx, BooleanValue(isExpression));
|
||||
|
||||
RootedValue cb(cx, callbacks[type]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, opt(id), array, body, isGeneratorVal, isExpressionVal,
|
||||
pos, dst);
|
||||
}
|
||||
|
||||
if (isGenerator) {
|
||||
MOZ_ASSERT(generatorStyle == GeneratorStyle::ES6);
|
||||
JSAtom* styleStr = Atomize(cx, "es6", 3);
|
||||
|
@ -1665,32 +1313,17 @@ bool NodeBuilder::classMethod(HandleValue name, HandleValue body, PropKind kind,
|
|||
}
|
||||
|
||||
RootedValue isStaticVal(cx, BooleanValue(isStatic));
|
||||
RootedValue cb(cx, callbacks[AST_CLASS_METHOD]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, kindName, name, body, isStaticVal, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_CLASS_METHOD, pos, "name", name, "body", body, "kind",
|
||||
kindName, "static", isStaticVal, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::classField(HandleValue name, HandleValue initializer,
|
||||
TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_CLASS_FIELD]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, name, initializer, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_CLASS_FIELD, pos, "name", name, "init", initializer, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::staticClassBlock(HandleValue body, TokenPos* pos,
|
||||
MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_STATIC_CLASS_BLOCK]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, body, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_STATIC_CLASS_BLOCK, pos, "body", body, dst);
|
||||
}
|
||||
|
||||
|
@ -1702,22 +1335,12 @@ bool NodeBuilder::classDefinition(bool expr, HandleValue name,
|
|||
HandleValue heritage, HandleValue block,
|
||||
TokenPos* pos, MutableHandleValue dst) {
|
||||
ASTType type = expr ? AST_CLASS_EXPR : AST_CLASS_STMT;
|
||||
RootedValue cb(cx, callbacks[type]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, name, heritage, block, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(type, pos, "id", name, "superClass", heritage, "body", block,
|
||||
dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::metaProperty(HandleValue meta, HandleValue property,
|
||||
TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_METAPROPERTY]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, meta, property, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_METAPROPERTY, pos, "meta", meta, "property", property,
|
||||
dst);
|
||||
}
|
||||
|
@ -1729,20 +1352,10 @@ bool NodeBuilder::callImportExpression(HandleValue ident, NodeVector& args,
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedValue cb(cx, callbacks[AST_CALL_IMPORT]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, ident, array, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_CALL_IMPORT, pos, "ident", ident, "arguments", array, dst);
|
||||
}
|
||||
|
||||
bool NodeBuilder::super(TokenPos* pos, MutableHandleValue dst) {
|
||||
RootedValue cb(cx, callbacks[AST_SUPER]);
|
||||
if (!cb.isNull()) {
|
||||
return callback(cb, pos, dst);
|
||||
}
|
||||
|
||||
return newNode(AST_SUPER, pos, dst);
|
||||
}
|
||||
|
||||
|
@ -1875,7 +1488,7 @@ class ASTSerializer {
|
|||
{
|
||||
}
|
||||
|
||||
bool init(HandleObject userobj) { return builder.init(userobj); }
|
||||
bool init() { return builder.init(); }
|
||||
|
||||
void setParser(frontend::Parser<frontend::FullParseHandler, char16_t>* p) {
|
||||
parser = p;
|
||||
|
@ -3991,7 +3604,6 @@ static bool reflect_parse(JSContext* cx, uint32_t argc, Value* vp) {
|
|||
UniqueChars filename;
|
||||
uint32_t lineno = 1;
|
||||
bool loc = true;
|
||||
RootedObject builder(cx);
|
||||
ParseGoal target = ParseGoal::Script;
|
||||
|
||||
RootedValue arg(cx, args.get(1));
|
||||
|
@ -4045,22 +3657,6 @@ static bool reflect_parse(JSContext* cx, uint32_t argc, Value* vp) {
|
|||
}
|
||||
}
|
||||
|
||||
/* config.builder */
|
||||
RootedId builderId(cx, NameToId(cx->names().builder));
|
||||
RootedValue nullVal(cx, NullValue());
|
||||
if (!GetPropertyDefault(cx, config, builderId, nullVal, &prop)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!prop.isNullOrUndefined()) {
|
||||
if (!prop.isObject()) {
|
||||
ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, prop,
|
||||
nullptr, "not an object");
|
||||
return false;
|
||||
}
|
||||
builder = &prop.toObject();
|
||||
}
|
||||
|
||||
/* config.target */
|
||||
RootedId targetId(cx, NameToId(cx->names().target));
|
||||
RootedValue scriptVal(cx, StringValue(cx->names().script));
|
||||
|
@ -4096,10 +3692,9 @@ static bool reflect_parse(JSContext* cx, uint32_t argc, Value* vp) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Extract the builder methods first to report errors before parsing. */
|
||||
AutoReportFrontendContext fc(cx);
|
||||
ASTSerializer serialize(cx, &fc, loc, filename.get(), lineno);
|
||||
if (!serialize.init(builder)) {
|
||||
if (!serialize.init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
154
js/src/jsast.tbl
154
js/src/jsast.tbl
|
@ -6,90 +6,90 @@
|
|||
|
||||
/* AST_ERROR = -1 */
|
||||
|
||||
ASTDEF(AST_PROGRAM, "Program", "program")
|
||||
ASTDEF(AST_PROGRAM, "Program")
|
||||
|
||||
ASTDEF(AST_IDENTIFIER, "Identifier", "identifier")
|
||||
ASTDEF(AST_LITERAL, "Literal", "literal")
|
||||
ASTDEF(AST_PROPERTY, "Property", "property")
|
||||
ASTDEF(AST_PROTOTYPEMUTATION, "PrototypeMutation", "prototypeMutation")
|
||||
ASTDEF(AST_IDENTIFIER, "Identifier")
|
||||
ASTDEF(AST_LITERAL, "Literal")
|
||||
ASTDEF(AST_PROPERTY, "Property")
|
||||
ASTDEF(AST_PROTOTYPEMUTATION, "PrototypeMutation")
|
||||
|
||||
ASTDEF(AST_MODULE_DECL, "ModuleDeclaration", "moduleDeclaration")
|
||||
ASTDEF(AST_FUNC_DECL, "FunctionDeclaration", "functionDeclaration")
|
||||
ASTDEF(AST_VAR_DECL, "VariableDeclaration", "variableDeclaration")
|
||||
ASTDEF(AST_VAR_DTOR, "VariableDeclarator", "variableDeclarator")
|
||||
ASTDEF(AST_MODULE_DECL, "ModuleDeclaration")
|
||||
ASTDEF(AST_FUNC_DECL, "FunctionDeclaration")
|
||||
ASTDEF(AST_VAR_DECL, "VariableDeclaration")
|
||||
ASTDEF(AST_VAR_DTOR, "VariableDeclarator")
|
||||
|
||||
ASTDEF(AST_LIST_EXPR, "SequenceExpression", "sequenceExpression")
|
||||
ASTDEF(AST_COND_EXPR, "ConditionalExpression", "conditionalExpression")
|
||||
ASTDEF(AST_UNARY_EXPR, "UnaryExpression", "unaryExpression")
|
||||
ASTDEF(AST_BINARY_EXPR, "BinaryExpression", "binaryExpression")
|
||||
ASTDEF(AST_ASSIGN_EXPR, "AssignmentExpression", "assignmentExpression")
|
||||
ASTDEF(AST_LOGICAL_EXPR, "LogicalExpression", "logicalExpression")
|
||||
ASTDEF(AST_UPDATE_EXPR, "UpdateExpression", "updateExpression")
|
||||
ASTDEF(AST_NEW_EXPR, "NewExpression", "newExpression")
|
||||
ASTDEF(AST_CALL_EXPR, "CallExpression", "callExpression")
|
||||
ASTDEF(AST_OPT_CALL_EXPR, "OptionalCallExpression", "optionalCallExpression")
|
||||
ASTDEF(AST_MEMBER_EXPR, "MemberExpression", "memberExpression")
|
||||
ASTDEF(AST_OPT_MEMBER_EXPR, "OptionalMemberExpression", "optionalMemberExpression")
|
||||
ASTDEF(AST_FUNC_EXPR, "FunctionExpression", "functionExpression")
|
||||
ASTDEF(AST_ARROW_EXPR, "ArrowFunctionExpression", "arrowFunctionExpression")
|
||||
ASTDEF(AST_ARRAY_EXPR, "ArrayExpression", "arrayExpression")
|
||||
ASTDEF(AST_DELETE_OPTIONAL_EXPR, "DeleteOptionalExpression", "deleteOptionalExpression")
|
||||
ASTDEF(AST_OPTIONAL_EXPR, "OptionalExpression", "optionalExpression")
|
||||
ASTDEF(AST_SPREAD_EXPR, "SpreadExpression", "spreadExpression")
|
||||
ASTDEF(AST_OBJECT_EXPR, "ObjectExpression", "objectExpression")
|
||||
ASTDEF(AST_THIS_EXPR, "ThisExpression", "thisExpression")
|
||||
ASTDEF(AST_YIELD_EXPR, "YieldExpression", "yieldExpression")
|
||||
ASTDEF(AST_CLASS_EXPR, "ClassExpression", "classExpression")
|
||||
ASTDEF(AST_METAPROPERTY, "MetaProperty", "metaProperty")
|
||||
ASTDEF(AST_SUPER, "Super", "super")
|
||||
ASTDEF(AST_CALL_IMPORT, "CallImport", "callImport")
|
||||
ASTDEF(AST_LIST_EXPR, "SequenceExpression")
|
||||
ASTDEF(AST_COND_EXPR, "ConditionalExpression")
|
||||
ASTDEF(AST_UNARY_EXPR, "UnaryExpression")
|
||||
ASTDEF(AST_BINARY_EXPR, "BinaryExpression")
|
||||
ASTDEF(AST_ASSIGN_EXPR, "AssignmentExpression")
|
||||
ASTDEF(AST_LOGICAL_EXPR, "LogicalExpression")
|
||||
ASTDEF(AST_UPDATE_EXPR, "UpdateExpression")
|
||||
ASTDEF(AST_NEW_EXPR, "NewExpression")
|
||||
ASTDEF(AST_CALL_EXPR, "CallExpression")
|
||||
ASTDEF(AST_OPT_CALL_EXPR, "OptionalCallExpression")
|
||||
ASTDEF(AST_MEMBER_EXPR, "MemberExpression")
|
||||
ASTDEF(AST_OPT_MEMBER_EXPR, "OptionalMemberExpression")
|
||||
ASTDEF(AST_FUNC_EXPR, "FunctionExpression")
|
||||
ASTDEF(AST_ARROW_EXPR, "ArrowFunctionExpression")
|
||||
ASTDEF(AST_ARRAY_EXPR, "ArrayExpression")
|
||||
ASTDEF(AST_DELETE_OPTIONAL_EXPR, "DeleteOptionalExpression")
|
||||
ASTDEF(AST_OPTIONAL_EXPR, "OptionalExpression")
|
||||
ASTDEF(AST_SPREAD_EXPR, "SpreadExpression")
|
||||
ASTDEF(AST_OBJECT_EXPR, "ObjectExpression")
|
||||
ASTDEF(AST_THIS_EXPR, "ThisExpression")
|
||||
ASTDEF(AST_YIELD_EXPR, "YieldExpression")
|
||||
ASTDEF(AST_CLASS_EXPR, "ClassExpression")
|
||||
ASTDEF(AST_METAPROPERTY, "MetaProperty")
|
||||
ASTDEF(AST_SUPER, "Super")
|
||||
ASTDEF(AST_CALL_IMPORT, "CallImport")
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
ASTDEF(AST_RECORD_EXPR, "RecordExpression", "recordExpression")
|
||||
ASTDEF(AST_TUPLE_EXPR, "TupleExpression", "tupleExpression")
|
||||
ASTDEF(AST_RECORD_EXPR, "RecordExpression")
|
||||
ASTDEF(AST_TUPLE_EXPR, "TupleExpression")
|
||||
#endif
|
||||
|
||||
ASTDEF(AST_EMPTY_STMT, "EmptyStatement", "emptyStatement")
|
||||
ASTDEF(AST_BLOCK_STMT, "BlockStatement", "blockStatement")
|
||||
ASTDEF(AST_EXPR_STMT, "ExpressionStatement", "expressionStatement")
|
||||
ASTDEF(AST_LAB_STMT, "LabeledStatement", "labeledStatement")
|
||||
ASTDEF(AST_IF_STMT, "IfStatement", "ifStatement")
|
||||
ASTDEF(AST_SWITCH_STMT, "SwitchStatement", "switchStatement")
|
||||
ASTDEF(AST_WHILE_STMT, "WhileStatement", "whileStatement")
|
||||
ASTDEF(AST_DO_STMT, "DoWhileStatement", "doWhileStatement")
|
||||
ASTDEF(AST_FOR_STMT, "ForStatement", "forStatement")
|
||||
ASTDEF(AST_FOR_IN_STMT, "ForInStatement", "forInStatement")
|
||||
ASTDEF(AST_FOR_OF_STMT, "ForOfStatement", "forOfStatement")
|
||||
ASTDEF(AST_BREAK_STMT, "BreakStatement", "breakStatement")
|
||||
ASTDEF(AST_CONTINUE_STMT, "ContinueStatement", "continueStatement")
|
||||
ASTDEF(AST_WITH_STMT, "WithStatement", "withStatement")
|
||||
ASTDEF(AST_RETURN_STMT, "ReturnStatement", "returnStatement")
|
||||
ASTDEF(AST_TRY_STMT, "TryStatement", "tryStatement")
|
||||
ASTDEF(AST_THROW_STMT, "ThrowStatement", "throwStatement")
|
||||
ASTDEF(AST_DEBUGGER_STMT, "DebuggerStatement", "debuggerStatement")
|
||||
ASTDEF(AST_LET_STMT, "LetStatement", "letStatement")
|
||||
ASTDEF(AST_MODULE_REQUEST, "ModuleRequest", "moduleRequest")
|
||||
ASTDEF(AST_IMPORT_ASSERTION, "ImportAssertion", "importAssertion")
|
||||
ASTDEF(AST_IMPORT_DECL, "ImportDeclaration", "importDeclaration")
|
||||
ASTDEF(AST_IMPORT_SPEC, "ImportSpecifier", "importSpecifier")
|
||||
ASTDEF(AST_IMPORT_NAMESPACE_SPEC, "ImportNamespaceSpecifier", "importNamespaceSpecifier")
|
||||
ASTDEF(AST_EXPORT_DECL, "ExportDeclaration", "exportDeclaration")
|
||||
ASTDEF(AST_EXPORT_SPEC, "ExportSpecifier", "exportSpecifier")
|
||||
ASTDEF(AST_EXPORT_NAMESPACE_SPEC, "ExportNamespaceSpecifier", "exportNamespaceSpecifier")
|
||||
ASTDEF(AST_EXPORT_BATCH_SPEC, "ExportBatchSpecifier", "exportBatchSpecifier")
|
||||
ASTDEF(AST_EMPTY_STMT, "EmptyStatement")
|
||||
ASTDEF(AST_BLOCK_STMT, "BlockStatement")
|
||||
ASTDEF(AST_EXPR_STMT, "ExpressionStatement")
|
||||
ASTDEF(AST_LAB_STMT, "LabeledStatement")
|
||||
ASTDEF(AST_IF_STMT, "IfStatement")
|
||||
ASTDEF(AST_SWITCH_STMT, "SwitchStatement")
|
||||
ASTDEF(AST_WHILE_STMT, "WhileStatement")
|
||||
ASTDEF(AST_DO_STMT, "DoWhileStatement")
|
||||
ASTDEF(AST_FOR_STMT, "ForStatement")
|
||||
ASTDEF(AST_FOR_IN_STMT, "ForInStatement")
|
||||
ASTDEF(AST_FOR_OF_STMT, "ForOfStatement")
|
||||
ASTDEF(AST_BREAK_STMT, "BreakStatement")
|
||||
ASTDEF(AST_CONTINUE_STMT, "ContinueStatement")
|
||||
ASTDEF(AST_WITH_STMT, "WithStatement")
|
||||
ASTDEF(AST_RETURN_STMT, "ReturnStatement")
|
||||
ASTDEF(AST_TRY_STMT, "TryStatement")
|
||||
ASTDEF(AST_THROW_STMT, "ThrowStatement")
|
||||
ASTDEF(AST_DEBUGGER_STMT, "DebuggerStatement")
|
||||
ASTDEF(AST_LET_STMT, "LetStatement")
|
||||
ASTDEF(AST_MODULE_REQUEST, "ModuleRequest")
|
||||
ASTDEF(AST_IMPORT_ASSERTION, "ImportAssertion")
|
||||
ASTDEF(AST_IMPORT_DECL, "ImportDeclaration")
|
||||
ASTDEF(AST_IMPORT_SPEC, "ImportSpecifier")
|
||||
ASTDEF(AST_IMPORT_NAMESPACE_SPEC, "ImportNamespaceSpecifier")
|
||||
ASTDEF(AST_EXPORT_DECL, "ExportDeclaration")
|
||||
ASTDEF(AST_EXPORT_SPEC, "ExportSpecifier")
|
||||
ASTDEF(AST_EXPORT_NAMESPACE_SPEC, "ExportNamespaceSpecifier")
|
||||
ASTDEF(AST_EXPORT_BATCH_SPEC, "ExportBatchSpecifier")
|
||||
|
||||
ASTDEF(AST_CASE, "SwitchCase", "switchCase")
|
||||
ASTDEF(AST_CATCH, "CatchClause", "catchClause")
|
||||
ASTDEF(AST_CASE, "SwitchCase")
|
||||
ASTDEF(AST_CATCH, "CatchClause")
|
||||
|
||||
ASTDEF(AST_ARRAY_PATT, "ArrayPattern", "arrayPattern")
|
||||
ASTDEF(AST_OBJECT_PATT, "ObjectPattern", "objectPattern")
|
||||
ASTDEF(AST_PROP_PATT, "Property", "propertyPattern")
|
||||
ASTDEF(AST_TEMPLATE_LITERAL, "TemplateLiteral", "templateLiteral")
|
||||
ASTDEF(AST_TAGGED_TEMPLATE, "TaggedTemplate", "taggedTemplate")
|
||||
ASTDEF(AST_CALL_SITE_OBJ, "CallSiteObject", "callSiteObject")
|
||||
ASTDEF(AST_COMPUTED_NAME, "ComputedName", "computedName")
|
||||
ASTDEF(AST_ARRAY_PATT, "ArrayPattern")
|
||||
ASTDEF(AST_OBJECT_PATT, "ObjectPattern")
|
||||
ASTDEF(AST_PROP_PATT, "Property")
|
||||
ASTDEF(AST_TEMPLATE_LITERAL, "TemplateLiteral")
|
||||
ASTDEF(AST_TAGGED_TEMPLATE, "TaggedTemplate")
|
||||
ASTDEF(AST_CALL_SITE_OBJ, "CallSiteObject")
|
||||
ASTDEF(AST_COMPUTED_NAME, "ComputedName")
|
||||
|
||||
ASTDEF(AST_CLASS_STMT, "ClassStatement", "classStatement")
|
||||
ASTDEF(AST_CLASS_METHOD, "ClassMethod", "classMethod")
|
||||
ASTDEF(AST_CLASS_FIELD, "ClassField", "classField")
|
||||
ASTDEF(AST_STATIC_CLASS_BLOCK, "StaticClassBlock", "staticClassBlock")
|
||||
ASTDEF(AST_CLASS_STMT, "ClassStatement")
|
||||
ASTDEF(AST_CLASS_METHOD, "ClassMethod")
|
||||
ASTDEF(AST_CLASS_FIELD, "ClassField")
|
||||
ASTDEF(AST_STATIC_CLASS_BLOCK, "StaticClassBlock")
|
||||
/* AST_LIMIT = last + 1 */
|
||||
|
|
|
@ -1,215 +0,0 @@
|
|||
// |reftest| skip-if(!xulRuntime.shell)
|
||||
// A simple proof-of-concept that the builder API can be used to generate other
|
||||
// formats, such as JsonMLAst:
|
||||
//
|
||||
// http://code.google.com/p/es-lab/wiki/JsonMLASTFormat
|
||||
//
|
||||
// It's incomplete (e.g., it doesn't convert source-location information and
|
||||
// doesn't use all the direct-eval rules), but I think it proves the point.
|
||||
|
||||
function test() {
|
||||
|
||||
var JsonMLAst = (function() {
|
||||
function reject() {
|
||||
throw new SyntaxError("node type not supported");
|
||||
}
|
||||
|
||||
function isDirectEval(expr) {
|
||||
// an approximation to the actual rules. you get the idea
|
||||
return (expr[0] === "IdExpr" && expr[1].name === "eval");
|
||||
}
|
||||
|
||||
function functionNode(type) {
|
||||
return function(id, args, body, isGenerator, isExpression) {
|
||||
if (isExpression)
|
||||
body = ["ReturnStmt", {}, body];
|
||||
|
||||
if (!id)
|
||||
id = ["Empty"];
|
||||
|
||||
// Patch up the argument node types: s/IdExpr/IdPatt/g
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
args[i][0] = "IdPatt";
|
||||
}
|
||||
|
||||
args.unshift("ParamDecl", {});
|
||||
|
||||
return [type, {}, id, args, body];
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
program: function(stmts) {
|
||||
stmts.unshift("Program", {});
|
||||
return stmts;
|
||||
},
|
||||
identifier: function(name) {
|
||||
return ["IdExpr", { name: name }];
|
||||
},
|
||||
literal: function(val) {
|
||||
return ["LiteralExpr", { value: val }];
|
||||
},
|
||||
expressionStatement: expr => expr,
|
||||
conditionalExpression: function(test, cons, alt) {
|
||||
return ["ConditionalExpr", {}, test, cons, alt];
|
||||
},
|
||||
unaryExpression: function(op, expr) {
|
||||
return ["UnaryExpr", {op: op}, expr];
|
||||
},
|
||||
binaryExpression: function(op, left, right) {
|
||||
return ["BinaryExpr", {op: op}, left, right];
|
||||
},
|
||||
property: function(kind, key, val) {
|
||||
return [kind === "init"
|
||||
? "DataProp"
|
||||
: kind === "get"
|
||||
? "GetterProp"
|
||||
: "SetterProp",
|
||||
{name: key[1].name}, val];
|
||||
},
|
||||
functionDeclaration: functionNode("FunctionDecl"),
|
||||
variableDeclaration: function(kind, elts) {
|
||||
if (kind === "let" || kind === "const")
|
||||
throw new SyntaxError("let and const not supported");
|
||||
elts.unshift("VarDecl", {});
|
||||
return elts;
|
||||
},
|
||||
variableDeclarator: function(id, init) {
|
||||
id[0] = "IdPatt";
|
||||
if (!init)
|
||||
return id;
|
||||
return ["InitPatt", {}, id, init];
|
||||
},
|
||||
sequenceExpression: function(exprs) {
|
||||
var length = exprs.length;
|
||||
var result = ["BinaryExpr", {op:","}, exprs[exprs.length - 2], exprs[exprs.length - 1]];
|
||||
for (var i = exprs.length - 3; i >= 0; i--) {
|
||||
result = ["BinaryExpr", {op:","}, exprs[i], result];
|
||||
}
|
||||
return result;
|
||||
},
|
||||
assignmentExpression: function(op, lhs, expr) {
|
||||
return ["AssignExpr", {op: op}, lhs, expr];
|
||||
},
|
||||
logicalExpression: function(op, left, right) {
|
||||
return [op === "&&" ? "LogicalAndExpr" : "LogicalOrExpr", {}, left, right];
|
||||
},
|
||||
updateExpression: function(expr, op, isPrefix) {
|
||||
return ["CountExpr", {isPrefix:isPrefix, op:op}, expr];
|
||||
},
|
||||
newExpression: function(callee, args) {
|
||||
args.unshift("NewExpr", {}, callee);
|
||||
return args;
|
||||
},
|
||||
callExpression: function(callee, args) {
|
||||
args.unshift(isDirectEval(callee) ? "EvalExpr" : "CallExpr", {}, callee);
|
||||
return args;
|
||||
},
|
||||
memberExpression: function(isComputed, expr, member) {
|
||||
return ["MemberExpr", {}, expr, isComputed ? member : ["LiteralExpr", {type: "string", value: member[1].name}]];
|
||||
},
|
||||
functionExpression: functionNode("FunctionExpr"),
|
||||
arrayExpression: function(elts) {
|
||||
for (var i = 0; i < elts.length; i++) {
|
||||
if (!elts[i])
|
||||
elts[i] = ["Empty"];
|
||||
}
|
||||
elts.unshift("ArrayExpr", {});
|
||||
return elts;
|
||||
},
|
||||
objectExpression: function(props) {
|
||||
props.unshift("ObjectExpr", {});
|
||||
return props;
|
||||
},
|
||||
thisExpression: function() {
|
||||
return ["ThisExpr", {}];
|
||||
},
|
||||
templateLiteral: function(elts) {
|
||||
for (var i = 0; i < elts.length; i++) {
|
||||
if (!elts[i])
|
||||
elts[i] = ["Empty"];
|
||||
}
|
||||
elts.unshift("TemplateLit", {});
|
||||
return elts;
|
||||
},
|
||||
|
||||
yieldExpression: reject,
|
||||
|
||||
emptyStatement: () => ["EmptyStmt", {}],
|
||||
blockStatement: function(stmts) {
|
||||
stmts.unshift("BlockStmt", {});
|
||||
return stmts;
|
||||
},
|
||||
labeledStatement: function(lab, stmt) {
|
||||
return ["LabelledStmt", {label: lab}, stmt];
|
||||
},
|
||||
ifStatement: function(test, cons, alt) {
|
||||
return ["IfStmt", {}, test, cons, alt || ["EmptyStmt", {}]];
|
||||
},
|
||||
switchStatement: function(test, clauses, isLexical) {
|
||||
clauses.unshift("SwitchStmt", {}, test);
|
||||
return clauses;
|
||||
},
|
||||
whileStatement: function(expr, stmt) {
|
||||
return ["WhileStmt", {}, expr, stmt];
|
||||
},
|
||||
doWhileStatement: function(stmt, expr) {
|
||||
return ["DoWhileStmt", {}, stmt, expr];
|
||||
},
|
||||
forStatement: function(init, test, update, body) {
|
||||
return ["ForStmt", {}, init || ["Empty"], test || ["Empty"], update || ["Empty"], body];
|
||||
},
|
||||
forInStatement: function(lhs, rhs, body) {
|
||||
return ["ForInStmt", {}, lhs, rhs, body];
|
||||
},
|
||||
breakStatement: function(lab) {
|
||||
return lab ? ["BreakStmt", {}, lab] : ["BreakStmt", {}];
|
||||
},
|
||||
continueStatement: function(lab) {
|
||||
return lab ? ["ContinueStmt", {}, lab] : ["ContinueStmt", {}];
|
||||
},
|
||||
withStatement: function(expr, stmt) {
|
||||
return ["WithStmt", {}, expr, stmt];
|
||||
},
|
||||
returnStatement: function(expr) {
|
||||
return expr ? ["ReturnStmt", {}, expr] : ["ReturnStmt", {}];
|
||||
},
|
||||
tryStatement: function(body, handler, fin) {
|
||||
var node = ["TryStmt", body, handler];
|
||||
if (fin)
|
||||
node.push(fin);
|
||||
return node;
|
||||
},
|
||||
throwStatement: function(expr) {
|
||||
return ["ThrowStmt", {}, expr];
|
||||
},
|
||||
debuggerStatement: () => ["DebuggerStmt", {}],
|
||||
letStatement: reject,
|
||||
switchCase: function(expr, stmts) {
|
||||
if (expr)
|
||||
stmts.unshift("SwitchCase", {}, expr);
|
||||
else
|
||||
stmts.unshift("DefaultCase", {});
|
||||
return stmts;
|
||||
},
|
||||
catchClause: function(param, body) {
|
||||
param[0] = "IdPatt";
|
||||
return ["CatchClause", {}, param, body];
|
||||
},
|
||||
|
||||
arrayPattern: reject,
|
||||
objectPattern: reject,
|
||||
propertyPattern: reject,
|
||||
};
|
||||
})();
|
||||
|
||||
Pattern(["Program", {},
|
||||
["BinaryExpr", {op: "+"},
|
||||
["LiteralExpr", {value: 2}],
|
||||
["BinaryExpr", {op: "*"},
|
||||
["UnaryExpr", {op: "-"}, ["IdExpr", {name: "x"}]],
|
||||
["IdExpr", {name: "y"}]]]]).match(Reflect.parse("2 + (-x * y)", {loc: false, builder: JsonMLAst}));
|
||||
|
||||
}
|
||||
|
||||
runtest(test);
|
|
@ -1,54 +0,0 @@
|
|||
// |reftest| skip-if(!xulRuntime.shell)
|
||||
function test() {
|
||||
// Builder tests
|
||||
|
||||
Pattern("program").match(Reflect.parse("42", {builder:{program:() => "program"}}));
|
||||
|
||||
assertGlobalStmt("throw 42", 1, { throwStatement: () => 1 });
|
||||
assertGlobalStmt("for (;;);", 2, { forStatement: () => 2 });
|
||||
assertGlobalStmt("for (x in y);", 3, { forInStatement: () => 3 });
|
||||
assertGlobalStmt("{ }", 4, { blockStatement: () => 4 });
|
||||
assertGlobalStmt("foo: { }", 5, { labeledStatement: () => 5 });
|
||||
assertGlobalStmt("with (o) { }", 6, { withStatement: () => 6 });
|
||||
assertGlobalStmt("while (x) { }", 7, { whileStatement: () => 7 });
|
||||
assertGlobalStmt("do { } while(false);", 8, { doWhileStatement: () => 8 });
|
||||
assertGlobalStmt("switch (x) { }", 9, { switchStatement: () => 9 });
|
||||
assertGlobalStmt("try { } catch(e) { }", 10, { tryStatement: () => 10 });
|
||||
assertGlobalStmt(";", 11, { emptyStatement: () => 11 });
|
||||
assertGlobalStmt("debugger;", 12, { debuggerStatement: () => 12 });
|
||||
assertGlobalStmt("42;", 13, { expressionStatement: () => 13 });
|
||||
assertGlobalStmt("for (;;) break", forStmt(null, null, null, 14), { breakStatement: () => 14 });
|
||||
assertGlobalStmt("for (;;) continue", forStmt(null, null, null, 15), { continueStatement: () => 15 });
|
||||
|
||||
assertBlockDecl("var x", "var", { variableDeclaration: kind => kind });
|
||||
assertBlockDecl("let x", "let", { variableDeclaration: kind => kind });
|
||||
assertBlockDecl("const x = undefined", "const", { variableDeclaration: kind => kind });
|
||||
assertBlockDecl("function f() { }", "function", { functionDeclaration: () => "function" });
|
||||
|
||||
assertGlobalExpr("(x,y,z)", 1, { sequenceExpression: () => 1 });
|
||||
assertGlobalExpr("(x ? y : z)", 2, { conditionalExpression: () => 2 });
|
||||
assertGlobalExpr("x + y", 3, { binaryExpression: () => 3 });
|
||||
assertGlobalExpr("delete x", 4, { unaryExpression: () => 4 });
|
||||
assertGlobalExpr("x = y", 5, { assignmentExpression: () => 5 });
|
||||
assertGlobalExpr("x || y", 6, { logicalExpression: () => 6 });
|
||||
assertGlobalExpr("x++", 7, { updateExpression: () => 7 });
|
||||
assertGlobalExpr("new x", 8, { newExpression: () => 8 });
|
||||
assertGlobalExpr("x()", 9, { callExpression: () => 9 });
|
||||
assertGlobalExpr("x.y", 10, { memberExpression: () => 10 });
|
||||
assertGlobalExpr("(function() { })", 11, { functionExpression: () => 11 });
|
||||
assertGlobalExpr("[1,2,3]", 12, { arrayExpression: () => 12 });
|
||||
assertGlobalExpr("({ x: y })", 13, { objectExpression: () => 13 });
|
||||
assertGlobalExpr("this", 14, { thisExpression: () => 14 });
|
||||
assertGlobalExpr("(function*() { yield 42 })", genFunExpr("es6", null, [], blockStmt([exprStmt(19)])), { yieldExpression: () => 19 });
|
||||
|
||||
assertGlobalStmt("switch (x) { case y: }", switchStmt(ident("x"), [1]), { switchCase: () => 1 });
|
||||
assertGlobalStmt("try { } catch (e) { }", 2, { tryStatement: (b, h, f) => h, catchClause: () => 2 });
|
||||
assertGlobalStmt("try { } catch (e) { }", tryStmt(blockStmt([]), 2, null), { catchClause: () => 2 });
|
||||
|
||||
assertGlobalExpr("({ x: y } = z)", aExpr("=", 1, ident("z")), { objectPattern: () => 1 });
|
||||
assertGlobalExpr("({ x: y } = z)", aExpr("=", objPatt([2]), ident("z")), { propertyPattern: () => 2 });
|
||||
assertGlobalExpr("[ x ] = y", aExpr("=", 3, ident("y")), { arrayPattern: () => 3 });
|
||||
|
||||
}
|
||||
|
||||
runtest(test);
|
|
@ -1,15 +0,0 @@
|
|||
// |reftest| skip-if(!xulRuntime.shell)
|
||||
// Ensure that exceptions thrown by builder methods propagate.
|
||||
var thrown = false;
|
||||
try {
|
||||
Reflect.parse("42", { builder: { program: function() { throw "expected" } } });
|
||||
} catch (e) {
|
||||
if (e !== "expected")
|
||||
throw e;
|
||||
thrown = true;
|
||||
}
|
||||
if (!thrown)
|
||||
throw new Error("builder exception not propagated");
|
||||
|
||||
if (typeof reportCompare === 'function')
|
||||
reportCompare(true, true);
|
|
@ -10,13 +10,4 @@ assertEq(Reflect.parse("0;", opts).loc !== null, true);
|
|||
delete opts.loc;
|
||||
assertEq(Reflect.parse("0;", opts).loc !== null, true); // default is true
|
||||
|
||||
// Proxy builder
|
||||
var builder = {
|
||||
program: function (body) { return body.join(); },
|
||||
expressionStatement: function (expr) { return expr + ";" },
|
||||
literal: function (val) { return "" + val; }
|
||||
};
|
||||
opts = {builder: new Proxy(builder, {})};
|
||||
assertEq(Reflect.parse("0xff;", opts), "255;");
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
||||
|
|
Загрузка…
Ссылка в новой задаче