tslint-immutable
Version:
TSLint rules to disable mutation in TypeScript.
432 lines (431 loc) • 12.9 kB
HTML
<html lang="en">
<head>
<title>Code coverage report for readonlyArrayRule.ts</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="prettify.css" />
<link rel="stylesheet" href="base.css" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1>
<a href="index.html">All files</a> readonlyArrayRule.ts
</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">100% </span>
<span class="quiet">Statements</span>
<span class='fraction'>33/33</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">92.86% </span>
<span class="quiet">Branches</span>
<span class='fraction'>26/28</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">100% </span>
<span class="quiet">Functions</span>
<span class='fraction'>3/3</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">100% </span>
<span class="quiet">Lines</span>
<span class='fraction'>33/33</span>
</div>
</div>
</div>
<div class='status-line high'></div>
<pre><table class="coverage">
<tr><td class="line-count quiet">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123</td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">962x</span>
<span class="cline-any cline-yes">962x</span>
<span class="cline-any cline-yes">962x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">962x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">80x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">15x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">65x</span>
<span class="cline-any cline-yes">65x</span>
<span class="cline-any cline-yes">7x</span>
<span class="cline-any cline-yes">7x</span>
<span class="cline-any cline-yes">58x</span>
<span class="cline-any cline-yes">58x</span>
<span class="cline-any cline-yes">58x</span>
<span class="cline-any cline-yes">58x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">65x</span>
<span class="cline-any cline-yes">65x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">882x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">962x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">87x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">87x</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">79x</span>
<span class="cline-any cline-yes">34x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">16x</span>
<span class="cline-any cline-yes">16x</span>
<span class="cline-any cline-yes">16x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">16x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">938x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import * as ts from "typescript";
import * as Lint from "tslint";
import * as Ignore from "./shared/ignore";
import {
InvalidNode,
createInvalidNode,
CheckNodeResult,
createCheckNodeRule
} from "./shared/check-node";
type Options = Ignore.IgnoreLocalOption & Ignore.IgnorePrefixOption;
// tslint:disable-next-line:variable-name
export const Rule = createCheckNodeRule(
Ignore.checkNodeWithIgnore(checkNode),
"Only ReadonlyArray allowed."
);
function checkNode(
node: ts.Node,
ctx: Lint.WalkContext<Options>
): CheckNodeResult {
const explicitTypeFailures = checkArrayTypeOrReference(node, ctx);
const implicitTypeFailures = checkVariableOrParameterImplicitType(node, ctx);
return { invalidNodes: explicitTypeFailures.concat(implicitTypeFailures) };
}
function checkArrayTypeOrReference(
node: ts.Node,
ctx: Lint.WalkContext<Options>
): ReadonlyArray<InvalidNode> {
// We need to check both shorthand syntax "number[]" and type reference "Array<number>"
if (
node.kind === ts.SyntaxKind.ArrayType ||
(node.kind === ts.SyntaxKind.TypeReference &&
(node as ts.TypeReferenceNode).typeName.getText(ctx.sourceFile) ===
"Array")
) {
if (
node.parent &&
Ignore.shouldIgnorePrefix(node.parent, ctx.options, ctx.sourceFile)
) {
return [];
}
let typeArgument: string = "T";
if (node.kind === ts.SyntaxKind.ArrayType) {
const typeNode = node as ts.ArrayTypeNode;
typeArgument = typeNode.elementType.getFullText(ctx.sourceFile).trim();
} else <span class="missing-if-branch" title="else path not taken" >E</span>if (node.kind === ts.SyntaxKind.TypeReference) {
const typeNode = node as ts.TypeReferenceNode;
<span class="missing-if-branch" title="else path not taken" >E</span>if (typeNode.typeArguments) {
typeArgument = typeNode.typeArguments[0]
.getFullText(ctx.sourceFile)
.trim();
}
}
const length = node.getWidth(ctx.sourceFile);
return [
createInvalidNode(
node,
new Lint.Replacement(
node.end - length,
length,
`ReadonlyArray<${typeArgument}>`
)
)
];
}
return [];
}
function checkVariableOrParameterImplicitType(
node: ts.Node,
ctx: Lint.WalkContext<Options>
): ReadonlyArray<InvalidNode> {
if (
node.kind === ts.SyntaxKind.VariableDeclaration ||
node.kind === ts.SyntaxKind.Parameter ||
node.kind === ts.SyntaxKind.PropertyDeclaration
) {
// The initializer is used to set and implicit type
const varOrParamNode = node as
| ts.VariableDeclaration
| ts.ParameterDeclaration;
if (Ignore.shouldIgnorePrefix(node, ctx.options, ctx.sourceFile)) {
return [];
}
if (!varOrParamNode.type) {
if (
varOrParamNode.initializer &&
varOrParamNode.initializer.kind === ts.SyntaxKind.ArrayLiteralExpression
) {
const length = varOrParamNode.name.getWidth(ctx.sourceFile);
const nameText = varOrParamNode.name.getText(ctx.sourceFile);
let typeArgument = "any";
// Not sure it is a good idea to guess what the element types are...
// const arrayLiteralNode = varOrParamNode.initializer as ts.ArrayLiteralExpression;
// if (arrayLiteralNode.elements.length > 0) {
// const element = arrayLiteralNode.elements[0];
// if (element.kind === ts.SyntaxKind.NumericLiteral) {
// typeArgument = "number";
// } else if (element.kind === ts.SyntaxKind.StringLiteral) {
// typeArgument = "string";
// } else if (element.kind === ts.SyntaxKind.TrueKeyword || element.kind === ts.SyntaxKind.FalseKeyword) {
// typeArgument = "boolean";
// }
// }
return [
createInvalidNode(
varOrParamNode.name,
new Lint.Replacement(
varOrParamNode.name.end - length,
length,
`${nameText}: ReadonlyArray<${typeArgument}>`
)
)
];
}
}
}
return [];
}
</pre></td></tr>
</table></pre>
<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage
generated by <a href="https://istanbul.js.org/" target="_blank">istanbul</a> at Tue Jan 16 2018 21:59:42 GMT+0100 (CET)
</div>
</div>
<script src="prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="sorter.js"></script>
</body>
</html>