UNPKG

tslint-immutable

Version:

TSLint rules to disable mutation in TypeScript.

75 lines 3.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var ts = require("typescript"); var utils = require("tsutils/typeguard/2.8"); var util_1 = require("tsutils/util"); var check_node_1 = require("./shared/check-node"); var Ignore = require("./shared/ignore"); var typeguard_1 = require("./shared/typeguard"); // tslint:disable-next-line:variable-name exports.Rule = check_node_1.createCheckNodeTypedRule(checkNode, "Modifying properties of existing object not allowed."); var forbidUnaryOps = [ ts.SyntaxKind.PlusPlusToken, ts.SyntaxKind.MinusMinusToken ]; function checkNode(node, ctx, checker) { var invalidNodes = []; // No assignment with object.property on the left if (utils.isBinaryExpression(node) && typeguard_1.isAccessExpression(node.left) && utils.isBinaryExpression(node) && util_1.isAssignmentKind(node.operatorToken.kind) && !Ignore.isIgnoredPrefix(node.getText(node.getSourceFile()), ctx.options.ignorePrefix) && !inConstructor(node)) { invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node, [])]); } // No deleting object properties if (utils.isDeleteExpression(node) && typeguard_1.isAccessExpression(node.expression) && !Ignore.isIgnoredPrefix(node.expression.getText(node.getSourceFile()), ctx.options.ignorePrefix)) { invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node, [])]); } // No prefix inc/dec if (utils.isPrefixUnaryExpression(node) && typeguard_1.isAccessExpression(node.operand) && forbidUnaryOps.some(function (o) { return o === node.operator; }) && !Ignore.isIgnoredPrefix(node.operand.getText(node.getSourceFile()), ctx.options.ignorePrefix)) { invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node, [])]); } // No postfix inc/dec if (utils.isPostfixUnaryExpression(node) && typeguard_1.isAccessExpression(node.operand) && forbidUnaryOps.some(function (o) { return o === node.operator; }) && !Ignore.isIgnoredPrefix(node.getText(node.getSourceFile()), ctx.options.ignorePrefix)) { invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node, [])]); } // No Object.assign on identifiers. if (utils.isCallExpression(node) && utils.isPropertyAccessExpression(node.expression) && utils.isIdentifier(node.expression.name) && node.expression.name.text === "assign" && node.arguments.length >= 2 && (utils.isIdentifier(node.arguments[0]) || utils.isPropertyAccessExpression(node.arguments[0])) && !Ignore.isIgnoredPrefix(node.arguments[0].getText(node.arguments[0].getSourceFile()), ctx.options.ignorePrefix) && // Do type checking as late as possible as it is expensive. isObjectConstructorType(checker.getTypeAtLocation(node.expression.expression))) { invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node, [])]); } return { invalidNodes: invalidNodes }; } function inConstructor(nodeIn) { var node = nodeIn.parent; while (node) { if (utils.isConstructorDeclaration(node)) { return true; } node = node.parent; } return false; } function isObjectConstructorType(type) { return Boolean(type.symbol && type.symbol.name === "ObjectConstructor"); } exports.isObjectConstructorType = isObjectConstructorType; //# sourceMappingURL=noObjectMutationRule.js.map