cognitive-complexity-ts
Version:
This program analyses TypeScript and JavaScript code according to the [Cognitive Complexity metric](https://www.sonarsource.com/docs/CognitiveComplexity.pdf). It produces a JSON summary and a GUI for exploring the complexity of your codebase.
231 lines • 7.01 kB
JavaScript
;
/**
* Purpose: get children of a node organised by their depth.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.whereAreChildren = void 0;
const ts = __importStar(require("typescript"));
const node_util_1 = require("../util/node-util");
const node_inspection_1 = require("./node-inspection");
;
/**
* @param node The node whose children to categorise by depth
* @returns a tuple of [children and the same depth, children at one level below]
*/
function whereAreChildren(node) {
if (ts.isArrowFunction(node)) {
return arrowFunction(node);
}
else if (ts.isCatchClause(node)) {
return catchClause(node);
}
else if (ts.isConditionalExpression(node)) {
return conditionalExpression(node);
}
else if (ts.isConditionalTypeNode(node)) {
return conditionalType(node);
}
else if (ts.isDoStatement(node)) {
return doStatement(node);
}
else if ((0, node_inspection_1.isForLikeStatement)(node)) {
return forLikeStatement(node);
}
else if (ts.isFunctionDeclaration(node)) {
return functionDeclaration(node);
}
else if (ts.isFunctionExpression(node)) {
return functionExpression(node);
}
else if (ts.isIfStatement(node)) {
return ifStatement(node);
}
else if (ts.isMethodDeclaration(node)) {
return methodDeclaration(node);
}
else if (ts.isSwitchStatement(node)) {
return switchStatement(node);
}
else if (ts.isWhileStatement(node)) {
return whileStatement(node);
}
else {
return {
same: node.getChildren(),
below: []
};
}
}
exports.whereAreChildren = whereAreChildren;
function arrowFunction(node) {
const children = node.getChildren();
// aggregate code inside SyntaxList
const same = children.slice(1, -1);
// aggregate code inside arrow function
const below = [children[children.length - 1]];
return { same, below };
}
function catchClause(node) {
const children = node.getChildren();
const variableDeclaration = children.find(child => ts.isVariableDeclaration(child));
const block = children.find(child => ts.isBlock(child));
if (block === undefined)
throw new node_util_1.UnreachableNodeState(node, "catch clause has no block");
return {
same: variableDeclaration ? [variableDeclaration] : [],
below: [block],
};
}
function conditionalExpression(node) {
const children = node.getChildren();
const condition = children[0];
const thenCode = children[2];
const elseCode = children[4];
return {
same: [condition],
below: [thenCode, elseCode]
};
}
function conditionalType(node) {
const children = node.getChildren();
const endOfCondition = children
.findIndex(child => child.kind === ts.SyntaxKind.QuestionToken);
const endOfThen = children
.findIndex(child => child.kind === ts.SyntaxKind.ColonToken);
const condition = children.slice(0, endOfCondition);
// then code
const below = children.slice(endOfCondition + 1, endOfThen);
// else code
below.push(...children.slice(endOfThen + 1));
return {
same: condition,
below,
};
}
function doStatement(node) {
const same = [];
const below = [];
const children = node.getChildren();
// aggregate block
below.push(children[1]);
// aggregate condition
same.push(children[4]);
return { same, below };
}
function forLikeStatement(node) {
const same = [];
const below = [];
const children = node.getChildren();
// consume everything form the open parenthesis to the close parenthesis
let i = 2;
while (true) {
const child = children[i++];
if (ts.isToken(child) && child.kind === ts.SyntaxKind.CloseParenToken) {
break;
}
same.push(child);
}
// consume looped code
below.push(children[i]);
return { same, below };
}
function functionDeclaration(node) {
const children = node.getChildren();
const same = children.slice(1, -1);
const below = [children[children.length - 1]];
return {
below,
same,
};
}
function functionExpression(node) {
const children = node.getChildren();
const functionBody = children.slice(-1);
const functionDecl = children.slice(0, -1);
return {
same: functionBody,
below: functionDecl
};
}
function ifStatement(node) {
const children = node.getChildren();
const condition = children[2];
const thenCode = children[4];
const elseCode = children[6];
if (elseCode) {
if (ts.isIfStatement(elseCode)) {
// an else if structure is on the same depth
return {
same: [condition, elseCode],
below: [thenCode]
};
}
else {
// the contents of a solo else are at one depth below
return {
same: [condition],
below: [thenCode, elseCode]
};
}
}
return {
same: [condition],
below: [thenCode]
};
}
function methodDeclaration(node) {
const same = [];
const below = [];
for (const child of node.getChildren()) {
if (ts.isBlock(child)) {
below.push(child);
break;
}
same.push(child);
}
return { same, below };
}
function switchStatement(node) {
const children = node.getChildren();
// aggregate condition
const condition = [children[2]];
// consume cases
const cases = [children[4]];
return {
same: condition,
below: cases
};
}
function whileStatement(node) {
const children = node.getChildren();
const condition = children[2];
const loopCode = children[4];
return {
same: [condition],
below: [loopCode]
};
}
//# sourceMappingURL=depth.js.map