Various property fixes

* Implement getter/setter with computed value
* Fix parsing getter/setter after static or generator token
* Allow storing expressions for computed expression in AST_SymbolMethod
* Allow get and set in shorthand properties in object literals

Fixes #1094, #1146 and #1221
This commit is contained in:
Anthony Van de Gejuchte
2016-07-06 00:40:28 +02:00
committed by Richard van Velzen
parent 766fafda8b
commit 72a9d799b6
6 changed files with 462 additions and 207 deletions

View File

@@ -1738,7 +1738,7 @@ function parse($TEXT, options) {
if (!options.strict && is("punc", "}"))
// allow trailing comma
break;
var start = S.token;
start = S.token;
var type = start.type;
var name = as_property_name();
if (type != "string" && type != "num" && !is("punc", ":")) {
@@ -1747,6 +1747,8 @@ function parse($TEXT, options) {
a.push(concise);
continue;
}
} else if (start.value === "*") {
unexpected(prev());
}
if (type == "punc" && start.value == "[") {
@@ -1802,7 +1804,7 @@ function parse($TEXT, options) {
});
function class_(KindOfClass) {
var start, method, class_name, name, extends_, a = [];
var start, method, class_name, extends_, a = [];
if (S.token.type == "name" && S.token.value != "extends") {
class_name = as_symbol(KindOfClass === AST_DefClass ? AST_SymbolDefClass : AST_SymbolClass);
@@ -1822,8 +1824,7 @@ function parse($TEXT, options) {
if (is("punc", ";")) { next(); } // Leading semicolons are okay in class bodies.
while (!is("punc", "}")) {
start = S.token;
name = as_property_name();
method = concise_method_or_getset(name, start, true);
method = concise_method_or_getset(as_property_name(), start, true);
if (!method) { unexpected(); }
a.push(method);
if (is("punc", ";")) { next(); }
@@ -1841,46 +1842,64 @@ function parse($TEXT, options) {
}
function concise_method_or_getset(name, start, is_class) {
var get_ast = function(name, token) {
if (typeof name === "string" || typeof name === "number") {
if (name === "*") {
unexpected(token);
}
return new AST_SymbolMethod({
start: token,
name: name,
end: prev()
});
}
return name;
}
var is_static = false;
var is_generator = false;
if (is_class && name === "static" && !is("punc", "(")) {
is_static = true;
name = S.token.value;
next();
name = as_property_name();
}
if (name === "*") {
is_generator = true;
name = S.token.value;
next();
name = as_property_name();
}
if (is("punc", "(")) {
name = get_ast(name, start);
return new AST_ConciseMethod({
is_generator: is_generator,
start : start,
static : is_static,
name : new AST_SymbolMethod({ name: name }),
name : name,
argnames : params_or_seq_().as_params(croak),
body : _function_body(true, is_generator),
end : prev()
});
}
if (name == "get") {
return new AST_ObjectGetter({
start : start,
static: is_static,
key : as_atom_node(),
value : function_(AST_Accessor),
end : prev()
});
if (!is("punc") || is("punc", "[")) {
name = get_ast(as_property_name(), prev());
return new AST_ObjectGetter({
start : start,
static: is_static,
key : name,
value : function_(AST_Accessor),
end : prev()
});
}
}
if (name == "set") {
return new AST_ObjectSetter({
start : start,
static: is_static,
key : as_atom_node(),
value : function_(AST_Accessor),
end : prev()
});
else if (name == "set") {
if (!is("punc") || is("punc", "[")) {
name = get_ast(as_property_name(), prev());
return new AST_ObjectSetter({
start : start,
static: is_static,
key : name,
value : function_(AST_Accessor),
end : prev()
});
}
}
}
@@ -1996,19 +2015,22 @@ function parse($TEXT, options) {
var ex = expression(false);
expect("]");
return ex;
} else unexpected();
} else unexpected(tmp);
case "operator":
if (["*", "delete", "in", "instanceof", "new", "typeof", "void"].indexOf(tmp.value) === -1) {
unexpected(tmp);
}
case "name":
if (tmp.value === "yield" && S.input.has_directive("use strict") && !is_in_generator()) {
token_error(tmp, "SyntaxError: Unexpected yield identifier inside strict mode");
}
case "string":
case "num":
case "operator":
case "keyword":
case "atom":
return tmp.value;
default:
unexpected();
unexpected(tmp);
}
};