From 097c7d9b1328fc1cde0219db1866d382dbabaf4c Mon Sep 17 00:00:00 2001 From: itay mendelawy Date: Tue, 17 Feb 2026 21:58:48 +0000 Subject: [PATCH 1/2] removing deprecated apis and setting enableExtraction:true --- CHANGELOG.md | 6 ++ src/index.ts | 12 ++-- src/rules/max-cognitive.ts | 91 --------------------------- src/rules/max-cyclomatic.ts | 19 ------ src/rules/shared.ts | 119 ++---------------------------------- 5 files changed, 15 insertions(+), 232 deletions(-) delete mode 100644 src/rules/max-cognitive.ts delete mode 100644 src/rules/max-cyclomatic.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index c9a57af..70d88ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,10 +10,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Migrate plugin imports from `oxlint/plugins` to standalone `@oxlint/plugins` package (fixes compatibility with oxlint >= 1.45.0) +- **BREAKING:** `enableExtraction` now defaults to `true` — extraction suggestions are on by default (set `enableExtraction: false` to opt out) ### Added - Performance optimization: `minLines` option to skip complexity analysis for small functions. Default: 10 lines. +- Export `createCombinedComplexityVisitor` and `CombinedComplexityResult` from public API + +### Removed + +- **BREAKING:** Drop deprecated `complexity/max-cyclomatic` and `complexity/max-cognitive` rules — use `complexity/complexity` instead ## [1.0.0-rc.1] - 2026-02-08 diff --git a/src/index.ts b/src/index.ts index 1bd9b02..acb2c03 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,4 @@ import { definePlugin } from '@oxlint/plugins'; -import { maxCyclomatic } from './rules/max-cyclomatic.js'; -import { maxCognitive } from './rules/max-cognitive.js'; import { complexity } from './rules/complexity.js'; // Re-export types for library users @@ -24,6 +22,10 @@ export type { VisitorContext } from './visitor.js'; export { createCyclomaticVisitor } from './cyclomatic.js'; export { createCognitiveVisitor } from './cognitive/visitor.js'; +// Re-export combined visitor for advanced usage +export { createCombinedComplexityVisitor } from './combined-visitor.js'; +export type { CombinedComplexityResult } from './combined-visitor.js'; + // Re-export utilities export { getFunctionName, createComplexityPoint, summarizeComplexity } from './utils.js'; @@ -50,9 +52,7 @@ export { * Provides cyclomatic and cognitive complexity rules for oxlint. * * Rules: - * - complexity/complexity: RECOMMENDED - Enforce both metrics in one pass (17% faster) - * - complexity/max-cyclomatic: DEPRECATED - Use complexity instead - * - complexity/max-cognitive: DEPRECATED - Use complexity instead + * - complexity/complexity: Enforce both metrics in one pass */ const plugin = definePlugin({ meta: { @@ -60,8 +60,6 @@ const plugin = definePlugin({ }, rules: { complexity, - 'max-cyclomatic': maxCyclomatic, - 'max-cognitive': maxCognitive, }, }); diff --git a/src/rules/max-cognitive.ts b/src/rules/max-cognitive.ts deleted file mode 100644 index a740e12..0000000 --- a/src/rules/max-cognitive.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { defineRule } from '@oxlint/plugins'; -import type { - Rule, - Context, - FunctionNode, - ComplexityResult, - VisitorWithHooks, - ESTreeNode, - MaxCognitiveOptions, -} from '../types.js'; -import { getFunctionName, summarizeComplexity, formatBreakdown } from '../utils.js'; -import { createCognitiveVisitor } from '../cognitive/visitor.js'; -import { - normalizeCognitiveCategory, - warnDeprecated, - parseExtractionOptions, - getExtractionOutput, - EXTRACTION_SCHEMA_PROPERTIES, -} from './shared.js'; - -const DEFAULT_MAX = 15; - -/** - * Enforce a maximum cognitive complexity for functions. - * Default threshold: 15 - * - * For functions that significantly exceed the threshold (>150% of max), - * provides Smart Extraction Detection suggestions for refactoring. - * - * @deprecated Use 'complexity/complexity' instead for better performance. - */ -export const maxCognitive: Rule = defineRule({ - meta: { - type: 'suggestion', - docs: { - description: 'Cognitive Complexity of functions should not be too high', - recommended: false, - url: 'https://github.com/itaymendel/oxlint-plugin-complexity#complexitymax-cognitive', - }, - schema: [ - { - type: 'object', - properties: { - max: { - type: 'integer', - minimum: 0, - }, - ...EXTRACTION_SCHEMA_PROPERTIES, - }, - additionalProperties: false, - }, - ], - }, - - createOnce(context: Context) { - let maxComplexity = DEFAULT_MAX; - let parsed = parseExtractionOptions({}); - - return { - before() { - warnDeprecated('max-cognitive'); - - const options = (context.options[0] ?? {}) as MaxCognitiveOptions; - maxComplexity = options.max ?? DEFAULT_MAX; - parsed = parseExtractionOptions(options); - }, - - ...createCognitiveVisitor(context, (result: ComplexityResult, node: ESTreeNode) => { - if (result.total <= maxComplexity) return; - - const funcNode = node as FunctionNode; - const functionName = getFunctionName(funcNode, funcNode.parent); - const summary = summarizeComplexity(result.points, normalizeCognitiveCategory); - const breakdown = formatBreakdown(result.points, parsed.breakdownOptions); - const extractionOutput = getExtractionOutput( - parsed, - context, - node, - result.points, - result.total, - maxComplexity - ); - - context.report({ - node, - message: `Function '${functionName}' has Cognitive Complexity of ${result.total}. Maximum allowed is ${maxComplexity}.${summary}${breakdown}${extractionOutput}`, - }); - }), - } as VisitorWithHooks; - }, -}); diff --git a/src/rules/max-cyclomatic.ts b/src/rules/max-cyclomatic.ts deleted file mode 100644 index 54111ed..0000000 --- a/src/rules/max-cyclomatic.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { Rule } from '../types.js'; -import { createCyclomaticVisitor } from '../cyclomatic.js'; -import { createComplexityRule, warnDeprecated } from './shared.js'; - -/** - * Enforce a maximum cyclomatic complexity for functions. - * Default threshold: 20 - * - * @deprecated Use 'complexity/complexity' instead for better performance. - */ -export const maxCyclomatic: Rule = createComplexityRule({ - metricName: 'cyclomatic complexity', - defaultMax: 20, - schemaMinimum: 1, - description: 'Enforce a maximum cyclomatic complexity for functions', - url: 'https://github.com/itaymendel/oxlint-plugin-complexity#complexitymax-cyclomatic', - before: () => warnDeprecated('max-cyclomatic'), - createVisitor: createCyclomaticVisitor, -}); diff --git a/src/rules/shared.ts b/src/rules/shared.ts index f2d0388..7a19d91 100644 --- a/src/rules/shared.ts +++ b/src/rules/shared.ts @@ -1,21 +1,5 @@ -import { defineRule } from '@oxlint/plugins'; -import type { - Rule, - Context, - Visitor, - FunctionNode, - ComplexityPoint, - ComplexityResult, - VisitorWithHooks, - ESTreeNode, - MaxCognitiveOptions, -} from '../types.js'; -import { - getFunctionName, - summarizeComplexity, - formatBreakdown, - type BreakdownOptions, -} from '../utils.js'; +import type { Context, ComplexityPoint, ESTreeNode, MaxCognitiveOptions } from '../types.js'; +import { type BreakdownOptions } from '../utils.js'; import { analyzeExtractionOpportunities, shouldAnalyzeExtraction, @@ -24,79 +8,6 @@ import { } from '../extraction/index.js'; import { getVariablesForFunction } from '../extraction/variable-tracker.js'; -/** - * Configuration for creating a simple complexity rule - * (single metric, no extraction analysis). - */ -export interface ComplexityRuleConfig { - metricName: string; - defaultMax: number; - schemaMinimum: number; - description: string; - url: string; - - /** Factory to create the visitor */ - createVisitor: ( - onComplexityCalculated: (result: ComplexityResult, node: ESTreeNode) => void - ) => Visitor; - - /** Called once before the first file is processed */ - before?: () => void; - - normalizeCategory?: (category: string) => string; -} - -export function createComplexityRule(config: ComplexityRuleConfig): Rule { - return defineRule({ - meta: { - type: 'suggestion', - docs: { - description: config.description, - recommended: false, - url: config.url, - }, - schema: [ - { - type: 'object', - properties: { - max: { - type: 'integer', - minimum: config.schemaMinimum, - }, - }, - additionalProperties: false, - }, - ], - }, - - createOnce(context: Context) { - let maxComplexity = config.defaultMax; - - return { - before() { - const options = (context.options[0] ?? {}) as { max?: number }; - maxComplexity = options.max ?? config.defaultMax; - config.before?.(); - }, - - ...config.createVisitor((result, node) => { - if (result.total > maxComplexity) { - const funcNode = node as FunctionNode; - const name = getFunctionName(funcNode, funcNode.parent); - const summary = summarizeComplexity(result.points, config.normalizeCategory); - const breakdown = formatBreakdown(result.points); - - context.report({ - node, - message: `Function '${name}' has ${config.metricName} of ${result.total}. Maximum allowed is ${maxComplexity}.${summary}${breakdown}`, - }); - } - }), - } as VisitorWithHooks; - }, - }); -} - export function normalizeCognitiveCategory(category: string): string { if (category.startsWith('logical operator')) return 'logical operators'; if (category.startsWith('nested ')) return 'nested functions'; @@ -104,28 +15,6 @@ export function normalizeCognitiveCategory(category: string): string { return category; } -const MIGRATION_URL = 'https://github.com/itaymendel/oxlint-plugin-complexity#migration-to-v1'; -const warnedDeprecations = new Set(); - -export function warnDeprecated(ruleName: string): void { - if (warnedDeprecations.has(ruleName)) return; - warnedDeprecations.add(ruleName); - - // eslint-disable-next-line no-console -- Intentional deprecation warning - console.warn(` -DEPRECATION WARNING: complexity/${ruleName} - - Use "complexity/complexity" instead for better performance: - - "complexity/complexity": ["warn", { - "cyclomatic": 20, - "cognitive": 15 - }] - - See: ${MIGRATION_URL} -`); -} - /** JSON Schema properties shared by rules that support extraction analysis and breakdown tips. */ export const EXTRACTION_SCHEMA_PROPERTIES = { extractionMultiplier: { @@ -141,7 +30,7 @@ export const EXTRACTION_SCHEMA_PROPERTIES = { }, enableExtraction: { type: 'boolean', - description: 'Enable smart extraction suggestions for complex functions (default: false)', + description: 'Enable smart extraction suggestions for complex functions (default: true)', }, nestingTipThreshold: { type: 'integer', @@ -171,7 +60,7 @@ export interface ParsedExtractionOptions { export function parseExtractionOptions(options: ExtractionSchemaOptions): ParsedExtractionOptions { return { - enableExtraction: options.enableExtraction ?? false, + enableExtraction: options.enableExtraction ?? true, extractionOptions: { minComplexityMultiplier: options.extractionMultiplier, minComplexityPercentage: options.minExtractionPercentage, From 21f4419dc11426b71d0ce36871938c90cfaa620c Mon Sep 17 00:00:00 2001 From: itay mendelawy Date: Tue, 17 Feb 2026 22:01:40 +0000 Subject: [PATCH 2/2] chore: update readme --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ea6acdb..c2a4a54 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ function processData(items, mode, config) { "minLines": 10, // Default: 10 (skip functions <10 lines like getters; 0 = analyze all; counts comments/blanks) // Extraction suggestions (optional) - "enableExtraction": true, // Default: false + "enableExtraction": true, // Default: true "extractionMultiplier": 1.5, // Default: 1.5 (triggers at 1.5× cognitive threshold) "minExtractionPercentage": 30, // Default: 30 (min % of total complexity to suggest) @@ -122,7 +122,7 @@ Detects common complexity patterns and provides actionable tips: ### Extraction Suggestions -When `enableExtraction: true`, analyzes variable flow to identify extractable code blocks: +Analyzes variable flow to identify extractable code blocks (enabled by default, disable with `enableExtraction: false`): **Example output:** @@ -159,9 +159,9 @@ Always review suggestions before applying, even when marked "high confidence". --- -## Migration from v0.x to v1.0 +## Migration from v0.x -**v1.0:** Combined rule for better performance. Separate rules deprecated: +Replace the removed `max-cyclomatic` / `max-cognitive` rules with the combined `complexity` rule: ```diff // .oxlintrc.json