Fix parsing setters/getters (allow keywords for name).
The "key" property was always "set" or "get", which didn't make much sense. Now it'll be the actual name of the setter/getter (AST_Node), and the AST_Accessor object itself, which represents the function, won't store any name. Close #319
This commit is contained in:
@@ -371,7 +371,7 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
|
||||
}, AST_Scope);
|
||||
|
||||
var AST_Accessor = DEFNODE("Accessor", null, {
|
||||
$documentation: "A setter/getter function"
|
||||
$documentation: "A setter/getter function. The `name` property is always null."
|
||||
}, AST_Lambda);
|
||||
|
||||
var AST_Function = DEFNODE("Function", null, {
|
||||
@@ -756,7 +756,7 @@ var AST_Object = DEFNODE("Object", "properties", {
|
||||
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
||||
$documentation: "Base class for literal object properties",
|
||||
$propdoc: {
|
||||
key: "[string] the property name; it's always a plain string in our AST, no matter if it was a string, number or identifier in original code",
|
||||
key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.",
|
||||
value: "[AST_Node] property value. For setters and getters this is an AST_Function."
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
|
||||
@@ -1066,10 +1066,14 @@ function OutputStream(options) {
|
||||
});
|
||||
DEFPRINT(AST_ObjectSetter, function(self, output){
|
||||
output.print("set");
|
||||
output.space();
|
||||
self.key.print(output);
|
||||
self.value._do_print(output, true);
|
||||
});
|
||||
DEFPRINT(AST_ObjectGetter, function(self, output){
|
||||
output.print("get");
|
||||
output.space();
|
||||
self.key.print(output);
|
||||
self.value._do_print(output, true);
|
||||
});
|
||||
DEFPRINT(AST_Symbol, function(self, output){
|
||||
|
||||
45
lib/parse.js
45
lib/parse.js
@@ -789,7 +789,7 @@ function parse($TEXT, options) {
|
||||
return for_();
|
||||
|
||||
case "function":
|
||||
return function_(true);
|
||||
return function_(AST_Defun);
|
||||
|
||||
case "if":
|
||||
return if_();
|
||||
@@ -933,19 +933,12 @@ function parse($TEXT, options) {
|
||||
});
|
||||
};
|
||||
|
||||
var function_ = function(in_statement, ctor) {
|
||||
var is_accessor = ctor === AST_Accessor;
|
||||
var name = (is("name") ? as_symbol(in_statement
|
||||
? AST_SymbolDefun
|
||||
: is_accessor
|
||||
? AST_SymbolAccessor
|
||||
: AST_SymbolLambda)
|
||||
: is_accessor && (is("string") || is("num")) ? as_atom_node()
|
||||
: null);
|
||||
var function_ = function(ctor) {
|
||||
var in_statement = ctor === AST_Defun;
|
||||
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
|
||||
if (in_statement && !name)
|
||||
unexpected();
|
||||
expect("(");
|
||||
if (!ctor) ctor = in_statement ? AST_Defun : AST_Function;
|
||||
return new ctor({
|
||||
name: name,
|
||||
argnames: (function(first, a){
|
||||
@@ -1116,7 +1109,9 @@ function parse($TEXT, options) {
|
||||
var tok = S.token, ret;
|
||||
switch (tok.type) {
|
||||
case "name":
|
||||
return as_symbol(AST_SymbolRef);
|
||||
case "keyword":
|
||||
ret = _make_symbol(AST_SymbolRef);
|
||||
break;
|
||||
case "num":
|
||||
ret = new AST_Number({ start: tok, end: tok, value: tok.value });
|
||||
break;
|
||||
@@ -1167,7 +1162,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
if (is("keyword", "function")) {
|
||||
next();
|
||||
var func = function_(false);
|
||||
var func = function_(AST_Function);
|
||||
func.start = start;
|
||||
func.end = prev();
|
||||
return subscripts(func, allow_calls);
|
||||
@@ -1215,8 +1210,8 @@ function parse($TEXT, options) {
|
||||
if (name == "get") {
|
||||
a.push(new AST_ObjectGetter({
|
||||
start : start,
|
||||
key : name,
|
||||
value : function_(false, AST_Accessor),
|
||||
key : as_atom_node(),
|
||||
value : function_(AST_Accessor),
|
||||
end : prev()
|
||||
}));
|
||||
continue;
|
||||
@@ -1224,8 +1219,8 @@ function parse($TEXT, options) {
|
||||
if (name == "set") {
|
||||
a.push(new AST_ObjectSetter({
|
||||
start : start,
|
||||
key : name,
|
||||
value : function_(false, AST_Accessor),
|
||||
key : as_atom_node(),
|
||||
value : function_(AST_Accessor),
|
||||
end : prev()
|
||||
}));
|
||||
continue;
|
||||
@@ -1273,17 +1268,21 @@ function parse($TEXT, options) {
|
||||
}
|
||||
};
|
||||
|
||||
function _make_symbol(type) {
|
||||
var name = S.token.value;
|
||||
return new (name == "this" ? AST_This : type)({
|
||||
name : String(name),
|
||||
start : S.token,
|
||||
end : S.token
|
||||
});
|
||||
};
|
||||
|
||||
function as_symbol(type, noerror) {
|
||||
if (!is("name")) {
|
||||
if (!noerror) croak("Name expected");
|
||||
return null;
|
||||
}
|
||||
var name = S.token.value;
|
||||
var sym = new (name == "this" ? AST_This : type)({
|
||||
name : String(S.token.value),
|
||||
start : S.token,
|
||||
end : S.token
|
||||
});
|
||||
var sym = _make_symbol(type);
|
||||
next();
|
||||
return sym;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user