add support for abstract references

This commit is contained in:
Sebastian McKenzie 2014-11-23 17:43:46 +11:00
parent 6b4f40f556
commit 9b38a4826b
2 changed files with 209 additions and 3 deletions

View File

@ -428,6 +428,7 @@
var _arrow = {type: "=>", beforeExpr: true}, _bquote = {type: "`"}, _dollarBraceL = {type: "${", beforeExpr: true};
var _ltSlash = {type: "</"};
var _ellipsis = {type: "...", prefix: true, beforeExpr: true};
var _doubleColon = { type: "::", beforeExpr: true };
// Operators. These carry several kinds of properties to help the
// parser use them properly (the presence of these properties is
@ -473,7 +474,8 @@
dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq,
name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string,
arrow: _arrow, bquote: _bquote, dollarBraceL: _dollarBraceL, star: _star,
assign: _assign, xjsName: _xjsName, xjsText: _xjsText};
assign: _assign, xjsName: _xjsName, xjsText: _xjsText,
doubleColon: _doubleColon};
for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw];
// This is a trick taken from Esprima. It turns out that, on
@ -862,9 +864,19 @@
case 93: ++tokPos; return finishToken(_bracketR);
case 123: ++tokPos; return finishToken(_braceL);
case 125: ++tokPos; return finishToken(_braceR, undefined, !inXJSChildExpression);
case 58: ++tokPos; return finishToken(_colon);
case 63: ++tokPos; return finishToken(_question);
case 58:
++tokPos;
if (options.ecmaVersion >= 7) {
var next = input.charCodeAt(tokPos);
if (next === 58) {
++tokPos;
return finishToken(_doubleColon);
}
}
return finishToken(_colon);
case 96: // '`'
if (options.ecmaVersion >= 6) {
++tokPos;
@ -1865,6 +1877,7 @@
break;
case "SpreadElement":
case "VirtualPropertyExpression":
break;
default:
@ -2407,7 +2420,12 @@
}
function parseSubscripts(base, start, noCalls) {
if (eat(_dot)) {
if (eat(_doubleColon)) {
var node = startNodeAt(start);
node.object = base;
node.property = parseIdent(true);
return parseSubscripts(finishNode(node, "VirtualPropertyExpression"), start, noCalls);
} else if (eat(_dot)) {
var node = startNodeAt(start);
node.object = base;
node.property = parseIdent(true);

View File

@ -13605,6 +13605,194 @@ test("/[a-z]/u", {
ecmaVersion: 6
});
// ES7: Abstract references
test('foo::bar;', {
type: "Program",
start: 0,
end: 9,
body: [{
type: "ExpressionStatement",
start: 0,
end: 9,
expression: {
type: "VirtualPropertyExpression",
start: 0,
end: 8,
object: {
type: "Identifier",
start: 0,
end: 3,
name: "foo"
},
property: {
type: "Identifier",
start: 5,
end: 8,
name: "bar"
}
}
}]
}, {
ecmaVersion: 7
});
test('foo::bar::baz;', {
type: "Program",
start: 0,
end: 14,
body: [{
type: "ExpressionStatement",
start: 0,
end: 14,
expression: {
type: "VirtualPropertyExpression",
start: 0,
end: 13,
object: {
type: "VirtualPropertyExpression",
start: 0,
end: 8,
object: {
type: "Identifier",
start: 0,
end: 3,
name: "foo"
},
property: {
type: "Identifier",
start: 5,
end: 8,
name: "bar"
}
},
property: {
type: "Identifier",
start: 10,
end: 13,
name: "baz"
}
}
}]
}, {
ecmaVersion: 7
});
test('foo::baz();', {
type: "Program",
start: 0,
end: 11,
body: [{
type: "ExpressionStatement",
start: 0,
end: 11,
expression: {
type: "CallExpression",
start: 0,
end: 10,
callee: {
type: "VirtualPropertyExpression",
start: 0,
end: 8,
object: {
type: "Identifier",
start: 0,
end: 3,
name: "foo"
},
property: {
type: "Identifier",
start: 5,
end: 8,
name: "baz"
}
},
arguments: []
}
}]
}, {
ecmaVersion: 7
});
test('foo::bar = "baz";', {
type: "Program",
start: 0,
end: 17,
body: [{
type: "ExpressionStatement",
start: 0,
end: 17,
expression: {
type: "AssignmentExpression",
start: 0,
end: 16,
operator: "=",
left: {
type: "VirtualPropertyExpression",
start: 0,
end: 8,
object: {
type: "Identifier",
start: 0,
end: 3,
name: "foo"
},
property: {
type: "Identifier",
start: 5,
end: 8,
name: "bar"
}
},
right: {
type: "Literal",
start: 11,
end: 16,
value: "baz"
}
}
}]
}, {
ecmaVersion: 7
});
test('delete foo::bar;', {
type: "Program",
start: 0,
end: 16,
body: [{
type: "ExpressionStatement",
start: 0,
end: 16,
expression: {
type: "UnaryExpression",
start: 0,
end: 15,
operator: "delete",
prefix: true,
argument: {
type: "VirtualPropertyExpression",
start: 7,
end: 15,
object: {
type: "Identifier",
start: 7,
end: 10,
name: "foo"
},
property: {
type: "Identifier",
start: 12,
end: 15,
name: "bar"
}
}
}
}]
}, {
ecmaVersion: 7
});
// ES7: Async Functions
test('async function foo(promise) { await promise; }', {