cognitive-complexity-ts 0.6.4 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/src/cognitive-complexity/Scope.d.ts +4 -0
- package/build/src/cognitive-complexity/Scope.js +4 -0
- package/build/src/cognitive-complexity/cognitive-complexity.js +105 -59
- package/build/src/cognitive-complexity/debug.d.ts +1 -1
- package/build/src/cognitive-complexity/debug.js +2 -2
- package/build/src/cognitive-complexity/depth.d.ts +2 -2
- package/build/src/cognitive-complexity/depth.js +58 -36
- package/build/src/cognitive-complexity/node-inspection.d.ts +27 -2
- package/build/src/cognitive-complexity/node-inspection.js +93 -42
- package/build/src/cognitive-complexity/node-naming.js +22 -13
- package/build/src/cognitive-complexity/output.js +22 -13
- package/build/src/json.js +17 -7
- package/build/src/ui-server/ui-server.d.ts +0 -1
- package/build/src/ui-server/ui-server.js +18 -9
- package/build/src/util/util.d.ts +0 -2
- package/build/src/util/util.js +6 -32
- package/package.json +12 -15
- package/ui/README.md +0 -26
|
@@ -13,6 +13,10 @@ export declare class Scope {
|
|
|
13
13
|
readonly object: ReadonlyArray<string>;
|
|
14
14
|
constructor(local: ReadonlyArray<string>, object: ReadonlyArray<string>);
|
|
15
15
|
includes(name: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* @returns a new scope with the identifier from the node included,
|
|
18
|
+
* or if there is no identifier, it returns the scope not modified nor cloned
|
|
19
|
+
*/
|
|
16
20
|
maybeAdd(node: ts.Node, variableBeingDefined: string | undefined): Scope;
|
|
17
21
|
private scopeToAdd;
|
|
18
22
|
}
|
|
@@ -17,6 +17,10 @@ class Scope {
|
|
|
17
17
|
includes(name) {
|
|
18
18
|
return this.local.includes(name) || this.object.includes(name);
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* @returns a new scope with the identifier from the node included,
|
|
22
|
+
* or if there is no identifier, it returns the scope not modified nor cloned
|
|
23
|
+
*/
|
|
20
24
|
maybeAdd(node, variableBeingDefined) {
|
|
21
25
|
const { local, object } = this.scopeToAdd(node, variableBeingDefined);
|
|
22
26
|
if (local.length !== 0 || object.length !== 0) {
|
|
@@ -15,36 +15,54 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.fileCost =
|
|
36
|
+
exports.fileCost = fileCost;
|
|
27
37
|
const ts = __importStar(require("typescript"));
|
|
28
|
-
const util_1 = require("../util/util");
|
|
29
38
|
const node_naming_1 = require("./node-naming");
|
|
30
39
|
const depth_1 = require("./depth");
|
|
31
40
|
const node_inspection_1 = require("./node-inspection");
|
|
32
41
|
const Scope_1 = require("./Scope");
|
|
33
42
|
function fileCost(file) {
|
|
34
|
-
|
|
43
|
+
const initialContext = {
|
|
44
|
+
depth: 0,
|
|
45
|
+
scope: new Scope_1.Scope([], []),
|
|
46
|
+
topLevel: true,
|
|
47
|
+
variableBeingDefined: undefined,
|
|
48
|
+
};
|
|
49
|
+
const initialMutableContext = {
|
|
50
|
+
precedingOperator: undefined,
|
|
51
|
+
precedingTypeOperator: undefined,
|
|
52
|
+
};
|
|
53
|
+
return nodeCost(file, initialContext, initialMutableContext);
|
|
35
54
|
}
|
|
36
|
-
|
|
37
|
-
function aggregateCostOfChildren(children, childDepth, topLevel, scope, variableBeingDefined) {
|
|
55
|
+
function aggregateCostOfChildren(children, ctx, mutCtx) {
|
|
38
56
|
let score = 0;
|
|
39
57
|
// The inner containers of a node is defined as the concat of:
|
|
40
58
|
// * all child nodes that are functions/namespaces/classes
|
|
41
59
|
// * all containers declared directly under a non-container child node
|
|
42
60
|
const inner = [];
|
|
43
61
|
for (const child of children) {
|
|
44
|
-
const childCost = nodeCost(child,
|
|
62
|
+
const childCost = nodeCost(child, ctx, mutCtx);
|
|
45
63
|
score += childCost.score;
|
|
46
64
|
// a function/class/namespace/type is part of the inner scope we want to output
|
|
47
|
-
const name = (0, node_naming_1.chooseContainerName)(child, variableBeingDefined);
|
|
65
|
+
const name = (0, node_naming_1.chooseContainerName)(child, ctx.variableBeingDefined);
|
|
48
66
|
if (name !== undefined) {
|
|
49
67
|
inner.push({
|
|
50
68
|
...(0, node_inspection_1.getColumnAndLine)(child),
|
|
@@ -57,10 +75,7 @@ function aggregateCostOfChildren(children, childDepth, topLevel, scope, variable
|
|
|
57
75
|
inner.push(...childCost.inner);
|
|
58
76
|
}
|
|
59
77
|
}
|
|
60
|
-
return {
|
|
61
|
-
score,
|
|
62
|
-
inner
|
|
63
|
-
};
|
|
78
|
+
return { score, inner };
|
|
64
79
|
}
|
|
65
80
|
function costOfDepth(node, depth) {
|
|
66
81
|
// increment for nesting level
|
|
@@ -89,9 +104,9 @@ function costOfDepth(node, depth) {
|
|
|
89
104
|
}
|
|
90
105
|
return 0;
|
|
91
106
|
}
|
|
92
|
-
function inherentCost(node, scope) {
|
|
107
|
+
function inherentCost(node, scope, mutCtx) {
|
|
93
108
|
// certain language features carry and inherent cost
|
|
94
|
-
if ((0, node_inspection_1.
|
|
109
|
+
if ((0, node_inspection_1.isNewSequenceOfBinaryOperators)(node, mutCtx.precedingOperator)
|
|
95
110
|
|| ts.isCatchClause(node)
|
|
96
111
|
|| ts.isConditionalExpression(node)
|
|
97
112
|
|| ts.isConditionalTypeNode(node)
|
|
@@ -102,7 +117,8 @@ function inherentCost(node, scope) {
|
|
|
102
117
|
|| ts.isMappedTypeNode(node)
|
|
103
118
|
|| ts.isSwitchStatement(node)
|
|
104
119
|
|| ts.isWhileStatement(node)
|
|
105
|
-
|| (0, node_inspection_1.isBreakOrContinueToLabel)(node)
|
|
120
|
+
|| (0, node_inspection_1.isBreakOrContinueToLabel)(node)
|
|
121
|
+
|| (0, node_inspection_1.isNewSequenceOfBinaryTypeOperators)(node, mutCtx.precedingTypeOperator)) {
|
|
106
122
|
return 1;
|
|
107
123
|
}
|
|
108
124
|
const calledName = (0, node_naming_1.getNameIfCalledNode)(node);
|
|
@@ -126,61 +142,91 @@ function inherentCost(node, scope) {
|
|
|
126
142
|
}
|
|
127
143
|
return score;
|
|
128
144
|
}
|
|
129
|
-
if ((0, node_inspection_1.isBinaryTypeOperator)(node)) {
|
|
130
|
-
// This node naturally represents a sequence of binary type operators.
|
|
131
|
-
// (unlike normal binary operators)
|
|
132
|
-
let score = 1;
|
|
133
|
-
// However, this sequence can contain nodes that are a different binary operator.
|
|
134
|
-
// We can assume that children of the internal syntax list that are binary operators
|
|
135
|
-
// are not the same kind as this node.
|
|
136
|
-
// Binary sub-expressions at either end of the syntax list
|
|
137
|
-
// do not break this sequence of operators in the code; they merely bookend it.
|
|
138
|
-
const syntaxList = node.getChildren()[0];
|
|
139
|
-
const numOfSequenceInterrupts = (0, util_1.countNotAtTheEnds)(syntaxList.getChildren(), node_inspection_1.isBinaryTypeOperator);
|
|
140
|
-
score += numOfSequenceInterrupts;
|
|
141
|
-
return score;
|
|
142
|
-
}
|
|
143
145
|
return 0;
|
|
144
146
|
}
|
|
145
147
|
/**
|
|
146
148
|
* @param node The node whose cost we want
|
|
147
|
-
* @param
|
|
148
|
-
* @param
|
|
149
|
-
*
|
|
149
|
+
* @param ctx Information about the context a node is in, which is needed to know the node cost.
|
|
150
|
+
* @param mutCtx Same as above, but this information can be changed while traversing,
|
|
151
|
+
* which will provide information up the call stack (where this function is called and higher).
|
|
150
152
|
*/
|
|
151
|
-
function nodeCost(node,
|
|
152
|
-
|
|
153
|
-
score += costOfDepth(node, depth);
|
|
153
|
+
function nodeCost(node, ctx, mutCtx) {
|
|
154
|
+
const { depth, topLevel, scope, variableBeingDefined } = ctx;
|
|
154
155
|
// get the ancestors container names from the perspective of this node's children
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
const { same, below } = (0, depth_1.whereAreChildren)(node);
|
|
156
|
+
const scopeForChildren = scope.maybeAdd(node, variableBeingDefined);
|
|
157
|
+
const { sameDepth, below } = (0, depth_1.whereAreChildren)(node);
|
|
158
158
|
/**
|
|
159
159
|
* The name being introduced (if there is one)
|
|
160
160
|
* for a variable whose declaration this scope is directly inside of.
|
|
161
161
|
* It is used to give names to anonymous functions and classes.
|
|
162
|
-
* let a = $a$ () => {};
|
|
163
|
-
* let a = ( $a$ () => {} );
|
|
164
|
-
* let a = f( $
|
|
165
|
-
* let a = () => { $undefined$ };
|
|
162
|
+
* let a = $a$ () => { $anonymous$ };
|
|
163
|
+
* let a = ( $a$ () => { $anonymous$ } );
|
|
164
|
+
* let a = f( $anonymous$ () => { $anonymous$ } );
|
|
166
165
|
*/
|
|
167
166
|
let newVariableBeingDefined = (0, node_naming_1.getNameOfAssignment)(node);
|
|
168
167
|
if (newVariableBeingDefined === undefined
|
|
168
|
+
&& variableBeingDefined !== undefined
|
|
169
169
|
&& (0, node_inspection_1.passThroughNameBeingAssigned)(node)) {
|
|
170
170
|
newVariableBeingDefined = variableBeingDefined;
|
|
171
171
|
}
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
const opSequenceInProgress = mutCtx.precedingOperator;
|
|
173
|
+
const typeOpSequenceInProgress = mutCtx.precedingTypeOperator;
|
|
174
|
+
const pauseOpSequence = (0, node_inspection_1.pausesASequenceOfBinaryOperators)(node);
|
|
175
|
+
const pauseTypeOpSequence = (0, node_inspection_1.pausesASequenceOfBinaryTypeOperators)(node);
|
|
176
|
+
// Check if the node ends any ongoing sequence of binary operators
|
|
177
|
+
if ((0, node_inspection_1.breaksASequenceOfBinaryOperators)(node)) {
|
|
178
|
+
mutCtx.precedingTypeOperator = undefined;
|
|
179
|
+
mutCtx.precedingOperator = undefined;
|
|
180
|
+
}
|
|
181
|
+
// Score for the current node
|
|
182
|
+
let score = inherentCost(node, scope, mutCtx);
|
|
183
|
+
score += costOfDepth(node, depth);
|
|
184
|
+
// If this is a binary operator, there won't be any children.
|
|
185
|
+
// Pass along the operator info
|
|
186
|
+
if ((0, node_inspection_1.isChainableBinaryOperator)(node)) {
|
|
187
|
+
mutCtx.precedingOperator = node.kind;
|
|
188
|
+
}
|
|
189
|
+
// If this is a binary type operator, there won't be any children.
|
|
190
|
+
// Pass along the operator info
|
|
191
|
+
else if ((0, node_inspection_1.isChainableBinaryTypeOperator)(node)) {
|
|
192
|
+
mutCtx.precedingTypeOperator = node.kind;
|
|
193
|
+
}
|
|
194
|
+
else if (pauseOpSequence) {
|
|
195
|
+
mutCtx.precedingOperator = undefined;
|
|
196
|
+
}
|
|
197
|
+
else if (pauseTypeOpSequence) {
|
|
198
|
+
mutCtx.precedingTypeOperator = undefined;
|
|
199
|
+
}
|
|
200
|
+
const ctxForChildrenSameDepth = {
|
|
201
|
+
depth,
|
|
202
|
+
topLevel,
|
|
203
|
+
precedingOperator: mutCtx.precedingOperator,
|
|
204
|
+
scope: scopeForChildren,
|
|
205
|
+
variableBeingDefined: newVariableBeingDefined,
|
|
206
|
+
};
|
|
207
|
+
const costOfSameDepthChildren = aggregateCostOfChildren(sameDepth, ctxForChildrenSameDepth, mutCtx);
|
|
208
|
+
// The nodes below this node have an increased depth number,
|
|
209
|
+
// unless this node is top level and it is a container.
|
|
210
|
+
const depthOfBelow = depth + (topLevel && (0, node_inspection_1.isContainer)(node) ? 0 : 1);
|
|
211
|
+
const ctxForChildrenBelow = {
|
|
212
|
+
...ctxForChildrenSameDepth,
|
|
213
|
+
depth: depthOfBelow,
|
|
214
|
+
topLevel: false,
|
|
215
|
+
};
|
|
216
|
+
const costOfBelowChildren = aggregateCostOfChildren(below, ctxForChildrenBelow, mutCtx);
|
|
217
|
+
// continue a paused sequence
|
|
218
|
+
if (pauseOpSequence) {
|
|
219
|
+
mutCtx.precedingOperator = opSequenceInProgress;
|
|
220
|
+
}
|
|
221
|
+
else if (pauseTypeOpSequence) {
|
|
222
|
+
mutCtx.precedingTypeOperator = typeOpSequenceInProgress;
|
|
223
|
+
}
|
|
178
224
|
score += costOfSameDepthChildren.score;
|
|
179
225
|
score += costOfBelowChildren.score;
|
|
180
|
-
const inner = [
|
|
181
|
-
|
|
182
|
-
inner
|
|
183
|
-
|
|
184
|
-
};
|
|
226
|
+
const inner = [
|
|
227
|
+
...costOfSameDepthChildren.inner,
|
|
228
|
+
...costOfBelowChildren.inner
|
|
229
|
+
];
|
|
230
|
+
return { inner, score };
|
|
185
231
|
}
|
|
186
232
|
//# sourceMappingURL=cognitive-complexity.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.testLog = void 0;
|
|
4
|
+
exports.logNode = logNode;
|
|
4
5
|
const util_1 = require("util");
|
|
5
6
|
exports.testLog = (0, util_1.debuglog)("test");
|
|
6
7
|
function logNode(child) {
|
|
7
8
|
(0, exports.testLog)(child.getFullText());
|
|
8
9
|
}
|
|
9
|
-
exports.logNode = logNode;
|
|
10
10
|
//# sourceMappingURL=debug.js.map
|
|
@@ -6,11 +6,11 @@ interface DepthOfChildren {
|
|
|
6
6
|
/**
|
|
7
7
|
* The same level of depth.
|
|
8
8
|
*/
|
|
9
|
-
|
|
9
|
+
sameDepth: readonly ts.Node[];
|
|
10
10
|
/**
|
|
11
11
|
* One level of depth below.
|
|
12
12
|
*/
|
|
13
|
-
below: ts.Node[];
|
|
13
|
+
below: readonly ts.Node[];
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* @param node The node whose children to categorise by depth
|
|
@@ -18,15 +18,25 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
18
18
|
}) : function(o, v) {
|
|
19
19
|
o["default"] = v;
|
|
20
20
|
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || function (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
};
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
28
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.whereAreChildren =
|
|
39
|
+
exports.whereAreChildren = whereAreChildren;
|
|
30
40
|
const ts = __importStar(require("typescript"));
|
|
31
41
|
const node_util_1 = require("../util/node-util");
|
|
32
42
|
const node_inspection_1 = require("./node-inspection");
|
|
@@ -39,6 +49,9 @@ function whereAreChildren(node) {
|
|
|
39
49
|
if (ts.isArrowFunction(node)) {
|
|
40
50
|
return arrowFunction(node);
|
|
41
51
|
}
|
|
52
|
+
else if (ts.isBinaryExpression(node)) {
|
|
53
|
+
return binaryExpression(node);
|
|
54
|
+
}
|
|
42
55
|
else if (ts.isCatchClause(node)) {
|
|
43
56
|
return catchClause(node);
|
|
44
57
|
}
|
|
@@ -74,20 +87,32 @@ function whereAreChildren(node) {
|
|
|
74
87
|
}
|
|
75
88
|
else {
|
|
76
89
|
return {
|
|
77
|
-
|
|
78
|
-
below: []
|
|
90
|
+
sameDepth: node.getChildren(),
|
|
91
|
+
below: [],
|
|
79
92
|
};
|
|
80
93
|
}
|
|
81
94
|
}
|
|
82
|
-
exports.whereAreChildren = whereAreChildren;
|
|
83
95
|
function arrowFunction(node) {
|
|
84
96
|
const children = node.getChildren();
|
|
85
97
|
// aggregate code inside SyntaxList
|
|
86
|
-
const
|
|
98
|
+
const sameDepth = children.slice(1, -1);
|
|
87
99
|
// aggregate code inside arrow function
|
|
88
100
|
const below = [children[children.length - 1]];
|
|
89
|
-
return {
|
|
101
|
+
return { sameDepth, below };
|
|
90
102
|
}
|
|
103
|
+
function binaryExpression(node) {
|
|
104
|
+
return {
|
|
105
|
+
sameDepth: node.getChildren(),
|
|
106
|
+
below: [],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// function binaryTypeExpression(node: ts.UnionTypeNode | ts.IntersectionTypeNode): DepthOfChildren {
|
|
110
|
+
// return {
|
|
111
|
+
// sameDepth: [node.types[0]],
|
|
112
|
+
// right: node.types.slice(1),
|
|
113
|
+
// below: [],
|
|
114
|
+
// }
|
|
115
|
+
// }
|
|
91
116
|
function catchClause(node) {
|
|
92
117
|
const children = node.getChildren();
|
|
93
118
|
const variableDeclaration = children.find(child => ts.isVariableDeclaration(child));
|
|
@@ -95,7 +120,7 @@ function catchClause(node) {
|
|
|
95
120
|
if (block === undefined)
|
|
96
121
|
throw new node_util_1.UnreachableNodeState(node, "catch clause has no block");
|
|
97
122
|
return {
|
|
98
|
-
|
|
123
|
+
sameDepth: variableDeclaration ? [variableDeclaration] : [],
|
|
99
124
|
below: [block],
|
|
100
125
|
};
|
|
101
126
|
}
|
|
@@ -105,7 +130,7 @@ function conditionalExpression(node) {
|
|
|
105
130
|
const thenCode = children[2];
|
|
106
131
|
const elseCode = children[4];
|
|
107
132
|
return {
|
|
108
|
-
|
|
133
|
+
sameDepth: [condition],
|
|
109
134
|
below: [thenCode, elseCode]
|
|
110
135
|
};
|
|
111
136
|
}
|
|
@@ -121,22 +146,22 @@ function conditionalType(node) {
|
|
|
121
146
|
// else code
|
|
122
147
|
below.push(...children.slice(endOfThen + 1));
|
|
123
148
|
return {
|
|
124
|
-
|
|
149
|
+
sameDepth: condition,
|
|
125
150
|
below,
|
|
126
151
|
};
|
|
127
152
|
}
|
|
128
153
|
function doStatement(node) {
|
|
129
|
-
const
|
|
154
|
+
const sameDepth = [];
|
|
130
155
|
const below = [];
|
|
131
156
|
const children = node.getChildren();
|
|
132
157
|
// aggregate block
|
|
133
158
|
below.push(children[1]);
|
|
134
159
|
// aggregate condition
|
|
135
|
-
|
|
136
|
-
return {
|
|
160
|
+
sameDepth.push(children[4]);
|
|
161
|
+
return { sameDepth, below };
|
|
137
162
|
}
|
|
138
163
|
function forLikeStatement(node) {
|
|
139
|
-
const
|
|
164
|
+
const sameDepth = [];
|
|
140
165
|
const below = [];
|
|
141
166
|
const children = node.getChildren();
|
|
142
167
|
// consume everything form the open parenthesis to the close parenthesis
|
|
@@ -146,27 +171,24 @@ function forLikeStatement(node) {
|
|
|
146
171
|
if (ts.isToken(child) && child.kind === ts.SyntaxKind.CloseParenToken) {
|
|
147
172
|
break;
|
|
148
173
|
}
|
|
149
|
-
|
|
174
|
+
sameDepth.push(child);
|
|
150
175
|
}
|
|
151
176
|
// consume looped code
|
|
152
177
|
below.push(children[i]);
|
|
153
|
-
return {
|
|
178
|
+
return { sameDepth, below };
|
|
154
179
|
}
|
|
155
180
|
function functionDeclaration(node) {
|
|
156
181
|
const children = node.getChildren();
|
|
157
|
-
const
|
|
182
|
+
const sameDepth = children.slice(1, -1);
|
|
158
183
|
const below = [children[children.length - 1]];
|
|
159
|
-
return {
|
|
160
|
-
below,
|
|
161
|
-
same,
|
|
162
|
-
};
|
|
184
|
+
return { sameDepth, below };
|
|
163
185
|
}
|
|
164
186
|
function functionExpression(node) {
|
|
165
187
|
const children = node.getChildren();
|
|
166
188
|
const functionBody = children.slice(-1);
|
|
167
189
|
const functionDecl = children.slice(0, -1);
|
|
168
190
|
return {
|
|
169
|
-
|
|
191
|
+
sameDepth: functionBody,
|
|
170
192
|
below: functionDecl
|
|
171
193
|
};
|
|
172
194
|
}
|
|
@@ -179,34 +201,34 @@ function ifStatement(node) {
|
|
|
179
201
|
if (ts.isIfStatement(elseCode)) {
|
|
180
202
|
// an else if structure is on the same depth
|
|
181
203
|
return {
|
|
182
|
-
|
|
204
|
+
sameDepth: [condition, elseCode],
|
|
183
205
|
below: [thenCode]
|
|
184
206
|
};
|
|
185
207
|
}
|
|
186
208
|
else {
|
|
187
209
|
// the contents of a solo else are at one depth below
|
|
188
210
|
return {
|
|
189
|
-
|
|
211
|
+
sameDepth: [condition],
|
|
190
212
|
below: [thenCode, elseCode]
|
|
191
213
|
};
|
|
192
214
|
}
|
|
193
215
|
}
|
|
194
216
|
return {
|
|
195
|
-
|
|
217
|
+
sameDepth: [condition],
|
|
196
218
|
below: [thenCode]
|
|
197
219
|
};
|
|
198
220
|
}
|
|
199
221
|
function methodDeclaration(node) {
|
|
200
|
-
const
|
|
222
|
+
const sameDepth = [];
|
|
201
223
|
const below = [];
|
|
202
224
|
for (const child of node.getChildren()) {
|
|
203
225
|
if (ts.isBlock(child)) {
|
|
204
226
|
below.push(child);
|
|
205
227
|
break;
|
|
206
228
|
}
|
|
207
|
-
|
|
229
|
+
sameDepth.push(child);
|
|
208
230
|
}
|
|
209
|
-
return {
|
|
231
|
+
return { sameDepth, below };
|
|
210
232
|
}
|
|
211
233
|
function switchStatement(node) {
|
|
212
234
|
const children = node.getChildren();
|
|
@@ -215,7 +237,7 @@ function switchStatement(node) {
|
|
|
215
237
|
// consume cases
|
|
216
238
|
const cases = [children[4]];
|
|
217
239
|
return {
|
|
218
|
-
|
|
240
|
+
sameDepth: condition,
|
|
219
241
|
below: cases
|
|
220
242
|
};
|
|
221
243
|
}
|
|
@@ -224,7 +246,7 @@ function whileStatement(node) {
|
|
|
224
246
|
const condition = children[2];
|
|
225
247
|
const loopCode = children[4];
|
|
226
248
|
return {
|
|
227
|
-
|
|
249
|
+
sameDepth: [condition],
|
|
228
250
|
below: [loopCode]
|
|
229
251
|
};
|
|
230
252
|
}
|
|
@@ -6,12 +6,37 @@ export declare function getColumnAndLine(node: ts.Node): ColumnAndLine;
|
|
|
6
6
|
export declare function getIdentifier(node: ts.Node): string | undefined;
|
|
7
7
|
export declare function getFirstNonParenthesizedAncestor(node: ts.Node): ts.Node;
|
|
8
8
|
export declare function getTextWithoutBrackets(node: ts.Node): string;
|
|
9
|
-
export declare function isBinaryTypeOperator(node: ts.Node): node is ts.UnionOrIntersectionTypeNode;
|
|
10
9
|
export declare function isBreakOrContinueToLabel(node: ts.Node): boolean;
|
|
11
10
|
export declare function isContainer(node: ts.Node): boolean;
|
|
12
11
|
export declare function isForLikeStatement(node: ts.Node): node is ForLikeStatement;
|
|
13
12
|
export declare function isFunctionNode(node: ts.Node): node is FunctionNode;
|
|
14
|
-
export declare function isSequenceOfDifferentBooleanOperations(node: ts.Node): boolean;
|
|
15
13
|
export declare function isSyntaxList(node: ts.Node): node is ts.SyntaxList;
|
|
14
|
+
export declare function isNewSequenceOfBinaryOperators(node: ts.Node, precedingOperator: ChainableBinaryOperator["kind"] | undefined): boolean;
|
|
15
|
+
export declare function isNewSequenceOfBinaryTypeOperators(node: ts.Node, precedingTypeOperator: ChainableBinaryTypeOperator["kind"] | undefined): boolean;
|
|
16
|
+
export type ChainableBinaryOperator = ts.Node & {
|
|
17
|
+
kind: ts.SyntaxKind.AmpersandAmpersandToken | ts.SyntaxKind.BarBarToken | ts.SyntaxKind.QuestionQuestionToken;
|
|
18
|
+
};
|
|
19
|
+
export declare function isChainableBinaryOperator(node: ts.Node): node is ChainableBinaryOperator;
|
|
20
|
+
export type ChainableBinaryTypeOperator = ts.Node & {
|
|
21
|
+
kind: ts.SyntaxKind.AmpersandToken | ts.SyntaxKind.BarToken;
|
|
22
|
+
};
|
|
23
|
+
export declare function isChainableBinaryTypeOperator(node: ts.Node): node is ChainableBinaryTypeOperator;
|
|
24
|
+
/**
|
|
25
|
+
* A node that causes an end to a sequence of binary operators
|
|
26
|
+
* (i.e. A && B { C && D }, the curly braces end the prior sequence;
|
|
27
|
+
* C will not be interpreted as part of the last sequence.
|
|
28
|
+
*/
|
|
29
|
+
export declare function breaksASequenceOfBinaryOperators(node: ts.Node): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* A node that doesn't cause an end to a sequence of binary operators
|
|
32
|
+
* (i.e. A && Node && B, the 2 && are in the same sequence)
|
|
33
|
+
* but the node's children don't form part of that sequence
|
|
34
|
+
* (i.e. A && Node(B && C) && D, this is two sequences, one inside Node(), the other outside)
|
|
35
|
+
*/
|
|
36
|
+
export declare function pausesASequenceOfBinaryOperators(node: ts.Node): node is ts.ElementAccessExpression | ts.CallLikeExpression | ts.PrefixUnaryExpression;
|
|
37
|
+
/**
|
|
38
|
+
* @see {pausesASequenceOfBinaryOperators} but for type operators
|
|
39
|
+
*/
|
|
40
|
+
export declare function pausesASequenceOfBinaryTypeOperators(node: ts.Node): node is ts.ParenthesizedExpression | ts.TypeReferenceNode | ts.AsExpression;
|
|
16
41
|
export declare function passThroughNameBeingAssigned(node: ts.Node): boolean;
|
|
17
42
|
export declare function report(node: ts.Node, depth?: number): void;
|
|
@@ -15,15 +15,42 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.
|
|
36
|
+
exports.getColumnAndLine = getColumnAndLine;
|
|
37
|
+
exports.getIdentifier = getIdentifier;
|
|
38
|
+
exports.getFirstNonParenthesizedAncestor = getFirstNonParenthesizedAncestor;
|
|
39
|
+
exports.getTextWithoutBrackets = getTextWithoutBrackets;
|
|
40
|
+
exports.isBreakOrContinueToLabel = isBreakOrContinueToLabel;
|
|
41
|
+
exports.isContainer = isContainer;
|
|
42
|
+
exports.isForLikeStatement = isForLikeStatement;
|
|
43
|
+
exports.isFunctionNode = isFunctionNode;
|
|
44
|
+
exports.isSyntaxList = isSyntaxList;
|
|
45
|
+
exports.isNewSequenceOfBinaryOperators = isNewSequenceOfBinaryOperators;
|
|
46
|
+
exports.isNewSequenceOfBinaryTypeOperators = isNewSequenceOfBinaryTypeOperators;
|
|
47
|
+
exports.isChainableBinaryOperator = isChainableBinaryOperator;
|
|
48
|
+
exports.isChainableBinaryTypeOperator = isChainableBinaryTypeOperator;
|
|
49
|
+
exports.breaksASequenceOfBinaryOperators = breaksASequenceOfBinaryOperators;
|
|
50
|
+
exports.pausesASequenceOfBinaryOperators = pausesASequenceOfBinaryOperators;
|
|
51
|
+
exports.pausesASequenceOfBinaryTypeOperators = pausesASequenceOfBinaryTypeOperators;
|
|
52
|
+
exports.passThroughNameBeingAssigned = passThroughNameBeingAssigned;
|
|
53
|
+
exports.report = report;
|
|
27
54
|
const ts = __importStar(require("typescript"));
|
|
28
55
|
const util_1 = require("../util/util");
|
|
29
56
|
function getColumnAndLine(node) {
|
|
@@ -34,7 +61,6 @@ function getColumnAndLine(node) {
|
|
|
34
61
|
line: lineAndCol.line + 1,
|
|
35
62
|
};
|
|
36
63
|
}
|
|
37
|
-
exports.getColumnAndLine = getColumnAndLine;
|
|
38
64
|
function getIdentifier(node) {
|
|
39
65
|
for (const child of node.getChildren()) {
|
|
40
66
|
if (ts.isMemberName(child) || ts.isComputedPropertyName(child)) {
|
|
@@ -43,7 +69,6 @@ function getIdentifier(node) {
|
|
|
43
69
|
}
|
|
44
70
|
return undefined;
|
|
45
71
|
}
|
|
46
|
-
exports.getIdentifier = getIdentifier;
|
|
47
72
|
function getFirstNonParenthesizedAncestor(node) {
|
|
48
73
|
let firstNonParenthesisAncestor = node.parent;
|
|
49
74
|
while (ts.isParenthesizedExpression(firstNonParenthesisAncestor)) {
|
|
@@ -51,7 +76,6 @@ function getFirstNonParenthesizedAncestor(node) {
|
|
|
51
76
|
}
|
|
52
77
|
return firstNonParenthesisAncestor;
|
|
53
78
|
}
|
|
54
|
-
exports.getFirstNonParenthesizedAncestor = getFirstNonParenthesizedAncestor;
|
|
55
79
|
function getTextWithoutBrackets(node) {
|
|
56
80
|
if (ts.isParenthesizedExpression(node)) {
|
|
57
81
|
return node.getChildren()
|
|
@@ -61,11 +85,6 @@ function getTextWithoutBrackets(node) {
|
|
|
61
85
|
}
|
|
62
86
|
return node.getText();
|
|
63
87
|
}
|
|
64
|
-
exports.getTextWithoutBrackets = getTextWithoutBrackets;
|
|
65
|
-
function isBinaryTypeOperator(node) {
|
|
66
|
-
return ts.isUnionTypeNode(node) || ts.isIntersectionTypeNode(node);
|
|
67
|
-
}
|
|
68
|
-
exports.isBinaryTypeOperator = isBinaryTypeOperator;
|
|
69
88
|
function isBreakOrContinueToLabel(node) {
|
|
70
89
|
if (ts.isBreakOrContinueStatement(node)) {
|
|
71
90
|
for (const child of node.getChildren()) {
|
|
@@ -76,7 +95,6 @@ function isBreakOrContinueToLabel(node) {
|
|
|
76
95
|
}
|
|
77
96
|
return false;
|
|
78
97
|
}
|
|
79
|
-
exports.isBreakOrContinueToLabel = isBreakOrContinueToLabel;
|
|
80
98
|
function isContainer(node) {
|
|
81
99
|
return isFunctionNode(node)
|
|
82
100
|
|| ts.isClassDeclaration(node)
|
|
@@ -87,13 +105,11 @@ function isContainer(node) {
|
|
|
87
105
|
|| ts.isSourceFile(node)
|
|
88
106
|
|| ts.isSourceFile(node.parent);
|
|
89
107
|
}
|
|
90
|
-
exports.isContainer = isContainer;
|
|
91
108
|
function isForLikeStatement(node) {
|
|
92
109
|
return ts.isForInStatement(node)
|
|
93
110
|
|| ts.isForOfStatement(node)
|
|
94
111
|
|| ts.isForStatement(node);
|
|
95
112
|
}
|
|
96
|
-
exports.isForLikeStatement = isForLikeStatement;
|
|
97
113
|
function isFunctionNode(node) {
|
|
98
114
|
return ts.isArrowFunction(node)
|
|
99
115
|
|| ts.isFunctionDeclaration(node)
|
|
@@ -101,39 +117,75 @@ function isFunctionNode(node) {
|
|
|
101
117
|
|| ts.isMethodDeclaration(node)
|
|
102
118
|
|| ts.isAccessor(node);
|
|
103
119
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
120
|
+
function isSyntaxList(node) {
|
|
121
|
+
return node.kind === ts.SyntaxKind.SyntaxList;
|
|
122
|
+
}
|
|
123
|
+
function isNewSequenceOfBinaryOperators(node, precedingOperator) {
|
|
124
|
+
if (!isChainableBinaryOperator(node)
|
|
125
|
+
&& node.kind !== ts.SyntaxKind.AmpersandAmpersandEqualsToken
|
|
126
|
+
&& node.kind !== ts.SyntaxKind.BarBarEqualsToken
|
|
127
|
+
&& node.kind !== ts.SyntaxKind.QuestionQuestionEqualsToken) {
|
|
108
128
|
return false;
|
|
109
129
|
}
|
|
110
|
-
|
|
111
|
-
|
|
130
|
+
// is now an operator, or is different to previous operator
|
|
131
|
+
return precedingOperator === undefined || node.kind !== precedingOperator;
|
|
132
|
+
}
|
|
133
|
+
function isNewSequenceOfBinaryTypeOperators(node, precedingTypeOperator) {
|
|
134
|
+
if (!isChainableBinaryTypeOperator(node)) {
|
|
112
135
|
return false;
|
|
113
136
|
}
|
|
114
|
-
|
|
115
|
-
|| operatorToken.kind === ts.SyntaxKind.BarBarToken
|
|
116
|
-
|| operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken;
|
|
117
|
-
const firstNonParenthesisAncestor = getFirstNonParenthesizedAncestor(node);
|
|
118
|
-
if (operatorIsBoolean) {
|
|
119
|
-
// True if the parent does not use the same operator as this node.
|
|
120
|
-
// Presumably true if the parent is not a binary expression.
|
|
121
|
-
// Child number 1 is the operator token.
|
|
122
|
-
return ((_a = firstNonParenthesisAncestor.getChildAt(1)) === null || _a === void 0 ? void 0 : _a.kind) != operatorToken.kind;
|
|
123
|
-
}
|
|
124
|
-
return false;
|
|
137
|
+
return precedingTypeOperator !== node.kind;
|
|
125
138
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
139
|
+
function isChainableBinaryOperator(node) {
|
|
140
|
+
return node.kind === ts.SyntaxKind.AmpersandAmpersandToken
|
|
141
|
+
|| node.kind === ts.SyntaxKind.BarBarToken
|
|
142
|
+
|| node.kind === ts.SyntaxKind.QuestionQuestionToken;
|
|
143
|
+
}
|
|
144
|
+
function isChainableBinaryTypeOperator(node) {
|
|
145
|
+
const isPartOfTypeExpression = (node === null || node === void 0 ? void 0 : node.parent) !== undefined // this is actually undefined-able
|
|
146
|
+
&& (ts.isUnionTypeNode(node.parent) || ts.isIntersectionTypeNode(node.parent)); // doing .parent skips the syntax list for some reason
|
|
147
|
+
return isPartOfTypeExpression
|
|
148
|
+
&& (node.kind === ts.SyntaxKind.AmpersandToken || node.kind === ts.SyntaxKind.BarToken);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* A node that causes an end to a sequence of binary operators
|
|
152
|
+
* (i.e. A && B { C && D }, the curly braces end the prior sequence;
|
|
153
|
+
* C will not be interpreted as part of the last sequence.
|
|
154
|
+
*/
|
|
155
|
+
function breaksASequenceOfBinaryOperators(node) {
|
|
156
|
+
return ts.isStatement(node)
|
|
157
|
+
|| ts.isBlock(node)
|
|
158
|
+
|| isFunctionNode(node)
|
|
159
|
+
|| ts.isParameter(node)
|
|
160
|
+
|| ts.isTypeParameterDeclaration(node)
|
|
161
|
+
|| ts.isPropertyDeclaration(node)
|
|
162
|
+
|| (node.kind === ts.SyntaxKind.ColonToken && isFunctionNode(node.parent))
|
|
163
|
+
|| node.kind === ts.SyntaxKind.FirstAssignment; // separates extends expression from parameter default
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* A node that doesn't cause an end to a sequence of binary operators
|
|
167
|
+
* (i.e. A && Node && B, the 2 && are in the same sequence)
|
|
168
|
+
* but the node's children don't form part of that sequence
|
|
169
|
+
* (i.e. A && Node(B && C) && D, this is two sequences, one inside Node(), the other outside)
|
|
170
|
+
*/
|
|
171
|
+
function pausesASequenceOfBinaryOperators(node) {
|
|
172
|
+
return ts.isCallLikeExpression(node)
|
|
173
|
+
|| ts.isPrefixUnaryExpression(node)
|
|
174
|
+
|| ts.isElementAccessExpression(node);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* @see {pausesASequenceOfBinaryOperators} but for type operators
|
|
178
|
+
*/
|
|
179
|
+
function pausesASequenceOfBinaryTypeOperators(node) {
|
|
180
|
+
return ts.isParenthesizedExpression(node)
|
|
181
|
+
|| ts.isTypeReferenceNode(node)
|
|
182
|
+
|| ts.isAsExpression(node);
|
|
129
183
|
}
|
|
130
|
-
exports.isSyntaxList = isSyntaxList;
|
|
131
184
|
function passThroughNameBeingAssigned(node) {
|
|
132
185
|
return isSyntaxList(node)
|
|
133
186
|
|| ts.isObjectLiteralExpression(node)
|
|
134
187
|
|| ts.isParenthesizedExpression(node);
|
|
135
188
|
}
|
|
136
|
-
exports.passThroughNameBeingAssigned = passThroughNameBeingAssigned;
|
|
137
189
|
function report(node, depth = 0) {
|
|
138
190
|
const toLog = [(0, util_1.repeat)("\t", depth), ts.SyntaxKind[node.kind], node.kind];
|
|
139
191
|
console.error(...toLog);
|
|
@@ -141,5 +193,4 @@ function report(node, depth = 0) {
|
|
|
141
193
|
report(child, depth + 1);
|
|
142
194
|
}
|
|
143
195
|
}
|
|
144
|
-
exports.report = report;
|
|
145
196
|
//# sourceMappingURL=node-inspection.js.map
|
|
@@ -15,15 +15,29 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.
|
|
36
|
+
exports.chooseContainerName = chooseContainerName;
|
|
37
|
+
exports.getIntroducedLocalName = getIntroducedLocalName;
|
|
38
|
+
exports.getNameIfCalledNode = getNameIfCalledNode;
|
|
39
|
+
exports.getNameOfAssignment = getNameOfAssignment;
|
|
40
|
+
exports.getExpressionToAccessObjectMember = getExpressionToAccessObjectMember;
|
|
27
41
|
const ts = __importStar(require("typescript"));
|
|
28
42
|
const node_util_1 = require("../util/node-util");
|
|
29
43
|
const node_inspection_1 = require("./node-inspection");
|
|
@@ -52,7 +66,6 @@ function chooseContainerName(node, variableBeingDefined) {
|
|
|
52
66
|
}
|
|
53
67
|
return undefined;
|
|
54
68
|
}
|
|
55
|
-
exports.chooseContainerName = chooseContainerName;
|
|
56
69
|
function getIntroducedLocalName(node) {
|
|
57
70
|
if (ts.isVariableDeclaration(node)) {
|
|
58
71
|
return (0, node_inspection_1.getIdentifier)(node);
|
|
@@ -77,7 +90,6 @@ function getIntroducedLocalName(node) {
|
|
|
77
90
|
}
|
|
78
91
|
return undefined;
|
|
79
92
|
}
|
|
80
|
-
exports.getIntroducedLocalName = getIntroducedLocalName;
|
|
81
93
|
function getNameIfCalledNode(node) {
|
|
82
94
|
if (ts.isCallExpression(node)) {
|
|
83
95
|
return getCalledFunctionName(node);
|
|
@@ -99,7 +111,6 @@ function getNameIfCalledNode(node) {
|
|
|
99
111
|
}
|
|
100
112
|
return undefined;
|
|
101
113
|
}
|
|
102
|
-
exports.getNameIfCalledNode = getNameIfCalledNode;
|
|
103
114
|
function getNameOfAssignment(node) {
|
|
104
115
|
if (ts.isVariableDeclaration(node)
|
|
105
116
|
|| ts.isPropertyDeclaration(node)
|
|
@@ -116,7 +127,6 @@ function getNameOfAssignment(node) {
|
|
|
116
127
|
}
|
|
117
128
|
return undefined;
|
|
118
129
|
}
|
|
119
|
-
exports.getNameOfAssignment = getNameOfAssignment;
|
|
120
130
|
function getExpressionToAccessObjectMember(node) {
|
|
121
131
|
if (ts.isMethodDeclaration(node)) {
|
|
122
132
|
const [name, requiresDot] = getMethodDeclarationName(node);
|
|
@@ -138,7 +148,6 @@ function getExpressionToAccessObjectMember(node) {
|
|
|
138
148
|
}
|
|
139
149
|
return undefined;
|
|
140
150
|
}
|
|
141
|
-
exports.getExpressionToAccessObjectMember = getExpressionToAccessObjectMember;
|
|
142
151
|
/**
|
|
143
152
|
* @return [name, requires dot syntax]
|
|
144
153
|
*/
|
|
@@ -18,15 +18,29 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
18
18
|
}) : function(o, v) {
|
|
19
19
|
o["default"] = v;
|
|
20
20
|
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || function (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
};
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
28
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.
|
|
39
|
+
exports.getFileOrFolderOutput = getFileOrFolderOutput;
|
|
40
|
+
exports.getFileOutput = getFileOutput;
|
|
41
|
+
exports.getSourceOutput = getSourceOutput;
|
|
42
|
+
exports.getFolderOutput = getFolderOutput;
|
|
43
|
+
exports.programOutput = programOutput;
|
|
30
44
|
const fs_1 = require("fs");
|
|
31
45
|
const path = __importStar(require("path"));
|
|
32
46
|
const ts = __importStar(require("typescript"));
|
|
@@ -45,19 +59,16 @@ async function getFileOrFolderOutput(entryPath) {
|
|
|
45
59
|
return getFileOutput(entryPath);
|
|
46
60
|
}
|
|
47
61
|
}
|
|
48
|
-
exports.getFileOrFolderOutput = getFileOrFolderOutput;
|
|
49
62
|
// API
|
|
50
63
|
async function getFileOutput(filePath) {
|
|
51
64
|
const fileContent = (await fs_1.promises.readFile(filePath)).toString();
|
|
52
65
|
return getSourceOutput(fileContent, path.basename(filePath));
|
|
53
66
|
}
|
|
54
|
-
exports.getFileOutput = getFileOutput;
|
|
55
67
|
// API
|
|
56
68
|
function getSourceOutput(sourceCode, fileName = "") {
|
|
57
69
|
const parsedFile = ts.createSourceFile(fileName, sourceCode, ts.ScriptTarget.Latest, true);
|
|
58
70
|
return (0, cognitive_complexity_1.fileCost)(parsedFile);
|
|
59
71
|
}
|
|
60
|
-
exports.getSourceOutput = getSourceOutput;
|
|
61
72
|
// API
|
|
62
73
|
async function getFolderOutput(folderPath) {
|
|
63
74
|
const folderContents = await fs_1.promises.readdir(folderPath, { withFileTypes: true });
|
|
@@ -72,7 +83,6 @@ async function getFolderOutput(folderPath) {
|
|
|
72
83
|
return undefined;
|
|
73
84
|
});
|
|
74
85
|
}
|
|
75
|
-
exports.getFolderOutput = getFolderOutput;
|
|
76
86
|
// API
|
|
77
87
|
/**
|
|
78
88
|
* @param entryPath Relative to cwd
|
|
@@ -90,5 +100,4 @@ async function programOutput(entryPath) {
|
|
|
90
100
|
return value;
|
|
91
101
|
});
|
|
92
102
|
}
|
|
93
|
-
exports.programOutput = programOutput;
|
|
94
103
|
//# sourceMappingURL=output.js.map
|
package/build/src/json.js
CHANGED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
36
|
const path = __importStar(require("path"));
|
|
27
37
|
const process = __importStar(require("process"));
|
|
@@ -15,15 +15,25 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.createUiServer =
|
|
36
|
+
exports.createUiServer = createUiServer;
|
|
27
37
|
const fs_1 = require("fs");
|
|
28
38
|
const http = __importStar(require("http"));
|
|
29
39
|
const path = __importStar(require("path"));
|
|
@@ -47,7 +57,6 @@ function createUiServer(combinedOutputsJson) {
|
|
|
47
57
|
res.end();
|
|
48
58
|
});
|
|
49
59
|
}
|
|
50
|
-
exports.createUiServer = createUiServer;
|
|
51
60
|
function cached(res) {
|
|
52
61
|
res.setHeader("Cache-Control", "max-age=365000000; immutable");
|
|
53
62
|
}
|
package/build/src/util/util.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export declare function countNotAtTheEnds<T>(arr: T[], count: (elem: T) => boolean): number;
|
|
2
1
|
export declare function doesNotThrow<T>(promise: Promise<T>): Promise<boolean>;
|
|
3
2
|
/**
|
|
4
3
|
* Builds an object from a list of keys whose values are based on the key itself,
|
|
@@ -17,7 +16,6 @@ export declare function keysToAsyncValues<K extends keyof any, V>(keys: K[], toV
|
|
|
17
16
|
export declare function createObjectOfPromisedValues<I, K extends keyof any, V>(inputs: I[], toKey: (input: I) => K, toMaybePromise: (input: I) => Promise<V> | undefined): Promise<Record<K, V>>;
|
|
18
17
|
export declare function nonNaN(num: number, fallback: number): number;
|
|
19
18
|
export declare function repeat(str: string, times: number): string;
|
|
20
|
-
export declare function toPromise<T, E>(action: (callback: (err: E, successData: T) => void) => void, errorTransformer?: (err: E) => Error): Promise<T>;
|
|
21
19
|
export declare class Unreachable extends Error {
|
|
22
20
|
constructor(reason: string);
|
|
23
21
|
}
|
package/build/src/util/util.js
CHANGED
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Unreachable =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
for (let i = 1; i < arr.length - 2; i++) {
|
|
10
|
-
if (count(arr[i])) {
|
|
11
|
-
tot += 1;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
return tot;
|
|
15
|
-
}
|
|
16
|
-
exports.countNotAtTheEnds = countNotAtTheEnds;
|
|
3
|
+
exports.Unreachable = void 0;
|
|
4
|
+
exports.doesNotThrow = doesNotThrow;
|
|
5
|
+
exports.keysToAsyncValues = keysToAsyncValues;
|
|
6
|
+
exports.createObjectOfPromisedValues = createObjectOfPromisedValues;
|
|
7
|
+
exports.nonNaN = nonNaN;
|
|
8
|
+
exports.repeat = repeat;
|
|
17
9
|
async function doesNotThrow(promise) {
|
|
18
10
|
try {
|
|
19
11
|
await promise;
|
|
@@ -23,7 +15,6 @@ async function doesNotThrow(promise) {
|
|
|
23
15
|
return false;
|
|
24
16
|
}
|
|
25
17
|
}
|
|
26
|
-
exports.doesNotThrow = doesNotThrow;
|
|
27
18
|
/**
|
|
28
19
|
* Builds an object from a list of keys whose values are based on the key itself,
|
|
29
20
|
* but where that value is produced asynchronously.
|
|
@@ -43,7 +34,6 @@ async function keysToAsyncValues(keys, toValue) {
|
|
|
43
34
|
await Promise.all(promises);
|
|
44
35
|
return output;
|
|
45
36
|
}
|
|
46
|
-
exports.keysToAsyncValues = keysToAsyncValues;
|
|
47
37
|
/**
|
|
48
38
|
* Builds an object from a list of input items.
|
|
49
39
|
* The keys and values are derived from the input item,
|
|
@@ -70,14 +60,12 @@ async function createObjectOfPromisedValues(inputs, toKey, toMaybePromise) {
|
|
|
70
60
|
await Promise.all(promises);
|
|
71
61
|
return output;
|
|
72
62
|
}
|
|
73
|
-
exports.createObjectOfPromisedValues = createObjectOfPromisedValues;
|
|
74
63
|
function nonNaN(num, fallback) {
|
|
75
64
|
if (Number.isNaN(num)) {
|
|
76
65
|
return fallback;
|
|
77
66
|
}
|
|
78
67
|
return num;
|
|
79
68
|
}
|
|
80
|
-
exports.nonNaN = nonNaN;
|
|
81
69
|
function repeat(str, times) {
|
|
82
70
|
let res = "";
|
|
83
71
|
for (let i = 0; i < times; i++) {
|
|
@@ -85,20 +73,6 @@ function repeat(str, times) {
|
|
|
85
73
|
}
|
|
86
74
|
return res;
|
|
87
75
|
}
|
|
88
|
-
exports.repeat = repeat;
|
|
89
|
-
function toPromise(action, errorTransformer) {
|
|
90
|
-
return new Promise((resolve, reject) => {
|
|
91
|
-
action((err, successData) => {
|
|
92
|
-
if (err) {
|
|
93
|
-
reject(errorTransformer ? errorTransformer(err) : err);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
resolve(successData);
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
exports.toPromise = toPromise;
|
|
102
76
|
class Unreachable extends Error {
|
|
103
77
|
constructor(reason) {
|
|
104
78
|
super("Unreachable branch.\n" + reason);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognitive-complexity-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -45,22 +45,19 @@
|
|
|
45
45
|
"homepage": "https://github.com/Deskbot/Cognitive-Complexity-TS#readme",
|
|
46
46
|
"repository": "https://github.com/Deskbot/Cognitive-Complexity-TS",
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"js-beautify": "^1.
|
|
49
|
-
"minimist": "^1.2.
|
|
50
|
-
"open": "^
|
|
51
|
-
"source-map-support": "^0.5.
|
|
52
|
-
"typescript": "^5.
|
|
48
|
+
"js-beautify": "^1.15.4",
|
|
49
|
+
"minimist": "^1.2.8",
|
|
50
|
+
"open": "^11.0.0",
|
|
51
|
+
"source-map-support": "^0.5.21",
|
|
52
|
+
"typescript": "^5.9.3"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@types/deep-diff": "^1.0.
|
|
56
|
-
"@types/glob": "^
|
|
57
|
-
"@types/js-beautify": "^1.
|
|
58
|
-
"@types/minimist": "^1.2.
|
|
59
|
-
"@types/node": "^
|
|
60
|
-
"@types/tempfile": "^3.0.0",
|
|
55
|
+
"@types/deep-diff": "^1.0.5",
|
|
56
|
+
"@types/glob": "^9.0.0",
|
|
57
|
+
"@types/js-beautify": "^1.14.3",
|
|
58
|
+
"@types/minimist": "^1.2.5",
|
|
59
|
+
"@types/node": "^24.10.4",
|
|
61
60
|
"deep-diff": "^1.0.2",
|
|
62
|
-
"glob": "^
|
|
63
|
-
"json-stream": "^1.0.0",
|
|
64
|
-
"tempfile": "^3.0.0"
|
|
61
|
+
"glob": "^13.0.0"
|
|
65
62
|
}
|
|
66
63
|
}
|
package/ui/README.md
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# UI
|
|
2
|
-
|
|
3
|
-
Why is it written like this?
|
|
4
|
-
|
|
5
|
-
I want the value of componentised web development without a heavy framework. The UI is not so complicated that it requires html to change once written. The style does need to be slightly dynamic, which can be accomplished through the simple traditional DOM API.
|
|
6
|
-
|
|
7
|
-
Although frameworks allow for declarative code that is very short and readable, without transpilation it is inherently inefficient and would require the use of libraries with large memory footprints and speed-limiting virtual-DOM.
|
|
8
|
-
|
|
9
|
-
* Responsiveness of user-interfaces matters to users.
|
|
10
|
-
* RAM is valuable and programmers use a lot of it. A tool to help developers shouldn't take too much of it.
|
|
11
|
-
|
|
12
|
-
I am experimenting with ways of writing simple, well-organised, performant web UI code. I think it is important for this project because people may wish to look at an entire project at once.
|
|
13
|
-
|
|
14
|
-
I'm not entirely happy with certain aspects of this code, but it has been a learning experience. A lot of this turned out rather ad-hoc instead of like a framework, but I know how I would like things to look; the time that would be required to get to that point isn't worth it.
|
|
15
|
-
|
|
16
|
-
## Guiding Principles
|
|
17
|
-
|
|
18
|
-
* In reality UI is mutable and simple changes are simple to do in modern JavaScript.
|
|
19
|
-
* Components can be functional or stateful. Following the well-established principles of keeping components small and simple, means stateful components should not be too difficult to manage.
|
|
20
|
-
* Each stateful component should expose a single DOM element that has any number of children. Components can not change the DOM of another component, except by parenting their exposed DOM, or by adding a class to the exposed DOM that only affects its positioning (e.g. flex attributes). This allows the DOM of a component to be slotted in and out of the page, while not interfering with its internal behaviour and state.
|
|
21
|
-
* Note that document fragments can not be exposed by components because attaching the fragment to the dom re-parents the fragment's children.
|
|
22
|
-
* Functional components can return arrays of components or DOM.
|
|
23
|
-
* Components should be agnostic about their positioning. A component's creator should choose its position in the page if any.
|
|
24
|
-
* Flex CSS properties rely on groups of elements having properties that work together in specific ways. It makes much more sense for an element that has a `display` of `flex` or `inline-flex` to enforce the flex properties of its children than to give components general rules about how they should be sized if they happen to be put in a flex container.
|
|
25
|
-
* Other CSS for a component should be discoverable from the component code. This is achieved with lazy CSS imports being added when a component module is loaded.
|
|
26
|
-
* Stateful components should be rendered on construction to ensure that they are rendered correctly with all usages. Each method that alters the state of a component should also trigger a re-render. Although it should be avoided, it is ok for multiple re-renders to take place where a single one could be achieved and would be more efficient, if the code is still performant.
|