improve babylon test coverage and remove dead code

This commit is contained in:
Sebastian McKenzie 2015-07-25 19:54:19 +01:00
parent 2598299e64
commit 676766533c
20 changed files with 267 additions and 76 deletions

View File

@ -236,8 +236,7 @@ pp.parseSubscripts = function(base, startPos, startLoc, noCalls) {
this.expect(tt.bracketR);
base = this.finishNode(node, "MemberExpression");
} else if (!noCalls && this.state.type === tt.parenL) {
let possibleAsync = false;
if (base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon()) possibleAsync = true;
let possibleAsync = base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon();
this.next();
let node = this.startNodeAt(startPos, startLoc);

View File

@ -100,20 +100,20 @@ pp.parseRest = function () {
pp.parseBindingAtom = function () {
switch (this.state.type) {
case tt.name:
return this.parseIdent();
case tt.name:
return this.parseIdent();
case tt.bracketL:
let node = this.startNode();
this.next();
node.elements = this.parseBindingList(tt.bracketR, true, true);
return this.finishNode(node, "ArrayPattern");
case tt.bracketL:
let node = this.startNode();
this.next();
node.elements = this.parseBindingList(tt.bracketR, true, true);
return this.finishNode(node, "ArrayPattern");
case tt.braceL:
return this.parseObj(true);
case tt.braceL:
return this.parseObj(true);
default:
this.unexpected();
default:
this.unexpected();
}
};
@ -163,49 +163,45 @@ pp.parseMaybeDefault = function (startPos, startLoc, left) {
pp.checkLVal = function (expr, isBinding, checkClashes) {
switch (expr.type) {
case "Identifier":
if (this.strict && (reservedWords.strictBind(expr.name) || reservedWords.strict(expr.name)))
this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
if (checkClashes) {
if (checkClashes[expr.name]) {
this.raise(expr.start, "Argument name clash in strict mode");
} else {
checkClashes[expr.name] = true;
case "Identifier":
if (this.strict && (reservedWords.strictBind(expr.name) || reservedWords.strict(expr.name)))
this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
if (checkClashes) {
if (checkClashes[expr.name]) {
this.raise(expr.start, "Argument name clash in strict mode");
} else {
checkClashes[expr.name] = true;
}
}
}
break;
break;
case "MemberExpression":
if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
break;
case "MemberExpression":
if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
break;
case "ObjectPattern":
for (let prop of (expr.properties: Array)) {
if (prop.type === "Property") prop = prop.value;
this.checkLVal(prop, isBinding, checkClashes);
}
break;
case "ObjectPattern":
for (let prop of (expr.properties: Array)) {
if (prop.type === "Property") prop = prop.value;
this.checkLVal(prop, isBinding, checkClashes);
}
break;
case "ArrayPattern":
for (let elem of (expr.elements: Array)) {
if (elem) this.checkLVal(elem, isBinding, checkClashes);
}
break;
case "ArrayPattern":
for (let elem of (expr.elements: Array)) {
if (elem) this.checkLVal(elem, isBinding, checkClashes);
}
break;
case "AssignmentPattern":
this.checkLVal(expr.left, isBinding, checkClashes);
break;
case "AssignmentPattern":
this.checkLVal(expr.left, isBinding, checkClashes);
break;
case "SpreadProperty":
case "RestElement":
this.checkLVal(expr.argument, isBinding, checkClashes);
break;
case "SpreadProperty":
case "RestElement":
this.checkLVal(expr.argument, isBinding, checkClashes);
break;
case "ParenthesizedExpression":
this.checkLVal(expr.expression, isBinding, checkClashes);
break;
default:
this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue");
default:
this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue");
}
};

View File

@ -10,10 +10,7 @@ export class Node {
this.type = "";
this.start = pos;
this.end = 0;
if (parser) {
this.loc = new SourceLocation(loc);
}
this.loc = new SourceLocation(loc);
}
__clone() {

View File

@ -121,7 +121,6 @@ pp.jsxReadString = function(quote) {
pp.jsxReadEntity = function() {
var str = "", count = 0, entity;
var ch = this.input[this.state.pos];
if (ch !== "&") this.raise(this.state.pos, "Entity must start with an ampersand");
var startPos = ++this.state.pos;
while (this.state.pos < this.input.length && count++ < 10) {

View File

@ -79,11 +79,6 @@ export default class Tokenizer {
return curr;
}
getToken() {
this.next();
return new Token(this.state);
}
// Toggle strict mode. Re-reads the next number or string to please
// pedantic tests (`"use strict"; 010;` should fail).
@ -455,13 +450,19 @@ export default class Tokenizer {
for (;;) {
if (this.state.pos >= this.input.length) this.raise(start, "Unterminated regular expression");
let ch = this.input.charAt(this.state.pos);
if (lineBreak.test(ch)) this.raise(start, "Unterminated regular expression");
if (lineBreak.test(ch)) {
this.raise(start, "Unterminated regular expression");
}
if (escaped) {
escaped = false;
} else {
if (ch === "[") inClass = true;
else if (ch === "]" && inClass) inClass = false;
else if (ch === "/" && !inClass) break;
if (ch === "[") {
inClass = true;
} else if (ch === "]" && inClass) {
inClass = false;
} else if (ch === "/" && !inClass) {
break;
}
escaped = ch === "\\";
}
++this.state.pos;
@ -502,7 +503,11 @@ export default class Tokenizer {
// case the current environment doesn't support the flags it uses.
value = tryCreateRegexp.call(this, content, mods);
}
return this.finishToken(tt.regexp, {pattern: content, flags: mods, value: value});
return this.finishToken(tt.regexp, {
pattern: content,
flags: mods,
value
});
}
// Read an integer in the given radix. Return null if zero digits

View File

@ -83,19 +83,18 @@ function isInAstralSet(code, set) {
// Test whether a given character code starts an identifier.
export function isIdentifierStart(code, astral) {
export function isIdentifierStart(code) {
if (code < 65) return code === 36;
if (code < 91) return true;
if (code < 97) return code === 95;
if (code < 123) return true;
if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
if (astral === false) return false;
return isInAstralSet(code, astralIdentifierStartCodes);
}
// Test whether a given character is part of an identifier.
export function isIdentifierChar(code, astral) {
export function isIdentifierChar(code) {
if (code < 48) return code === 36;
if (code < 58) return true;
if (code < 65) return false;
@ -103,6 +102,5 @@ export function isIdentifierChar(code, astral) {
if (code < 97) return code === 95;
if (code < 123) return true;
if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
if (astral === false) return false;
return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
}

View File

@ -8,10 +8,6 @@ export class Position {
this.line = line;
this.column = col;
}
offset(n) {
return new Position(this.line, this.column + n);
}
}
export class SourceLocation {

View File

@ -0,0 +1 @@
declare foobar

View File

@ -0,0 +1,3 @@
{
"throws": "Unexpected token (1:8)"
}

View File

@ -0,0 +1,3 @@
var foo = {
[bar()]: ""
};

View File

@ -0,0 +1,169 @@
{
"type": "File",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 2
}
},
"program": {
"type": "Program",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 2
}
},
"sourceType": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 2
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 4,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 7
}
},
"name": "foo"
},
"init": {
"type": "ObjectExpression",
"start": 10,
"end": 27,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 3,
"column": 1
}
},
"properties": [
{
"type": "Property",
"start": 14,
"end": 25,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 13
}
},
"method": false,
"shorthand": false,
"computed": true,
"key": {
"type": "CallExpression",
"start": 15,
"end": 20,
"loc": {
"start": {
"line": 2,
"column": 3
},
"end": {
"line": 2,
"column": 8
}
},
"callee": {
"type": "Identifier",
"start": 15,
"end": 18,
"loc": {
"start": {
"line": 2,
"column": 3
},
"end": {
"line": 2,
"column": 6
}
},
"name": "bar"
},
"arguments": []
},
"value": {
"type": "Literal",
"start": 23,
"end": 25,
"loc": {
"start": {
"line": 2,
"column": 11
},
"end": {
"line": 2,
"column": 13
}
},
"value": "",
"rawValue": "",
"raw": "\"\""
},
"kind": "init"
}
]
}
}
],
"kind": "var"
}
]
},
"comments": []
}

