New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

tslint-immutable

Package Overview
Dependencies
Maintainers
1
Versions
56
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tslint-immutable - npm Package Compare versions

Comparing version 3.3.1 to 3.3.2

rules/readonly-shared.js

7

CHANGELOG.md

@@ -9,2 +9,6 @@ # Change Log

## [v3.3.2] - 2017-05-13
### Fixed
- Functions in interfaces cannot have readonly specified but are still checked [#28](https://github.com/jonaskello/tslint-immutable/issues/28)
## [v3.3.1] - 2017-05-09

@@ -87,3 +91,4 @@ ### Fixed

[Unreleased]: https://github.com/jonaskello/tslint-immutable/compare/v3.3.1...master
[Unreleased]: https://github.com/jonaskello/tslint-immutable/compare/v3.3.2...master
[v3.3.2]: https://github.com/jonaskello/tslint-immutable/compare/v3.3.1...v3.3.2
[v3.3.1]: https://github.com/jonaskello/tslint-immutable/compare/v3.3.0...v3.3.1

@@ -90,0 +95,0 @@ [v3.3.0]: https://github.com/jonaskello/tslint-immutable/compare/v3.2.0...v3.3.0

2

package.json
{
"name": "tslint-immutable",
"version": "3.3.1",
"version": "3.3.2",
"description": "TSLint rules to disable mutation in TypeScript.",

@@ -5,0 +5,0 @@ "main": "tslint-immutable.json",

@@ -15,2 +15,3 @@ "use strict";

var Lint = require("tslint");
var Shared = require("./readonly-shared");
var Rule = (function (_super) {

@@ -22,71 +23,12 @@ __extends(Rule, _super);

Rule.prototype.apply = function (sourceFile) {
return this.applyWithFunction(sourceFile, walk, parseOptions(this.ruleArguments));
return this.applyWithFunction(sourceFile, function (ctx) { return Shared.walk(ctx, checkNode, "Only ReadonlyArray allowed."); }, Shared.parseOptions(this.ruleArguments));
};
return Rule;
}(Lint.Rules.AbstractRule));
Rule.FAILURE_STRING = "Only ReadonlyArray allowed.";
exports.Rule = Rule;
var OPTION_IGNORE_LOCAL = "ignore-local";
var OPTION_IGNORE_PREFIX = "ignore-prefix";
function createInvalidNode(node, replacement) {
return { node: node, replacement: replacement };
}
function parseOptions(options) {
var ignoreLocal = options.indexOf(OPTION_IGNORE_LOCAL) !== -1;
var ignorePrefix;
for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
var o = options_1[_i];
if (typeof o === "object" && o[OPTION_IGNORE_PREFIX] !== null) {
ignorePrefix = o[OPTION_IGNORE_PREFIX];
break;
}
}
return { ignoreLocal: ignoreLocal, ignorePrefix: ignorePrefix };
}
function walk(ctx) {
return ts.forEachChild(ctx.sourceFile, cb);
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 || node.kind === ts.SyntaxKind.FunctionExpression)) {
// We still need to check the parameters and return type
var functionNode = node; //tslint:disable-line
var invalidNodes = checkIgnoreLocalFunctionNode(functionNode, ctx);
invalidNodes.forEach(function (n) { return reportInvalidNode(n, ctx); });
// Now skip this whole branch
return;
}
// Check the node
reportInvalidNode(checkNode(node, ctx), 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) {
return checkArrayTypeOrReference(node, ctx) || checkVariableOrParameterImplicitType(node, ctx);
var explicitTypeFailures = checkArrayTypeOrReference(node, ctx);
var implicitTypeFailures = checkVariableOrParameterImplicitType(node, ctx);
return explicitTypeFailures.concat(implicitTypeFailures);
}
function reportInvalidNode(invalidNode, ctx) {
if (invalidNode) {
ctx.addFailureAtNode(invalidNode.node, Rule.FAILURE_STRING, invalidNode.replacement);
}
}
function checkIgnoreLocalFunctionNode(functionNode, ctx) {
var invalidNodes = [];
// Check either the parameter's explicit type if it has one, or itself for implict type
for (var _i = 0, _a = functionNode.parameters.map(function (p) { return p.type ? p.type : p; }); _i < _a.length; _i++) {
var n = _a[_i];
var invalidNode = checkNode(n, ctx);
if (invalidNode) {
invalidNodes.push(invalidNode);
}
}
// Check the return type
if (functionNode.type) {
var invalidNode = checkNode(functionNode.type, ctx);
if (invalidNode) {
invalidNodes.push(invalidNode);
}
}
return invalidNodes;
}
function checkArrayTypeOrReference(node, ctx) {

@@ -96,4 +38,4 @@ // We need to check both shorthand syntax "number[]" and type reference "Array<number>"

|| (node.kind === ts.SyntaxKind.TypeReference && node.typeName.getText(ctx.sourceFile) === "Array")) {
if (node.parent && shouldIgnorePrefix(node.parent, ctx.options, ctx.sourceFile)) {
return undefined;
if (node.parent && Shared.shouldIgnorePrefix(node.parent, ctx.options, ctx.sourceFile)) {
return [];
}

@@ -112,5 +54,5 @@ var typeArgument = "T";

var length_1 = node.getWidth(ctx.sourceFile);
return createInvalidNode(node, new Lint.Replacement(node.end - length_1, length_1, "ReadonlyArray<" + typeArgument + ">"));
return [Shared.createInvalidNode(node, new Lint.Replacement(node.end - length_1, length_1, "ReadonlyArray<" + typeArgument + ">"))];
}
return undefined;
return [];
}

