diff --git a/eslint/babel-eslint-parser/index.js b/eslint/babel-eslint-parser/index.js index 0977fd421a..cd28c76545 100644 --- a/eslint/babel-eslint-parser/index.js +++ b/eslint/babel-eslint-parser/index.js @@ -173,10 +173,6 @@ function monkeypatch() { var visitClass = referencer.prototype.visitClass; referencer.prototype.visitClass = function(node) { visitDecorators.call(this, node); - // visit class - if (node.id) { - this.visit(node.id); - } // visit flow type: ClassImplements if (node.implements) { for (var i = 0; i < node.implements.length; i++) { @@ -198,7 +194,7 @@ function monkeypatch() { // visit decorators that are in: Property / MethodDefinition var visitProperty = referencer.prototype.visitProperty; referencer.prototype.visitProperty = function(node) { - if (node.value.type === 'TypeCastExpression') { + if (node.value.type === "TypeCastExpression") { visitTypeAnnotation.call(this, node.value); } visitDecorators.call(this, node); @@ -238,18 +234,21 @@ function monkeypatch() { variableDeclaration.call(this, node); }; - referencer.prototype.TypeAlias = function(node) { - this.currentScope().__define( - node.id, + function createScopeVariable (node, name) { + this.currentScope().variableScope.__define(name, new Definition( - "Variable", - node.id, - node, - null, - null, - null + "Variable", + name, + node, + null, + null, + null ) ); + } + + referencer.prototype.TypeAlias = function(node) { + createScopeVariable.call(this, node, node.id); if (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) { diff --git a/eslint/babel-eslint-parser/test/non-regression.js b/eslint/babel-eslint-parser/test/non-regression.js index 9b0b783d33..2a837f779c 100644 --- a/eslint/babel-eslint-parser/test/non-regression.js +++ b/eslint/babel-eslint-parser/test/non-regression.js @@ -255,9 +255,8 @@ describe("verify", function () { it("ClassImplements", function () { verifyAndAssertMessages([ - "import type Foo from 'foo';", "import type Bar from 'foo';", - "class Foo implements Bar {}" + "export default class Foo implements Bar {}" ].join("\n"), { "no-unused-vars": 1, "no-undef": 1 }, [] @@ -459,7 +458,7 @@ describe("verify", function () { [ "import type Foo 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"), { "no-unused-vars": 1, "no-undef": 1 }, [] @@ -469,8 +468,8 @@ describe("verify", function () { it("15", function () { verifyAndAssertMessages( [ - "import type Foo from 'foo';", - "class Foo {get fooProp():Foo{}}" + "import type Foo2 from 'foo';", + "export default class Foo {get fooProp(): Foo2{}}" ].join("\n"), { "no-unused-vars": 1, "no-undef": 1 }, [] @@ -581,7 +580,7 @@ describe("verify", function () { "import type Foo from 'foo';", "import type Foo2 from 'foo';", "import Baz from 'foo';", - "class Bar extends Baz { };" + "export default class Bar extends Baz { };" ].join("\n"), { "no-unused-vars": 1, "no-undef": 1 }, [] @@ -594,7 +593,7 @@ describe("verify", function () { "import type Foo from 'foo';", "import type Foo2 from 'foo';", "import type Foo3 from 'foo';", - "class Bar { bar():Foo3 { return 42; }}" + "export default class Bar { bar():Foo3 { return 42; }}" ].join("\n"), { "no-unused-vars": 1, "no-undef": 1 }, [] @@ -606,7 +605,7 @@ describe("verify", function () { [ "import type Foo 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"), { "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 () { verifyAndAssertMessages( "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 () { it("class declaration", function () { verifyAndAssertMessages(