View File

@ -0,0 +1 @@
<Foo bar=bar() />

View File

@ -0,0 +1,3 @@
{
"throws": "JSX value should be either an expression or a quoted JSX text (1:9)"
}

View File

@ -0,0 +1 @@
<foo bar={} />

View File

@ -0,0 +1,3 @@
{
"throws": "JSX attributes must only be assigned a non-empty expression (1:9)"
}

View File

@ -0,0 +1 @@
<foo>yes

View File

@ -0,0 +1,3 @@
{
"throws": "Unterminated JSX contents (1:5)"
}

View File

@ -0,0 +1 @@
<foo bar="

View File

@ -0,0 +1,3 @@
{
"throws": "Unterminated string constant (1:9)"
}

View File

@ -18,6 +18,12 @@ _.each(fixtures, function (suites, name) {
});
});
function save(test, ast) {
delete ast.tokens;
if (!ast.comments.length) delete ast.comments;
require("fs").writeFileSync(test.expect.loc, JSON.stringify(ast, null, " "));
}
function runTest(test) {
var opts = test.options;
opts.locations = true;
@ -38,18 +44,21 @@ function runTest(test) {
throw err;
}
if (!test.expect.code) {
test.expect.loc += "on";
return save(test, ast);
}
if (opts.throws) {
throw new Error("Expected error message: " + opts.throws + ". But parsing succeeded.");
} else {
try {
var mis = misMatch(JSON.parse(test.expect.code), ast);
} catch (err) {
console.log(test.expect.code);
// save(test, ast);
throw err;
}
if (mis) {
//delete ast.tokens;
//require("fs").writeFileSync(test.expect.loc, JSON.stringify(ast, null, " "));
throw new Error(mis);
}
}