diff --git a/eslint/babel-eslint-parser/index.js b/eslint/babel-eslint-parser/index.js index 2002b68fd9..613d1fc72d 100644 --- a/eslint/babel-eslint-parser/index.js +++ b/eslint/babel-eslint-parser/index.js @@ -54,6 +54,41 @@ function monkeypatch() { estraverse.VisitorKeys.TypeAlias = TypeAliasKeys; return results; }; + + // monkeypatch escope/referencer + var referencerLoc; + try { + var referencerLoc = Module._resolveFilename("./referencer", escopeMod); + } catch (err) { + throw new ReferenceError("couldn't resolve escope/referencer"); + } + var referencer = require(referencerLoc); + + // if there are decotators, then visit each + function visitDecorators(node) { + if (!node.decorators) { + return; + } + for (var i = 0; i < node.decorators.length; i++) { + if (node.decorators[i].expression) { + this.visit(node.decorators[i]); + } + } + } + + // monkeypatch referencer methods to visit decorators + var visitClass = referencer.prototype.visitClass; + referencer.prototype.visitClass = function (node) { + // visit decorators that are in: Class Declaration + visitDecorators.call(this, node); + visitClass.call(this, node); + } + var visitProperty = referencer.prototype.visitProperty; + referencer.prototype.visitProperty = function (node) { + // visit decorators that are in: Visit Property / MethodDefinition + visitDecorators.call(this, node); + visitProperty.call(this, node); + } } 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 ba62ccf050..3cb0222a5b 100644 --- a/eslint/babel-eslint-parser/test/non-regression.js +++ b/eslint/babel-eslint-parser/test/non-regression.js @@ -55,7 +55,7 @@ describe("verify", function () { verifyAndAssertMessages( "import Foo from 'foo';\n" + "export default Foo;", - { }, + {}, [] ); }); @@ -163,4 +163,96 @@ describe("verify", function () { [] ); }); + + describe("decorators #72", function () { + it("class declaration", function () { + verifyAndAssertMessages( + [ + "import classDeclaration from 'decorator';", + "import decoratorParameter from 'decorator';", + "@classDeclaration(decoratorParameter)", + "@classDeclaration", + "class TextareaAutosize {}" + ].join("\n"), + { "no-unused-vars": 1 }, + [] + ); + }); + + it("method definition", function () { + verifyAndAssertMessages( + [ + "import classMethodDeclarationA from 'decorator';", + "import decoratorParameter from 'decorator';", + "class TextareaAutosize {", + "@classMethodDeclarationA(decoratorParameter)", + "@classMethodDeclarationA", + "methodDeclaration(e) {", + "e();", + "}", + "}" + ].join("\n"), + { "no-unused-vars": 1 }, + [] + ); + }); + + it("method definition get/set", function () { + verifyAndAssertMessages( + [ + "import classMethodDeclarationA from 'decorator';", + "import decoratorParameter from 'decorator';", + "class TextareaAutosize {", + "@classMethodDeclarationA(decoratorParameter)", + "@classMethodDeclarationA", + "get bar() { }", + "@classMethodDeclarationA(decoratorParameter)", + "@classMethodDeclarationA", + "set bar() { }", + "}" + ].join("\n"), + { "no-unused-vars": 1 }, + [] + ); + }); + + it("object property", function () { + verifyAndAssertMessages( + [ + "import classMethodDeclarationA from 'decorator';", + "import decoratorParameter from 'decorator';", + "var obj = {", + "@classMethodDeclarationA(decoratorParameter)", + "@classMethodDeclarationA", + "methodDeclaration(e) {", + "e();", + "}", + "};", + "obj;" + ].join("\n"), + { "no-unused-vars": 1 }, + [] + ); + }); + + it("object property get/set", function () { + verifyAndAssertMessages( + [ + "import classMethodDeclarationA from 'decorator';", + "import decoratorParameter from 'decorator';", + "var obj = {", + "@classMethodDeclarationA(decoratorParameter)", + "@classMethodDeclarationA", + "get bar() { },", + "@classMethodDeclarationA(decoratorParameter)", + "@classMethodDeclarationA", + "set bar() { }", + "};", + "obj;" + ].join("\n"), + { "no-unused-vars": 1 }, + [] + ); + }); + }); });