tslint-immutable
Advanced tools
Comparing version 3.1.0 to 3.1.1
@@ -10,6 +10,11 @@ # Change Log | ||
## [v3.1.1] - 2017-04-05 | ||
### Fixed | ||
- Function parameters are not checked when using ignore-local option, [#13](https://github.com/jonaskello/tslint-immutable/issues/13). | ||
- Implicit Array type by default value for function parameter is not checked, [#14](https://github.com/jonaskello/tslint-immutable/issues/14). | ||
## [v3.1.0] - 2017-04-05 | ||
### Added | ||
- `ignore-local` option added to `readonly-array`. | ||
- `ignore-prefix` option added to `readonly-array`. | ||
- [`ignore-local`](https://github.com/jonaskello/tslint-immutable#using-the-ignore-local-option) option added to `readonly-array`. | ||
- [`ignore-prefix`](https://github.com/jonaskello/tslint-immutable#using-the-ignore-local-option) option added to `readonly-array`. | ||
@@ -57,4 +62,5 @@ ## [v3.0.0] - 2017-04-02 | ||
[Unreleased]: https://github.com/jonaskello/tslint-immutable/compare/v3.1.0...master | ||
[v3.0.0]: https://github.com/jonaskello/tslint-immutable/compare/v3.0.0...v3.1.0 | ||
[Unreleased]: https://github.com/jonaskello/tslint-immutable/compare/v3.1.1...master | ||
[v3.1.1]: https://github.com/jonaskello/tslint-immutable/compare/v3.1.0...v3.1.1 | ||
[v3.1.0]: https://github.com/jonaskello/tslint-immutable/compare/v3.0.0...v3.1.0 | ||
[v3.0.0]: https://github.com/jonaskello/tslint-immutable/compare/v2.1.1...v3.0.0 | ||
@@ -61,0 +67,0 @@ [v2.1.2]: https://github.com/jonaskello/tslint-immutable/compare/v2.1.1...v2.1.2 |
{ | ||
"name": "tslint-immutable", | ||
"version": "3.1.0", | ||
"version": "3.1.1", | ||
"description": "TSLint rules to disable mutation in TypeScript.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -23,2 +23,4 @@ # tslint-immutable | ||
See the [example](#sample-configuration-file) tslint.json file for configuration. | ||
## Compability | ||
@@ -231,4 +233,6 @@ | ||
The quote above is from the [clojure docs](https://clojure.org/reference/transients). In general, it is more important to enforce immutability for state that is passed in and out of functions than for local state used for internal calculations within a function. For example in Redux, the state going in and out of reducers needs to be immutable while the reducer may be allowed to mutate local state in its calculations in order to achieve higher performance. This is what the `ignore-local` option enables. With this option enabled immutability will be enforced everywhere but in local state. | ||
The quote above is from the [clojure docs](https://clojure.org/reference/transients). In general, it is more important to enforce immutability for state that is passed in and out of functions than for local state used for internal calculations within a function. For example in Redux, the state going in and out of reducers needs to be immutable while the reducer may be allowed to mutate local state in its calculations in order to achieve higher performance. This is what the `ignore-local` option enables. With this option enabled immutability will be enforced everywhere but in local state. Function parameters are not considered local state so they will still be checked. | ||
Note that using this option can lead to more imperative code in functions so use with care! | ||
### Using the `ignore-prefix` option | ||
@@ -235,0 +239,0 @@ |
@@ -44,16 +44,38 @@ "use strict"; | ||
function cb(node) { | ||
// Skip checking in functions if ignore-local is set | ||
if (ctx.options.ignoreLocal && (node.kind === ts.SyntaxKind.FunctionDeclaration || node.kind === ts.SyntaxKind.ArrowFunction)) { | ||
// skip checking in functions if ignore-local is set | ||
// We still need to check the parameters which resides in the SyntaxList node | ||
for (var _i = 0, _a = node.getChildren(ctx.sourceFile); _i < _a.length; _i++) { | ||
var child1 = _a[_i]; | ||
if (child1.kind === ts.SyntaxKind.SyntaxList) { | ||
for (var _b = 0, _c = child1.getChildren(ctx.sourceFile); _b < _c.length; _b++) { | ||
var child2 = _c[_b]; | ||
if (child2.kind === ts.SyntaxKind.Parameter) { | ||
for (var _d = 0, _e = child2.getChildren(ctx.sourceFile).filter(function (child) { | ||
return child.kind === ts.SyntaxKind.ArrayLiteralExpression || child.kind === ts.SyntaxKind.TypeReference; | ||
}); _d < _e.length; _d++) { | ||
var child3 = _e[_d]; | ||
checkNode(child3, ctx); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return; | ||
} | ||
if (node.kind === ts.SyntaxKind.TypeReference && isInvalidArrayTypeReference(node, ctx)) { | ||
ctx.addFailureAtNode(node, Rule.FAILURE_STRING); | ||
} | ||
if (node.kind === ts.SyntaxKind.ArrayLiteralExpression && isInvalidArrayLiteralExpression(node, ctx)) { | ||
var variableDeclarationNode = node.parent; | ||
ctx.addFailureAt(variableDeclarationNode.name.getStart(ctx.sourceFile), variableDeclarationNode.name.getWidth(ctx.sourceFile), Rule.FAILURE_STRING); | ||
} | ||
// Check the node | ||
checkNode(node, ctx); | ||
// Use return becuase performance hints docs say it optimizes the function using tail-call recursion | ||
return ts.forEachChild(node, cb); | ||
} | ||
} | ||
function checkNode(node, ctx) { | ||
if (node.kind === ts.SyntaxKind.TypeReference && isInvalidArrayTypeReference(node, ctx)) { | ||
ctx.addFailureAtNode(node, Rule.FAILURE_STRING); | ||
} | ||
if (node.kind === ts.SyntaxKind.ArrayLiteralExpression && isInvalidArrayLiteralExpression(node, ctx)) { | ||
var variableDeclarationNode = node.parent; | ||
ctx.addFailureAt(variableDeclarationNode.name.getStart(ctx.sourceFile), variableDeclarationNode.name.getWidth(ctx.sourceFile), Rule.FAILURE_STRING); | ||
} | ||
} | ||
function isInvalidArrayTypeReference(node, ctx) { | ||
@@ -74,7 +96,8 @@ if (node.typeName.getText(ctx.sourceFile) === "Array") { | ||
// must have a type spcecified, otherwise it will implicitly be of mutable Array type | ||
if (node.parent && node.parent.kind === ts.SyntaxKind.VariableDeclaration) { | ||
var variableDeclarationNode = node.parent; | ||
if (!variableDeclarationNode.type) { | ||
// It could also be a function parameter that has an array literal as default value | ||
if (node.parent && (node.parent.kind === ts.SyntaxKind.VariableDeclaration || node.parent.kind === ts.SyntaxKind.Parameter)) { | ||
var parent_1 = node.parent; | ||
if (!parent_1.type) { | ||
if (ctx.options.ignorePrefix && | ||
variableDeclarationNode.name.getText(ctx.sourceFile).substr(0, ctx.options.ignorePrefix.length) === ctx.options.ignorePrefix) { | ||
parent_1.name.getText(ctx.sourceFile).substr(0, ctx.options.ignorePrefix.length) === ctx.options.ignorePrefix) { | ||
return false; | ||
@@ -81,0 +104,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
79850
63
890
306