Skip to content
This repository has been archived by the owner on May 19, 2018. It is now read-only.

Commit

Permalink
Fix all throw tests
Browse files Browse the repository at this point in the history
  • Loading branch information
danez committed Jan 14, 2017
1 parent 67a610f commit a08bdae
Show file tree
Hide file tree
Showing 19 changed files with 122 additions and 88 deletions.
57 changes: 30 additions & 27 deletions src/parser/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,20 @@ pp.isGetterOrSetterMethod = function (prop, isPattern) {
!this.match(tt.braceR); // method get() or set()
};

// get methods aren't allowed to have any parameters
// set methods must have exactly 1 parameter
pp.checkGetterSetterParamCount = function (method) {
const paramCount = method.kind === "get" ? 0 : 1;
if (method.params.length !== paramCount) {
const start = method.start;
if (method.kind === "get") {
this.raise(start, "getter should have no params");
} else {
this.raise(start, "setter should have exactly one param");
}
}
};

pp.parseObjectMethod = function (prop, isGenerator, isAsync, isPattern) {
if (isAsync || isGenerator || this.match(tt.parenL)) {
if (isPattern) this.unexpected();
Expand All @@ -820,15 +834,7 @@ pp.parseObjectMethod = function (prop, isGenerator, isAsync, isPattern) {
prop.kind = prop.key.name;
this.parsePropertyName(prop);
this.parseMethod(prop);
const paramCount = prop.kind === "get" ? 0 : 1;
if (prop.params.length !== paramCount) {
const start = prop.start;
if (prop.kind === "get") {
this.raise(start, "getter should have no params");
} else {
this.raise(start, "setter should have exactly one param");
}
}
this.checkGetterSetterParamCount(prop);

return this.finishNode(prop, "ObjectMethod");
}
Expand Down Expand Up @@ -916,8 +922,19 @@ pp.parseArrowExpression = function (node, params, isAsync) {
return this.finishNode(node, "ArrowFunctionExpression");
};

// Parse function body and check parameters.
pp.isStrictBody = function (node, isExpression) {
if (!isExpression && node.body.directives.length) {
for (const directive of (node.body.directives: Array<Object>)) {
if (directive.value.value === "use strict") {
return true;
}
}
}

return false;
};

// Parse function body and check parameters.
pp.parseFunctionBody = function (node, allowExpression) {
const isExpression = allowExpression && !this.match(tt.braceL);

Expand All @@ -942,24 +959,10 @@ pp.parseFunctionBody = function (node, allowExpression) {
// If this is a strict mode function, verify that argument names
// are not repeated, and it does not try to bind the words `eval`
// or `arguments`.
let checkLVal = this.state.strict;
let isStrict = false;

// arrow function
if (allowExpression) checkLVal = true;

// normal function
if (!isExpression && node.body.directives.length) {
for (const directive of (node.body.directives: Array<Object>)) {
if (directive.value.value === "use strict") {
isStrict = true;
checkLVal = true;
break;
}
}
}
const isStrict = this.isStrictBody(node, isExpression);
// Also check when allowExpression === true for arrow functions
const checkLVal = this.state.strict || allowExpression || isStrict;

//
if (isStrict && node.id && node.id.type === "Identifier" && node.id.name === "yield") {
this.raise(node.id.start, "Binding yield in strict mode");
}
Expand Down
12 changes: 1 addition & 11 deletions src/parser/statement.js
Original file line number Diff line number Diff line change
Expand Up @@ -748,18 +748,8 @@ pp.parseClassBody = function (node) {

this.parseClassMethod(classBody, method, isGenerator, isAsync);

// get methods aren't allowed to have any parameters
// set methods must have exactly 1 parameter
if (isGetSet) {
const paramCount = method.kind === "get" ? 0 : 1;
if (method.params.length !== paramCount) {
const start = method.start;
if (method.kind === "get") {
this.raise(start, "getter should have no params");
} else {
this.raise(start, "setter should have exactly one param");
}
}
this.checkGetterSetterParamCount(method);
}
}

Expand Down
74 changes: 69 additions & 5 deletions src/plugins/estree.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ pp.estreeParseLiteral = function (value) {
return node;
};

pp.directiveToStmt = function (directive) {
const directiveLiteral = directive.value;

const stmt = this.startNodeAt(directive.start, directive.loc.start);
const expression = this.startNodeAt(directiveLiteral.start, directiveLiteral.loc.start);

expression.value = directiveLiteral.value;
expression.raw = directiveLiteral.extra.raw;

stmt.expression = this.finishNodeAt(expression, "Literal", directiveLiteral.end, directiveLiteral.loc.end);

return this.finishNodeAt(stmt, "ExpressionStatement", directive.end, directive.loc.end);
};

function isSimpleProperty(node) {
return node &&
node.type === "Property" &&
Expand All @@ -43,13 +57,32 @@ export default function (instance) {
};
});

instance.extend("checkGetterSetterParamCount", function() {
return function (prop) {
const paramCount = prop.kind === "get" ? 0 : 1;
if (prop.value.params.length !== paramCount) {
const start = prop.start;
if (prop.kind === "get") {
this.raise(start, "getter should have no params");
} else {
this.raise(start, "setter should have exactly one param");
}
}
};
});

instance.extend("checkLVal", function(inner) {
return function (expr, isBinding, checkClashes, ...args) {
switch (expr.type) {
case "ObjectPattern":
for (const prop of (expr.properties: Array<Object>)) {
this.checkLVal(prop.value, isBinding, checkClashes, "object destructuring pattern");
}
expr.properties.forEach((prop) => {
this.checkLVal(
prop.type === "Property" ? prop.value : prop,
isBinding,
checkClashes,
"object destructuring pattern"
);
});
break;
default:
inner.call(this, expr, isBinding, checkClashes, ...args);
Expand All @@ -72,12 +105,43 @@ export default function (instance) {
};
});

instance.extend("isValidDirective", function () {
return function () {
instance.extend("isStrictBody", function () {
return function (node, isExpression) {
if (!isExpression && node.body.body.length > 0) {
for (const directive of (node.body.body: Array<Object>)) {
if (directive.type === "ExpressionStatement" && directive.expression.type === "Literal") {
if (directive.expression.value === "use strict") return true;
} else {
// Break for the first non literal expression
break;
}
}
}

return false;
};
});

instance.extend("isValidDirective", function () {
return function (stmt) {
return stmt.type === "ExpressionStatement" &&
stmt.expression.type === "Literal" &&
typeof stmt.expression.value === "string" &&
(!stmt.expression.extra || !stmt.expression.extra.parenthesized);
};
});

instance.extend("parseBlockBody", function (inner) {
return function (node, ...args) {
inner.call(this, node, ...args);

node.directives.reverse().forEach((directive) => {
node.body.unshift(this.directiveToStmt(directive));
});
delete node.directives;
};
});

instance.extend("parseClassMethod", function (inner) {
return function (classBody, ...args) {
inner.call(this, classBody, ...args);
Expand Down
8 changes: 3 additions & 5 deletions test/fixtures/estree/class-method/basic/expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,16 +141,14 @@
"column": 10
}
},
"body": [],
"directives": []
"body": []
},
"expression": false
}
}
]
}
}
],
"directives": []
]
}
}
}
8 changes: 3 additions & 5 deletions test/fixtures/estree/directives/block/expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,9 @@
"raw": "\"use strict\""
}
}
],
"directives": []
]
}
}
],
"directives": []
]
}
}
}
5 changes: 2 additions & 3 deletions test/fixtures/estree/directives/program/expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@
],
"kind": "var"
}
],
"directives": []
]
}
}
}
5 changes: 2 additions & 3 deletions test/fixtures/estree/literal/boolean/expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@
],
"kind": "var"
}
],
"directives": []
]
}
}
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