@@ -121,4 +63,4 @@ function checkVariableOrParameterImplicitType(node, ctx) {

var varOrParamNode = node;
if (shouldIgnorePrefix(node, ctx.options, ctx.sourceFile)) {
return undefined;
if (Shared.shouldIgnorePrefix(node, ctx.options, ctx.sourceFile)) {
return [];
}

@@ -142,22 +84,7 @@ if (!varOrParamNode.type) {

// }
return createInvalidNode(varOrParamNode.name, new Lint.Replacement(varOrParamNode.name.end - length_2, length_2, nameText + ": ReadonlyArray<" + typeArgument + ">"));
return [Shared.createInvalidNode(varOrParamNode.name, new Lint.Replacement(varOrParamNode.name.end - length_2, length_2, nameText + ": ReadonlyArray<" + typeArgument + ">"))];
}
}
}
return undefined;
return [];
}
function shouldIgnorePrefix(node, options, sourceFile) {
// Check ignore-prefix for VariableDeclaration, PropertySignature, TypeAliasDeclaration, Parameter
if (options.ignorePrefix) {
if (node && (node.kind === ts.SyntaxKind.VariableDeclaration
|| node.kind === ts.SyntaxKind.Parameter
|| node.kind === ts.SyntaxKind.PropertySignature
|| node.kind === ts.SyntaxKind.TypeAliasDeclaration)) {
var variableDeclarationNode = node;
if (variableDeclarationNode.name.getText(sourceFile).substr(0, options.ignorePrefix.length) === options.ignorePrefix) {
return true;
}
}
}
return false;
}

@@ -15,2 +15,3 @@ "use strict";

var Lint = require("tslint");
var Shared = require("./readonly-shared");
var Rule = (function (_super) {

@@ -22,38 +23,28 @@ __extends(Rule, _super);

Rule.prototype.apply = function (sourceFile) {
var walker = new ReadonlyInterfaceWalker(sourceFile, this.getOptions());
return this.applyWithWalker(walker);
return this.applyWithFunction(sourceFile, function (ctx) { return Shared.walk(ctx, checkNode, "Interface members must have readonly modifier."); }, Shared.parseOptions(this.ruleArguments));
};
return Rule;
}(Lint.Rules.AbstractRule));
Rule.FAILURE_STRING = "Interface members must have readonly modifier.";
Rule.FAILURE_STRING_ARRAY = "Interface members of array type must be ReadonlyArray.";
exports.Rule = Rule;
var ReadonlyInterfaceWalker = (function (_super) {
__extends(ReadonlyInterfaceWalker, _super);
function ReadonlyInterfaceWalker() {
return _super !== null && _super.apply(this, arguments) || this;
}
ReadonlyInterfaceWalker.prototype.visitInterfaceDeclaration = function (node) {
for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
function checkNode(node, ctx) {
return checkInterfaceDeclaration(node, ctx);
}
function checkInterfaceDeclaration(node, ctx) {
if (node.kind === ts.SyntaxKind.InterfaceDeclaration) {
var interfaceDeclarationNode = node;
var invalidNodes = [];
for (var _i = 0, _a = interfaceDeclarationNode.members; _i < _a.length; _i++) {
var member = _a[_i];
if (!(member.modifiers && member.modifiers.filter(function (m) { return m.kind === ts.SyntaxKind.ReadonlyKeyword; }).length > 0)) {
this.addFailure(this.createFailure(member.getStart(), member.getWidth(), Rule.FAILURE_STRING));
// readonly modifier is only allowed for PropertySignature and IndexSignature
if (member.kind === ts.SyntaxKind.PropertySignature || member.kind === ts.SyntaxKind.IndexSignature) {
if (!(member.modifiers && member.modifiers.filter(function (m) { return m.kind === ts.SyntaxKind.ReadonlyKeyword; }).length > 0)) {
var length_1 = member.getWidth(ctx.sourceFile);
var memberName = member.name;
invalidNodes.push(Shared.createInvalidNode(member, new Lint.Replacement(node.end - length_1, length_1, "readonly " + memberName)));
}
}
// interface Foo {
// readonly bar: number,
// readonly zoo: () => string
// readonly loo: Array<string>,
// readonly <T1>(): Array<T1>
// }
// let f: Foo;
// f.zoo = () => "";
// console.log("member.type", (member as any).type);
//
// if (member.kind === ts.SyntaxKind.ArrayType) {
// this.addFailure(this.createFailure(member.getStart(), member.getWidth(), Rule.FAILURE_STRING_ARRAY));
// }
}
_super.prototype.visitInterfaceDeclaration.call(this, node);
};
return ReadonlyInterfaceWalker;
}(Lint.RuleWalker));
return invalidNodes;
}
return [];
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc