Skip to content
This repository has been archived by the owner on Aug 4, 2020. It is now read-only.

Commit

Permalink
Added babel/no-invalid-this rule. (Closes #12)
Browse files Browse the repository at this point in the history
  • Loading branch information
mathieumg committed Oct 3, 2016
1 parent 80d66bc commit 7e00840
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 19 deletions.
4 changes: 3 additions & 1 deletion README.md
Expand Up @@ -34,7 +34,8 @@ original ones as well!).
"babel/arrow-parens": 1,
"babel/no-await-in-loop": 1,
"babel/flow-object-type": 1,
"babel/func-params-comma-dangle": 1
"babel/func-params-comma-dangle": 1,
"babel/no-invalid-this": 1
}
}
```
Expand All @@ -50,6 +51,7 @@ Each rule corresponds to a core `eslint` rule, and has the same options.
- `babel/object-curly-spacing`: doesn't complain about `export x from "mod";` or `export * as x from "mod";` (🛠 )
- `babel/object-shorthand`: doesn't fail when using object spread (`...obj`)
- `babel/arrow-parens`: Handles async functions correctly (🛠 )
- `babel/no-invalid-this`: doesn't fail when inside class properties (`class A { a = this.b; }`)

The following rules are not in `eslint`, but are relevant only to syntax that is not specified by
the current JavaScript standard or supported by `eslint`.
Expand Down
15 changes: 0 additions & 15 deletions ast-utils.js
Expand Up @@ -9,8 +9,6 @@
// Requirements
//------------------------------------------------------------------------------

const esutils = require("esutils");

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
Expand Down Expand Up @@ -303,19 +301,6 @@ module.exports = {
);
},

/**
* Gets the trailing statement of a given node.
*
* if (code)
* consequent;
*
* When taking this `IfStatement`, returns `consequent;` statement.
*
* @param {ASTNode} A node to get.
* @returns {ASTNode|null} The trailing statement's node.
*/
getTrailingStatement: esutils.ast.trailingStatement,

/**
* Finds the variable by a given name in a given scope and its upper scopes.
*
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -29,6 +29,7 @@
"devDependencies": {
"babel-eslint": "^6.1.0",
"eslint": "^3.0.0",
"lodash.clonedeep": "^4.5.0",
"mocha": "^3.0.0"
}
}
23 changes: 22 additions & 1 deletion rules/no-invalid-this.js
Expand Up @@ -30,6 +30,8 @@ module.exports = {
const stack = [],
sourceCode = context.getSourceCode();

let insideClassProperty = false;

/**
* Gets the current checking context.
*
Expand All @@ -51,6 +53,23 @@ module.exports = {
return current;
};

/**
* `this` should be fair game anywhere inside a class property.
*
* @returns {void}
*/
function enterClassProperty() {
insideClassProperty = true;
}

/**
* Back to the normal check.
* @returns {void}
*/
function exitClassProperty() {
insideClassProperty = false;
}

/**
* Pushs new checking context into the stack.
*
Expand Down Expand Up @@ -104,6 +123,8 @@ module.exports = {
stack.pop();
},

ClassProperty: enterClassProperty,
"ClassProperty:exit": exitClassProperty,
FunctionDeclaration: enterFunction,
"FunctionDeclaration:exit": exitFunction,
FunctionExpression: enterFunction,
Expand All @@ -113,7 +134,7 @@ module.exports = {
ThisExpression(node) {
const current = stack.getCurrent();

if (current && !current.valid) {
if (!insideClassProperty && current && !current.valid) {
context.report(node, "Unexpected 'this'.");
}
}
Expand Down
21 changes: 19 additions & 2 deletions tests/rules/no-invalid-this.js
Expand Up @@ -9,7 +9,7 @@
// Requirements
//------------------------------------------------------------------------------

const lodash = require("lodash");
const cloneDeep = require("lodash.clonedeep");
const rule = require("../../rules/no-invalid-this");
const RuleTester = require("../RuleTester");

Expand Down Expand Up @@ -68,7 +68,7 @@ function extractPatterns(patterns, type) {
// Clone and apply the pattern environment.
const patternsList = patterns.map(function(pattern) {
return pattern[type].map(function(applyCondition) {
const thisPattern = lodash.cloneDeep(pattern);
const thisPattern = cloneDeep(pattern);

applyCondition(thisPattern);

Expand Down Expand Up @@ -582,6 +582,23 @@ const patterns = [
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES]
},

// babel/no-invalid-this

// Class Instance Properties.
{
code: "class A {a = this.b;};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: []
},

{
code: "class A {a = () => {return this.b;};};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: []
},
];

const ruleTester = new RuleTester();
Expand Down

0 comments on commit 7e00840

Please sign in to comment.