5 changes: 2 additions & 3 deletions test/fixtures/estree/literal/null/expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@
],
"kind": "var"
}
],
"directives": []
]
}
}
}
5 changes: 2 additions & 3 deletions test/fixtures/estree/literal/number/expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@
],
"kind": "var"
}
],
"directives": []
]
}
}
}
5 changes: 2 additions & 3 deletions test/fixtures/estree/literal/regexp/expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@
],
"kind": "var"
}
],
"directives": []
]
}
}
}

This file was deleted.

This file was deleted.

5 changes: 2 additions & 3 deletions test/fixtures/estree/literal/string/expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@
],
"kind": "var"
}
],
"directives": []
]
}
}
}
5 changes: 2 additions & 3 deletions test/fixtures/estree/object-property/basic/expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@
],
"kind": "const"
}
],
"directives": []
]
}
}
}
4 changes: 2 additions & 2 deletions test/utils/runFixtureTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ exports.runFixtureTests = function runFixtureTests(fixturesPath, parseFunction)
Object.keys(fixtures).forEach(function (name) {
fixtures[name].forEach(function (testSuite) {
testSuite.tests.forEach(function (task) {
var testFn = task.disabled ? test.skip : test;
var testFn = task.disabled ? test.skip : task.options.only ? test.only : test;

testFn(name + "/" + testSuite.title + "/" + task.title, function () {
try {
Expand All @@ -33,7 +33,7 @@ exports.runThrowTestsWithEstree = function runThrowTestsWithEstree(fixturesPath,
task.options.plugins = task.options.plugins || [];
task.options.plugins.push("estree");

var testFn = task.disabled ? test.skip : test;
var testFn = task.disabled ? test.skip : task.options.only ? test.only : test;

testFn(name + "/" + testSuite.title + "/" + task.title, function () {
try {
Expand Down

0 comments on commit a08bdae

Please sign in to comment.