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.
246 lines • 8.84 kB
JavaScript
"use strict";
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.getExpressionToAccessObjectMember = exports.getNameOfAssignment = exports.getNameIfCalledNode = exports.getIntroducedLocalName = exports.chooseContainerName = void 0;
const ts = __importStar(require("typescript"));
const node_util_1 = require("../util/node-util");
const node_inspection_1 = require("./node-inspection");
function chooseContainerName(node, variableBeingDefined) {
var _a, _b;
if ((0, node_inspection_1.isFunctionNode)(node)) {
return (_b = (_a = getFunctionNodeName(node)) !== null && _a !== void 0 ? _a : variableBeingDefined) !== null && _b !== void 0 ? _b : "";
}
if (ts.isClassDeclaration(node)) {
return getClassDeclarationName(node);
}
if (ts.isClassExpression(node)) {
return getClassExpressionName(node, variableBeingDefined);
}
if (ts.isConstructorDeclaration(node)) {
return "constructor";
}
if (ts.isInterfaceDeclaration(node)) {
return getInterfaceDeclarationName(node);
}
if (ts.isModuleDeclaration(node)) {
return getModuleDeclarationName(node);
}
if (ts.isTypeAliasDeclaration(node)) {
return getTypeAliasName(node);
}
return undefined;
}
exports.chooseContainerName = chooseContainerName;
function getIntroducedLocalName(node) {
if (ts.isVariableDeclaration(node)) {
return (0, node_inspection_1.getIdentifier)(node);
}
if (ts.isClassDeclaration(node)) {
return getClassDeclarationName(node);
}
if (ts.isClassExpression(node)) {
return getClassExpressionName(node);
}
if (ts.isInterfaceDeclaration(node)) {
return getInterfaceDeclarationName(node);
}
// functions not always defined in object scope
if (ts.isArrowFunction(node)
|| ts.isFunctionDeclaration(node)
|| ts.isFunctionExpression(node)) {
return getFunctionNodeName(node);
}
if (ts.isTypeAliasDeclaration(node)) {
return getTypeAliasName(node);
}
return undefined;
}
exports.getIntroducedLocalName = getIntroducedLocalName;
function getNameIfCalledNode(node) {
if (ts.isCallExpression(node)) {
return getCalledFunctionName(node);
}
if (ts.isNewExpression(node)) {
return getNewedConstructorName(node);
}
if (ts.isPropertyAccessExpression(node)) {
return node.getText();
}
if (ts.isJsxOpeningLikeElement(node)) {
return node.getChildAt(1).getText();
}
if (ts.isTypeReferenceNode(node)) {
return node.getChildAt(0).getText();
}
if (ts.isTaggedTemplateExpression(node)) {
return node.getChildAt(0).getText();
}
return undefined;
}
exports.getNameIfCalledNode = getNameIfCalledNode;
function getNameOfAssignment(node) {
if (ts.isVariableDeclaration(node)
|| ts.isPropertyDeclaration(node)
|| ts.isPropertyAssignment(node)
|| ts.isBindingElement(node)
|| ts.isTypeElement(node)
|| ts.isEnumDeclaration(node)
|| ts.isEnumMember(node)
|| ts.isCallSignatureDeclaration(node)) {
return (0, node_inspection_1.getIdentifier)(node);
}
if (ts.isTypeAliasDeclaration(node)) {
return getTypeAliasName(node);
}
return undefined;
}
exports.getNameOfAssignment = getNameOfAssignment;
function getExpressionToAccessObjectMember(node) {
if (ts.isMethodDeclaration(node)) {
const [name, requiresDot] = getMethodDeclarationName(node);
if (requiresDot) {
return "this." + name;
}
else {
return "this" + name;
}
}
if (ts.isAccessor(node)) {
const [name, requiresDot] = getAccessorIdentifierName(node);
if (requiresDot) {
return "this." + name;
}
else {
return "this" + name;
}
}
return undefined;
}
exports.getExpressionToAccessObjectMember = getExpressionToAccessObjectMember;
/**
* @return [name, requires dot syntax]
*/
function getAccessorIdentifierName(node) {
for (const child of node.getChildren()) {
if (ts.isMemberName(child)) {
return [child.getText(), true];
}
if (ts.isComputedPropertyName(child)) {
return [child.getText(), false];
}
}
throw new node_util_1.UnreachableNodeState(node, "The accessor was expected to have an identifier or computed property name.");
}
function getIdentifierDespiteBrackets(node) {
if (ts.isMemberName(node) || ts.isElementAccessExpression(node)) {
return node.getText();
}
if (ts.isParenthesizedExpression(node)) {
return getIdentifierDespiteBrackets(node.getChildAt(1));
}
return undefined;
}
function getCalledFunctionName(node) {
const children = node.getChildren();
const expressionToCall = children[0];
const name = getIdentifierDespiteBrackets(expressionToCall);
return name !== null && name !== void 0 ? name : "";
}
function getClassDeclarationName(node) {
const name = (0, node_inspection_1.getIdentifier)(node);
return name !== null && name !== void 0 ? name : ""; // anonymous class
}
function getClassExpressionName(node, variableBeingDefined = undefined) {
var _a;
return (_a = maybeGetFirstIdentifierName(node)) !== null && _a !== void 0 ? _a : variableBeingDefined;
}
function getFunctionNodeName(func) {
if (ts.isAccessor(func)) {
const [name] = getAccessorIdentifierName(func);
return name;
}
if (ts.isArrowFunction(func)) {
return undefined;
}
if (ts.isFunctionDeclaration(func)) {
const functionKeywordIndex = func.getChildren()
.findIndex(node => node.kind === ts.SyntaxKind.FunctionKeyword);
const identifier = func.getChildAt(functionKeywordIndex + 1);
return identifier.getText();
}
if (ts.isFunctionExpression(func)) {
const maybeIdentifier = func.getChildren()[1];
if (ts.isMemberName(maybeIdentifier)) {
return maybeIdentifier.getText();
}
else {
return undefined;
}
}
if (ts.isMethodDeclaration(func)) {
const [name] = getMethodDeclarationName(func);
return name;
}
throw new node_util_1.UnreachableNodeState(func, "FunctionNode is not of a recognised type.");
}
function getInterfaceDeclarationName(node) {
return node.getChildAt(1).getText();
}
function getModuleDeclarationName(node) {
const moduleKeywordIndex = node.getChildren()
.findIndex(node => node.kind === ts.SyntaxKind.NamespaceKeyword
|| node.kind === ts.SyntaxKind.ModuleKeyword);
if (moduleKeywordIndex === -1) {
throw new node_util_1.UnreachableNodeState(node, "Module has no module/namespace keyword.");
}
const moduleIdentifier = node.getChildAt(moduleKeywordIndex + 1);
return moduleIdentifier.getText();
}
/**
* @return [name, requires dot syntax]
*/
function getMethodDeclarationName(node) {
for (const child of node.getChildren()) {
if (ts.isMemberName(child)) {
return [child.getText(), true];
}
if (ts.isComputedPropertyName(child)) {
return [child.getText(), false];
}
}
throw new node_util_1.UnreachableNodeState(node, "Method has no identifier.");
}
function getNewedConstructorName(node) {
return (0, node_inspection_1.getTextWithoutBrackets)(node.getChildAt(1));
}
function getTypeAliasName(node) {
return node.getChildAt(1).getText();
}
function maybeGetFirstIdentifierName(node) {
const name = node.getChildren()
.find(child => ts.isMemberName(child));
return name === null || name === void 0 ? void 0 : name.getText();
}
//# sourceMappingURL=node-naming.js.map