tslint-immutable
Advanced tools
Comparing version 5.5.2 to 6.0.0
19
all.json
@@ -8,15 +8,20 @@ { | ||
"readonly-keyword": true, | ||
"readonly-array": true, | ||
"no-array-mutation": true, | ||
"no-delete": true, | ||
"no-let": true, | ||
"no-method-signature": true, | ||
"no-object-mutation": true, | ||
"no-delete": true, | ||
"no-method-signature": true, | ||
"readonly-array": true, | ||
"readonly-keyword": true, | ||
"no-this": true, | ||
"no-class": true, | ||
"no-expression-statement": true, | ||
"no-if-statement": true, | ||
"no-loop-statement": true, | ||
"no-mixed-interface": true, | ||
"no-expression-statement": true, | ||
"no-if-statement": true | ||
"no-reject": true, | ||
"no-this": true, | ||
"no-throw": true, | ||
"no-try": true | ||
} | ||
} |
@@ -10,2 +10,6 @@ # Change Log | ||
## [v6.0.0] - 2019-06-05 | ||
* Overhaul ignore-prefix, adding in ignore-suffix and ignore-pattern. | ||
## [v5.5.2] - 2019-03-25 | ||
@@ -12,0 +16,0 @@ |
{ | ||
"name": "tslint-immutable", | ||
"version": "5.5.2", | ||
"version": "6.0.0", | ||
"description": "TSLint rules to disable mutation in TypeScript.", | ||
@@ -5,0 +5,0 @@ "main": "tslint-immutable.json", |
@@ -122,2 +122,4 @@ # tslint-immutable | ||
* [ignore-prefix](#using-the-ignore-prefix-option) | ||
* [ignore-suffix](#using-the-ignore-suffix-option) | ||
* [ignore-pattern](#using-the-ignore-pattern-option) | ||
@@ -177,2 +179,4 @@ #### Example config | ||
* [ignore-prefix](#using-the-ignore-prefix-option) | ||
* [ignore-suffix](#using-the-ignore-suffix-option) | ||
* [ignore-pattern](#using-the-ignore-pattern-option) | ||
* [ignore-return-type](#using-the-ignore-return-type-option) | ||
@@ -224,2 +228,4 @@ * [ignore-rest-parameters](#using-the-ignore-rest-parameters-option) | ||
* [ignore-prefix](#using-the-ignore-prefix-option) | ||
* [ignore-suffix](#using-the-ignore-suffix-option) | ||
* [ignore-pattern](#using-the-ignore-pattern-option) | ||
@@ -261,2 +267,4 @@ #### Example config | ||
* [ignore-prefix](#using-the-ignore-prefix-option) | ||
* [ignore-suffix](#using-the-ignore-suffix-option) | ||
* [ignore-pattern](#using-the-ignore-pattern-option) | ||
* [ignore-new-array](#using-the-ignore-new-array-option-with-no-array-mutation) | ||
@@ -301,2 +309,4 @@ * ~~ignore-mutation-following-accessor~~ - _deprecated in favor of [ignore-new-array](#using-the-ignore-new-array-option-with-no-array-mutation)_ | ||
* [ignore-prefix](#using-the-ignore-prefix-option) | ||
* [ignore-suffix](#using-the-ignore-suffix-option) | ||
* [ignore-pattern](#using-the-ignore-pattern-option) | ||
@@ -552,2 +562,25 @@ #### Example config | ||
### Using the `ignore-suffix` option | ||
Like ignore-prefix but with suffix matching instead of prefix matching. | ||
### Using the `ignore-pattern` option | ||
Like ignore-prefix and ignore-suffix but with more control. | ||
This option allows you to specify dot seperated paths what should be ignored. | ||
For example, the following config would ignore all object mutations for all properties that start with "mutable". | ||
```json | ||
{ | ||
"no-object-mutation": [true, { "ignore-pattern": "**.mutable*" }] | ||
} | ||
``` | ||
The following wildcards can be used when specifing a pattern: | ||
* `**` - Match any depth (including zero). Can only be used as a full accessor. | ||
* `*` - When used as a full accessor, match the next accessor. When used as part of an accessor, match any characters. | ||
### Using the `ignore-prefix` option with `no-expression-statement` | ||
@@ -554,0 +587,0 @@ |
@@ -82,3 +82,3 @@ "use strict"; | ||
function checkBinaryExpression(node, ctx, checker) { | ||
if (!Ignore.isIgnoredPrefix(node.getText(node.getSourceFile()), ctx.options.ignorePrefix) && | ||
if (!Ignore.isIgnored(node.left, ctx.options.ignorePattern, ctx.options.ignorePrefix, ctx.options.ignoreSuffix) && | ||
util_1.isAssignmentKind(node.operatorToken.kind) && | ||
@@ -97,3 +97,3 @@ typeguard_1.isAccessExpression(node.left)) { | ||
function checkDeleteExpression(node, ctx, checker) { | ||
if (!Ignore.isIgnoredPrefix(node.expression.getText(node.getSourceFile()), ctx.options.ignorePrefix) && | ||
if (!Ignore.isIgnored(node.expression, ctx.options.ignorePattern, ctx.options.ignorePrefix, ctx.options.ignoreSuffix) && | ||
typeguard_1.isAccessExpression(node.expression)) { | ||
@@ -111,3 +111,3 @@ var expressionType = checker.getTypeAtLocation(getRootAccessExpression(node.expression).expression); | ||
function checkPrefixUnaryExpression(node, ctx, checker) { | ||
if (!Ignore.isIgnoredPrefix(node.operand.getText(node.getSourceFile()), ctx.options.ignorePrefix) && | ||
if (!Ignore.isIgnored(node.operand, ctx.options.ignorePattern, ctx.options.ignorePrefix, ctx.options.ignoreSuffix) && | ||
typeguard_1.isAccessExpression(node.operand) && | ||
@@ -126,3 +126,3 @@ forbidUnaryOps.some(function (o) { return o === node.operator; })) { | ||
function checkPostfixUnaryExpression(node, ctx, checker) { | ||
if (!Ignore.isIgnoredPrefix(node.getText(node.getSourceFile()), ctx.options.ignorePrefix) && | ||
if (!Ignore.isIgnored(node.operand, ctx.options.ignorePattern, ctx.options.ignorePrefix, ctx.options.ignoreSuffix) && | ||
typeguard_1.isAccessExpression(node.operand) && | ||
@@ -141,3 +141,3 @@ forbidUnaryOps.some(function (o) { return o === node.operator; })) { | ||
function checkCallExpression(node, ctx, checker) { | ||
if (!Ignore.isIgnoredPrefix(node.getText(node.getSourceFile()), ctx.options.ignorePrefix) && | ||
if (!Ignore.isIgnored(node.expression, ctx.options.ignorePattern, ctx.options.ignorePrefix, ctx.options.ignoreSuffix) && | ||
utils.isPropertyAccessExpression(node.expression) && | ||
@@ -144,0 +144,0 @@ (!(ctx.options.ignoreNewArray || ctx.options.ignoreMutationFollowingAccessor) || |
@@ -13,8 +13,4 @@ "use strict"; | ||
var isYield = children.every(function (n) { return n.kind === ts.SyntaxKind.YieldExpression; }); | ||
var text = node.getText(node.getSourceFile()); | ||
if (utils.isAwaitExpression(node.expression)) { | ||
text = node.expression.expression.getText(node.expression.getSourceFile()); | ||
} | ||
var isIgnored2 = Ignore.isIgnoredPrefix(text, ctx.options.ignorePrefix); | ||
if (!isYield && !isIgnored2) { | ||
var isIgnored = Ignore.isIgnored(node.expression, ctx.options.ignorePattern, ctx.options.ignorePrefix, ctx.options.ignoreSuffix); | ||
if (!isYield && !isIgnored) { | ||
return { invalidNodes: [check_node_1.createInvalidNode(node, [])] }; | ||
@@ -21,0 +17,0 @@ } |
@@ -50,3 +50,3 @@ "use strict"; | ||
var variableDeclarationNode = _a[_i]; | ||
if (!Ignore.shouldIgnorePrefix(variableDeclarationNode, ctx.options, ctx.sourceFile)) { | ||
if (!Ignore.shouldIgnore(variableDeclarationNode, ctx.options, ctx.sourceFile)) { | ||
invalidVariableDeclarationNodes.push(check_node_1.createInvalidNode(variableDeclarationNode, addFix | ||
@@ -53,0 +53,0 @@ ? [ |
@@ -20,5 +20,4 @@ "use strict"; | ||
typeguard_1.isAccessExpression(node.left) && | ||
utils.isBinaryExpression(node) && | ||
util_1.isAssignmentKind(node.operatorToken.kind) && | ||
!Ignore.isIgnoredPrefix(node.getText(node.getSourceFile()), ctx.options.ignorePrefix) && | ||
!Ignore.isIgnored(node.left, ctx.options.ignorePattern, ctx.options.ignorePrefix, ctx.options.ignoreSuffix) && | ||
!inConstructor(node)) { | ||
@@ -30,3 +29,3 @@ invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node, [])]); | ||
typeguard_1.isAccessExpression(node.expression) && | ||
!Ignore.isIgnoredPrefix(node.expression.getText(node.getSourceFile()), ctx.options.ignorePrefix)) { | ||
!Ignore.isIgnored(node.expression, ctx.options.ignorePattern, ctx.options.ignorePrefix, ctx.options.ignoreSuffix)) { | ||
invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node, [])]); | ||
@@ -38,3 +37,3 @@ } | ||
forbidUnaryOps.some(function (o) { return o === node.operator; }) && | ||
!Ignore.isIgnoredPrefix(node.operand.getText(node.getSourceFile()), ctx.options.ignorePrefix)) { | ||
!Ignore.isIgnored(node.operand, ctx.options.ignorePattern, ctx.options.ignorePrefix, ctx.options.ignoreSuffix)) { | ||
invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node, [])]); | ||
@@ -46,3 +45,3 @@ } | ||
forbidUnaryOps.some(function (o) { return o === node.operator; }) && | ||
!Ignore.isIgnoredPrefix(node.getText(node.getSourceFile()), ctx.options.ignorePrefix)) { | ||
!Ignore.isIgnored(node.operand, ctx.options.ignorePattern, ctx.options.ignorePrefix, ctx.options.ignoreSuffix)) { | ||
invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node, [])]); | ||
@@ -58,3 +57,3 @@ } | ||
utils.isPropertyAccessExpression(node.arguments[0])) && | ||
!Ignore.isIgnoredPrefix(node.arguments[0].getText(node.arguments[0].getSourceFile()), ctx.options.ignorePrefix) && | ||
!Ignore.isIgnored(node.arguments[0], ctx.options.ignorePattern, ctx.options.ignorePrefix, ctx.options.ignoreSuffix) && | ||
// Do type checking as late as possible as it is expensive. | ||
@@ -61,0 +60,0 @@ isObjectConstructorType(checker.getTypeAtLocation(node.expression.expression))) { |
@@ -33,3 +33,3 @@ "use strict"; | ||
if (node.parent && | ||
Ignore.shouldIgnorePrefix(node.parent, ctx.options, ctx.sourceFile)) { | ||
Ignore.shouldIgnore(node.parent, ctx.options, ctx.sourceFile)) { | ||
return { | ||
@@ -67,3 +67,3 @@ invalidNodes: [], | ||
if (node.parent && | ||
Ignore.shouldIgnorePrefix(node.parent, ctx.options, ctx.sourceFile)) { | ||
Ignore.shouldIgnore(node.parent, ctx.options, ctx.sourceFile)) { | ||
return { | ||
@@ -88,3 +88,3 @@ invalidNodes: [], | ||
function checkImplicitType(node, ctx) { | ||
if (Ignore.shouldIgnorePrefix(node, ctx.options, ctx.sourceFile)) { | ||
if (Ignore.shouldIgnore(node, ctx.options, ctx.sourceFile)) { | ||
return { | ||
@@ -91,0 +91,0 @@ invalidNodes: [], |
@@ -25,3 +25,3 @@ "use strict"; | ||
// Check if ignore-prefix applies | ||
if (Ignore.shouldIgnorePrefix(node, ctx.options, ctx.sourceFile)) { | ||
if (Ignore.shouldIgnore(node, ctx.options, ctx.sourceFile)) { | ||
return { invalidNodes: [] }; | ||
@@ -28,0 +28,0 @@ } |
@@ -7,2 +7,3 @@ "use strict"; | ||
var ts = require("typescript"); | ||
var utils_1 = require("tslint/lib/utils"); | ||
var utils = require("tsutils/typeguard/2.8"); | ||
@@ -68,22 +69,33 @@ var typeguard_1 = require("./typeguard"); | ||
} | ||
function shouldIgnorePrefix(node, options, sourceFile) { | ||
// Check ignore-prefix for VariableLikeDeclaration, TypeAliasDeclaration | ||
if (options.ignorePrefix) { | ||
if (node && | ||
(typeguard_1.isVariableLikeDeclaration(node) || utils.isTypeAliasDeclaration(node))) { | ||
var variableText = node.name.getText(sourceFile); | ||
// if ( | ||
// variableText.substr(0, options.ignorePrefix.length) === | ||
// options.ignorePrefix | ||
// ) { | ||
// return true; | ||
// } | ||
if (isIgnoredPrefix(variableText, options.ignorePrefix)) { | ||
return true; | ||
} | ||
function shouldIgnore(node, options, sourceFile) { | ||
// Check ignore for VariableLikeDeclaration, TypeAliasDeclaration | ||
if (node && | ||
(typeguard_1.isVariableLikeDeclaration(node) || utils.isTypeAliasDeclaration(node))) { | ||
var variableText = node.name.getText(sourceFile); | ||
if (isIgnoredPattern(variableText, options.ignorePattern)) { | ||
return true; | ||
} | ||
if (isIgnoredPrefix(variableText, options.ignorePrefix)) { | ||
return true; | ||
} | ||
if (isIgnoredSuffix(variableText, options.ignoreSuffix)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
exports.shouldIgnorePrefix = shouldIgnorePrefix; | ||
exports.shouldIgnore = shouldIgnore; | ||
function isIgnored(node, ignorePattern, ignorePrefix, ignoreSuffix) { | ||
var text = node.getText(); | ||
if (isIgnoredPrefix(text, ignorePrefix) || | ||
isIgnoredSuffix(text, ignoreSuffix) || | ||
isIgnoredPattern(node.getText(), ignorePattern)) { | ||
return true; | ||
} | ||
if (typeguard_1.hasExpression(node)) { | ||
return isIgnored(node.expression, undefined, ignorePrefix, ignoreSuffix); | ||
} | ||
return false; | ||
} | ||
exports.isIgnored = isIgnored; | ||
function isIgnoredPrefix(text, ignorePrefix) { | ||
@@ -105,3 +117,68 @@ if (!ignorePrefix) { | ||
} | ||
exports.isIgnoredPrefix = isIgnoredPrefix; | ||
function isIgnoredSuffix(text, ignoreSuffix) { | ||
if (!ignoreSuffix) { | ||
return false; | ||
} | ||
if (Array.isArray(ignoreSuffix)) { | ||
if (ignoreSuffix.find(function (sfx) { | ||
var indexToFindAt = text.length - sfx.length; | ||
return indexToFindAt >= 0 && text.indexOf(sfx) === indexToFindAt; | ||
})) { | ||
return true; | ||
} | ||
} | ||
else { | ||
var indexToFindAt = text.length - ignoreSuffix.length; | ||
if (indexToFindAt >= 0 && text.indexOf(ignoreSuffix) === indexToFindAt) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
function isIgnoredPattern(text, ignorePattern) { | ||
if (!ignorePattern) { | ||
return false; | ||
} | ||
var patterns = Array.isArray(ignorePattern) | ||
? ignorePattern | ||
: [ignorePattern]; | ||
var findMatch = function (patternParts, textParts) { | ||
var index = 0; | ||
for (; index < patternParts.length; index++) { | ||
// Out of text? | ||
if (index >= textParts.length) { | ||
return false; | ||
} | ||
switch (patternParts[index]) { | ||
// Match any depth (including 0)? | ||
case "**": | ||
var subpattern = patternParts.slice(index + 1); | ||
for (var offset = index; offset < textParts.length; offset++) { | ||
var submatch = findMatch(subpattern, textParts.slice(offset)); | ||
if (submatch) { | ||
return submatch; | ||
} | ||
} | ||
return false; | ||
// Match anything? | ||
case "*": | ||
continue; | ||
default: | ||
break; | ||
} | ||
// textParts[i] matches patternParts[i]? | ||
if (new RegExp("^" + utils_1.escapeRegExp(patternParts[index]).replace(/\\\*/g, ".*") + "$").test(textParts[index])) { | ||
continue; | ||
} | ||
// No Match. | ||
return false; | ||
} | ||
// Match. | ||
return textParts.length === index; | ||
}; | ||
// One or more patterns match? | ||
return patterns.some(function (pattern) { | ||
return findMatch(pattern.split("."), text.split(".")); | ||
}); | ||
} | ||
//# sourceMappingURL=ignore.js.map |
@@ -39,2 +39,6 @@ "use strict"; | ||
exports.isVariableOrParameterOrPropertyDeclaration = isVariableOrParameterOrPropertyDeclaration; | ||
function hasExpression(node) { | ||
return Object.prototype.hasOwnProperty.call(node, "expression"); | ||
} | ||
exports.hasExpression = hasExpression; | ||
//# sourceMappingURL=typeguard.js.map |
{ | ||
"rulesDirectory": "./rules", | ||
"rules": { | ||
"no-array-mutation": false, | ||
"no-class": false, | ||
@@ -13,6 +14,9 @@ "no-delete": false, | ||
"no-object-mutation": false, | ||
"no-reject": false, | ||
"no-this": false, | ||
"readonly-keyword": false, | ||
"readonly-array": false | ||
"no-throw": false, | ||
"no-try": false, | ||
"readonly-array": false, | ||
"readonly-keyword": false | ||
} | ||
} |
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
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
127503
1087
713