UNPKG

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.

212 lines 8.32 kB
"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 () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.getColumnAndLine = getColumnAndLine; exports.getIdentifier = getIdentifier; exports.getFirstNonParenthesizedAncestor = getFirstNonParenthesizedAncestor; exports.getNodeKind = getNodeKind; exports.getTextWithoutBrackets = getTextWithoutBrackets; exports.isBreakOrContinueToLabel = isBreakOrContinueToLabel; exports.isContainer = isContainer; exports.isForLikeStatement = isForLikeStatement; exports.isFunctionNode = isFunctionNode; exports.isSyntaxList = isSyntaxList; exports.isNewSequenceOfBinaryOperators = isNewSequenceOfBinaryOperators; exports.isNewSequenceOfBinaryTypeOperators = isNewSequenceOfBinaryTypeOperators; exports.isChainableBinaryOperator = isChainableBinaryOperator; exports.isChainableBinaryTypeOperator = isChainableBinaryTypeOperator; exports.breaksASequenceOfBinaryOperators = breaksASequenceOfBinaryOperators; exports.pausesASequenceOfBinaryOperators = pausesASequenceOfBinaryOperators; exports.pausesASequenceOfBinaryTypeOperators = pausesASequenceOfBinaryTypeOperators; exports.passThroughNameBeingAssigned = passThroughNameBeingAssigned; exports.report = report; const ts = __importStar(require("typescript")); const util_1 = require("../util/util"); function getColumnAndLine(node) { const lineAndCol = node.getSourceFile() .getLineAndCharacterOfPosition(node.getStart()); return { column: lineAndCol.character + 1, line: lineAndCol.line + 1, }; } function getIdentifier(node) { for (const child of node.getChildren()) { if (ts.isMemberName(child) || ts.isComputedPropertyName(child)) { return child.getText(); } } return undefined; } function getFirstNonParenthesizedAncestor(node) { let firstNonParenthesisAncestor = node.parent; while (ts.isParenthesizedExpression(firstNonParenthesisAncestor)) { firstNonParenthesisAncestor = firstNonParenthesisAncestor.parent; } return firstNonParenthesisAncestor; } function getNodeKind(node) { if (isFunctionNode(node)) { return "function"; } if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) { return "class"; } if (ts.isTypeAliasDeclaration(node) || ts.isInterfaceDeclaration(node)) { return "type"; } if (ts.isModuleDeclaration(node)) { return "module"; } return undefined; } function getTextWithoutBrackets(node) { if (ts.isParenthesizedExpression(node)) { return node.getChildren() .slice(1, -1) // ignore the bracket at each end .map(getTextWithoutBrackets) .join(""); } return node.getText(); } function isBreakOrContinueToLabel(node) { if (ts.isBreakOrContinueStatement(node)) { for (const child of node.getChildren()) { if (ts.isMemberName(child)) { return true; } } } return false; } function isContainer(node) { return isFunctionNode(node) || ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isModuleDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isSourceFile(node) || ts.isSourceFile(node.parent); } function isForLikeStatement(node) { return ts.isForInStatement(node) || ts.isForOfStatement(node) || ts.isForStatement(node); } function isFunctionNode(node) { return ts.isArrowFunction(node) || ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isMethodDeclaration(node) || ts.isConstructorDeclaration(node) || ts.isAccessor(node); } function isSyntaxList(node) { return node.kind === ts.SyntaxKind.SyntaxList; } function isNewSequenceOfBinaryOperators(node, precedingOperator) { if (!isChainableBinaryOperator(node) && node.kind !== ts.SyntaxKind.AmpersandAmpersandEqualsToken && node.kind !== ts.SyntaxKind.BarBarEqualsToken && node.kind !== ts.SyntaxKind.QuestionQuestionEqualsToken) { return false; } // is now an operator, or is different to previous operator return precedingOperator === undefined || node.kind !== precedingOperator; } function isNewSequenceOfBinaryTypeOperators(node, precedingTypeOperator) { if (!isChainableBinaryTypeOperator(node)) { return false; } return precedingTypeOperator !== node.kind; } function isChainableBinaryOperator(node) { return node.kind === ts.SyntaxKind.AmpersandAmpersandToken || node.kind === ts.SyntaxKind.BarBarToken || node.kind === ts.SyntaxKind.QuestionQuestionToken; } function isChainableBinaryTypeOperator(node) { const isPartOfTypeExpression = (node === null || node === void 0 ? void 0 : node.parent) !== undefined // this is actually undefined-able && (ts.isUnionTypeNode(node.parent) || ts.isIntersectionTypeNode(node.parent)); // doing .parent skips the syntax list for some reason return isPartOfTypeExpression && (node.kind === ts.SyntaxKind.AmpersandToken || node.kind === ts.SyntaxKind.BarToken); } /** * A node that causes an end to a sequence of binary operators * (i.e. A && B { C && D }, the curly braces end the prior sequence; * C will not be interpreted as part of the last sequence. */ function breaksASequenceOfBinaryOperators(node) { return ts.isStatement(node) || ts.isBlock(node) || isFunctionNode(node) || ts.isParameter(node) || ts.isTypeParameterDeclaration(node) || ts.isPropertyDeclaration(node) || (node.kind === ts.SyntaxKind.ColonToken && isFunctionNode(node.parent)) || node.kind === ts.SyntaxKind.FirstAssignment; // separates extends expression from parameter default } /** * A node that doesn't cause an end to a sequence of binary operators * (i.e. A && Node && B, the 2 && are in the same sequence) * but the node's children don't form part of that sequence * (i.e. A && Node(B && C) && D, this is two sequences, one inside Node(), the other outside) */ function pausesASequenceOfBinaryOperators(node) { return ts.isCallLikeExpression(node) || ts.isPrefixUnaryExpression(node) || ts.isElementAccessExpression(node); } /** * @see {pausesASequenceOfBinaryOperators} but for type operators */ function pausesASequenceOfBinaryTypeOperators(node) { return ts.isParenthesizedExpression(node) || ts.isTypeReferenceNode(node) || ts.isAsExpression(node); } function passThroughNameBeingAssigned(node) { return isSyntaxList(node) || ts.isObjectLiteralExpression(node) || ts.isParenthesizedExpression(node); } function report(node, depth = 0) { const toLog = [(0, util_1.repeat)("\t", depth), ts.SyntaxKind[node.kind], node.kind]; console.error(...toLog); for (const child of node.getChildren()) { report(child, depth + 1); } } //# sourceMappingURL=node-inspection.js.map