Commit Graph

1 Commits

Author SHA1 Message Date
apk 8b75eb7834 feat(summary): count complexity per function, the way each language branches
The CX column was one path per file plus every branch keyword the token
stream showed, and on the generic tokenizer that list was partly
unreachable: it splits punctuation into single characters, so the && and ||
entries never matched outside JavaScript and ?? counted twice. Measured
against lizard on ten GitHub-trending projects in nine languages, CX ranked
files with a median Spearman correlation of 0.83 and put their size at 0.75
of lizard's.

- Adjacent punctuation is joined before matching, so short-circuit
  operators count in every language.
- Per-language rules: Rust match arms count by their =>, less one per match
  since N arms are N paths; Swift adds guard and Go select. Where ? also
  marks an optional (TypeScript, JavaScript, Swift, Kotlin, Groovy, C#) it
  counts only as a ternary, told apart from String? and x?.y by being
  written in the open; ?: is Elvis only in Kotlin and Groovy.
- One path per function: by declaring keyword (def, fn, func, function, fun,
  and => for arrow functions), and in C, C++, Java, Objective-C and C# by the
  head(args) { shape told apart from if (...) {. Languages with neither keep
  the per-file baseline.
- The body of a """ or ''' string no longer counts. The line-based tokenizer
  leaves its quotes in adjacent literals, and an odd number of triple quotes
  in such a run opens or closes the string, which handles the PEP 257
  opener """Summary. that a pair-of-tokens check read backwards. This is
  limited to languages where """ is a delimiter: where a doubled quote is an
  escape (C#, VB.NET, SQL, Pascal) it swallowed a 413-branch C# file.
- A keyword-shaped word the file binds as a name - case = 3, x.case,
  f(case, when) - is not a branch in that file.

On the same ten projects the median correlation rose to 0.92 and the ratio
to 1.00, and every project improved. Where CX and lizard still differ they
differ on purpose: lizard counts a match once whatever its arms, and does
not count ??.

Detection, tokenization and clone output are untouched: the fixtures corpus
reports the same 248 clones. fixtures/summary-demo has one file per language
whose complexity can be counted by hand, and every CX value matches it.
2026-09-17 12:36:55 +02:00