Merge pull request babel/babel-eslint#114 from hzoo/i-9

support comprehensions (no-undef) - fixes babel/babel-eslint#9
This commit is contained in:
Henry Zhu 2015-06-03 17:06:42 -04:00
parent e6ba27075e
commit ade0b3b21b
2 changed files with 96 additions and 22 deletions

View File

@ -173,10 +173,6 @@ function monkeypatch() {
var visitClass = referencer.prototype.visitClass; var visitClass = referencer.prototype.visitClass;
referencer.prototype.visitClass = function(node) { referencer.prototype.visitClass = function(node) {
visitDecorators.call(this, node); visitDecorators.call(this, node);
// visit class
if (node.id) {
this.visit(node.id);
}
// visit flow type: ClassImplements // visit flow type: ClassImplements
if (node.implements) { if (node.implements) {
for (var i = 0; i < node.implements.length; i++) { for (var i = 0; i < node.implements.length; i++) {
@ -198,7 +194,7 @@ function monkeypatch() {
// visit decorators that are in: Property / MethodDefinition // visit decorators that are in: Property / MethodDefinition
var visitProperty = referencer.prototype.visitProperty; var visitProperty = referencer.prototype.visitProperty;
referencer.prototype.visitProperty = function(node) { referencer.prototype.visitProperty = function(node) {
if (node.value.type === 'TypeCastExpression') { if (node.value.type === "TypeCastExpression") {
visitTypeAnnotation.call(this, node.value); visitTypeAnnotation.call(this, node.value);
} }
visitDecorators.call(this, node); visitDecorators.call(this, node);
@ -238,18 +234,21 @@ function monkeypatch() {
variableDeclaration.call(this, node); variableDeclaration.call(this, node);
}; };
referencer.prototype.TypeAlias = function(node) { function createScopeVariable (node, name) {
this.currentScope().__define( this.currentScope().variableScope.__define(name,
node.id,
new Definition( new Definition(
"Variable", "Variable",
node.id, name,
node, node,
null, null,
null, null,
null null
) )
); );
}
referencer.prototype.TypeAlias = function(node) {
createScopeVariable.call(this, node, node.id);
if (node.right) { if (node.right) {
visitTypeAnnotation.call(this, node.right); visitTypeAnnotation.call(this, node.right);
} }
@ -259,6 +258,24 @@ function monkeypatch() {
} }
} }
} }
referencer.prototype.ComprehensionBlock = function(node) {
var left = node.left;
if (left) {
if (left.type === "Identifier") {
createScopeVariable.call(this, node, left);
} else if (left.type === "ArrayPattern") {
for (var i = 0; i < left.elements.length; i++) {
if (left.elements[i]) {
createScopeVariable.call(this, left.elements, left.elements[i]);
}
}
}
}
if (node.right) {
this.visit(node.right);
}
}
} }
exports.attachComments = function (ast, comments, tokens) { exports.attachComments = function (ast, comments, tokens) {

View File

@ -255,9 +255,8 @@ describe("verify", function () {
it("ClassImplements", function () { it("ClassImplements", function () {
verifyAndAssertMessages([ verifyAndAssertMessages([
"import type Foo from 'foo';",
"import type Bar from 'foo';", "import type Bar from 'foo';",
"class Foo implements Bar {}" "export default class Foo implements Bar {}"
].join("\n"), ].join("\n"),
{ "no-unused-vars": 1, "no-undef": 1 }, { "no-unused-vars": 1, "no-undef": 1 },
[] []
@ -459,7 +458,7 @@ describe("verify", function () {
[ [
"import type Foo from 'foo';", "import type Foo from 'foo';",
"import type Foo2 from 'foo';", "import type Foo2 from 'foo';",
"class Bar {set fooProp(value:Foo):Foo2{ value; }}" "export default class Bar {set fooProp(value:Foo):Foo2{ value; }}"
].join("\n"), ].join("\n"),
{ "no-unused-vars": 1, "no-undef": 1 }, { "no-unused-vars": 1, "no-undef": 1 },
[] []
@ -469,8 +468,8 @@ describe("verify", function () {
it("15", function () { it("15", function () {
verifyAndAssertMessages( verifyAndAssertMessages(
[ [
"import type Foo from 'foo';", "import type Foo2 from 'foo';",
"class Foo {get fooProp():Foo{}}" "export default class Foo {get fooProp(): Foo2{}}"
].join("\n"), ].join("\n"),
{ "no-unused-vars": 1, "no-undef": 1 }, { "no-unused-vars": 1, "no-undef": 1 },
[] []
@ -581,7 +580,7 @@ describe("verify", function () {
"import type Foo from 'foo';", "import type Foo from 'foo';",
"import type Foo2 from 'foo';", "import type Foo2 from 'foo';",
"import Baz from 'foo';", "import Baz from 'foo';",
"class Bar<Foo> extends Baz<Foo2> { };" "export default class Bar<Foo> extends Baz<Foo2> { };"
].join("\n"), ].join("\n"),
{ "no-unused-vars": 1, "no-undef": 1 }, { "no-unused-vars": 1, "no-undef": 1 },
[] []
@ -594,7 +593,7 @@ describe("verify", function () {
"import type Foo from 'foo';", "import type Foo from 'foo';",
"import type Foo2 from 'foo';", "import type Foo2 from 'foo';",
"import type Foo3 from 'foo';", "import type Foo3 from 'foo';",
"class Bar<Foo> { bar<Foo2>():Foo3 { return 42; }}" "export default class Bar<Foo> { bar<Foo2>():Foo3 { return 42; }}"
].join("\n"), ].join("\n"),
{ "no-unused-vars": 1, "no-undef": 1 }, { "no-unused-vars": 1, "no-undef": 1 },
[] []
@ -606,7 +605,7 @@ describe("verify", function () {
[ [
"import type Foo from 'foo';", "import type Foo from 'foo';",
"import type Foo2 from 'foo';", "import type Foo2 from 'foo';",
"class Bar { static prop1:Foo; prop2:Foo2; }" "export default class Bar { static prop1:Foo; prop2:Foo2; }"
].join("\n"), ].join("\n"),
{ "no-unused-vars": 1, "no-undef": 1 }, { "no-unused-vars": 1, "no-undef": 1 },
[] []
@ -885,6 +884,19 @@ describe("verify", function () {
); );
}); });
it("class definition: gaearon/redux#24", function () {
verifyAndAssertMessages([
"export default function root(stores) {",
"return DecoratedComponent => class ReduxRootDecorator {",
"a() { DecoratedComponent; }",
"};",
"}",
].join("\n"),
{ "no-undef": 1, "no-unused-vars": 1 },
[]
);
});
it("class properties", function () { it("class properties", function () {
verifyAndAssertMessages( verifyAndAssertMessages(
"class Lol { foo = 'bar'; }", "class Lol { foo = 'bar'; }",
@ -914,6 +926,51 @@ describe("verify", function () {
); );
}); });
describe("comprehensions", function () {
it("array #9", function () {
verifyAndAssertMessages([
"let arr = [1, 2, 3];",
"let b = [for (e of arr) String(e)];"
].join("\n"),
{ "no-unused-vars": 1, "no-undef": 1 },
[]
);
});
it("array, if statement, multiple blocks", function () {
verifyAndAssertMessages([
"let arr = [1, 2, 3];",
"let arr2 = [1, 2, 3];",
"[for (x of arr) for (y of arr2) if (x === true && y === true) x + y];"
].join("\n"),
{ "no-unused-vars": 1, "no-undef": 1 },
[]
);
});
it("expression, if statement, multiple blocks", function () {
verifyAndAssertMessages([
"let arr = [1, 2, 3];",
"let arr2 = [1, 2, 3];",
"(for (x of arr) for (y of arr2) if (x === true && y === true) x + y)"
].join("\n"),
{ "no-unused-vars": 1, "no-undef": 1 },
[]
);
});
it("ArrayPattern", function () {
verifyAndAssertMessages([
"let arr = [1, 2, 3];",
"let arr2 = [1, 2, 3];",
"[for ([,x] of arr) for ({[start.x]: x, [start.y]: y} of arr2) x]"
].join("\n"),
{ "no-unused-vars": 1, "no-undef": 1 },
[]
);
});
});
describe("decorators #72", function () { describe("decorators #72", function () {
it("class declaration", function () { it("class declaration", function () {
verifyAndAssertMessages( verifyAndAssertMessages(