Skip to content

tools: refactor code-quality scorer and add header/macro/PARAM rules - #8158

Merged
mohanchen merged 5 commits into
deepmodeling:developfrom
mohanchen:2026-10-16-a
Oct 17, 2026
Merged

mohanchen merged 5 commits into
deepmodeling:developfrom
mohanchen:2026-10-16-a

Conversation

@mohanchen

Copy link
Copy Markdown
Collaborator

Summary

Refactor tools/03_code_analysis/code_quality_score.py and extend it
with new AGENTS.md-backed rules. All changes are confined to the
scoring tool and AGENTS.md; no solver or build code is touched.

Changes

1. Split the scorer into focused modules (bfecaf3cb)

The 2349-line code_quality_score.py now delegates to five
single-responsibility modules under tools/03_code_analysis/, while
the entry command (python3 code_quality_score.py ...) is unchanged:

Module Responsibility
cqs_config.py weights, caps, thresholds, compiled regexes, prefix helper
cqs_text.py comment/string stripping, comment-block extraction
cqs_rules.py rule-detection (find_* / analyze_*) functions
cqs_analyze.py per-file analysis orchestration, file discovery
cqs_report.py Finding/FileReport dataclasses, text/JSON renderers

This commit also folds in two rule additions made just before the
split and broadens one existing rule:

  • complex_argument_expression (AGENTS.md §14): penalises a ternary
    ?:, && or || used as a top-level call argument (weight 1, cap 5).
  • ifdef_in_call_args: penalises #if/#ifdef blocks wrapping
    arguments inside a call's argument list (weight 1, cap 5).
  • the using-namespace rule now matches any using namespace X;
    directive instead of only using namespace std;.

2. Header-specific rules (f005fb6c4)

  • header_too_long: a .h file exceeding 120 lines costs 1 per extra
    10-line block, capped at 5 (stacks with the generic 500-line rule).
  • header_function_body: a non-inline, non-template function body
    exceeding 20 lines in a .h file costs 1 per extra 10-line block,
    capped at 5. inline functions, template <...> functions, and
    bodies at or below 20 lines are exempt.

3. New AGENTS.md rules 16 and 17 (ebb2716ca)

  • Rule 16 — new_macro_definition: a #define NAME ... in a
    .h/.cpp file costs 3 per definition (cap 10). Guard-style macros
    (name ending in _H/_HPP with no parameter list or replacement
    text) and #ifdef/#ifndef usages of existing macros are exempt.
  • Rule 17 — param_member_init: a member variable initialized from
    PARAM in a .h/.hpp file costs 5 per declaration (cap 10).
    Function default arguments and constructor member-initializer lists
    are out of scope (already covered by default_parameter /
    global_dependency).

Verification

No ABACUS compilation or runtime test was run (tooling-only change);
all checks are Python-level:

  • python3 -m py_compile passes on all touched modules after every
    commit.
  • Split commit: smoke sample (ternary/&&/|| args + #ifdef-wrapped
    args) scores identically before and after the split (92; rule A hits
    L7-L11, rule B hits L22, no false positives); a full source_base/
    scan (284 files) produces the same module rollup, text/JSON and -o
    output as before the split.
  • header_function_body: a smoke header with a 23-line plain body, a
    23-line inline body, a 23-line template body and a 6-line body
    charges only the plain long one; source_base/matrix.h shows no
    false positive.
  • new_macro_definition: a smoke header with a guard macro, an
    object-like macro and a function-like macro charges only the latter
    two; source_md/msst.h (guard only) shows no finding.
  • param_member_init: a smoke header with = PARAM..., {PARAM...},
    static const = PARAM..., a method default argument and a
    constructor init list charges only the three declaration-site
    initializations; source_base/matrix.h and source_md/md_base.h
    show no finding.

Notes

  • The entry command and CLI flags are unchanged; existing CI/pre-commit
    invocations of code_quality_score.py keep working.
  • Known limitation (documented in code): inline written on the line
    above a signature is not detected by header_function_body.

abacus_fixer added 3 commits October 16, 2026 11:16
The 2349-line scorer now delegates to five single-responsibility
modules while keeping the entry command unchanged:
  cqs_config.py  - weights/caps/thresholds/regexes/prefix helpers
  cqs_text.py    - comment/string stripping, comment-block extraction
  cqs_rules.py   - rule-detection (find_*/analyze_*) functions
  cqs_analyze.py - per-file analysis orchestration, file discovery
  cqs_report.py  - Finding/FileReport dataclasses, text/JSON renderers

Also folds in the two rule additions made just before the split:
  - complex_argument_expression (AGENTS.md §14): penalises a ternary
    ?:, && or || used as a top-level call argument (weight 1, cap 5)
  - ifdef_in_call_args: penalises #if/#ifdef blocks wrapping arguments
    inside a call's argument list (weight 1, cap 5)
and broadens the using-namespace rule from std-only to any
`using namespace X;` directive.

Verification: python3 -m py_compile on all six files; smoke sample
(ternary/&&/|| args + #ifdef-wrapped args) scores identically before
and after the split (92, rule A hits L7-L11, rule B hits L22, no false
positives); full source_base/ scan (284 files) produces the same
module rollup, text/JSON and -o output.
Add two .h-specific rules to the code-quality scorer:
  - header_too_long: .h file exceeding 120 lines costs 1 per extra
    10-line block, capped at 5 (stacks with the generic 500-line
    file rule)
  - header_function_body: a non-inline, non-template function body
    exceeding 20 lines in a .h file costs 1 per extra 10-line block,
    capped at 5. `inline` functions, `template <...>` functions, and
    bodies at or below 20 lines (typical accessors) are exempt.

Verification: python3 -m py_compile on all touched modules; smoke
header with a 23-line plain body, a 23-line inline body, a 23-line
template body and a 6-line plain body scores only the plain long one
(1 point); real source_base/matrix.h shows no header_function_body
false positive.
…, 17)

Add AGENTS.md rules 16 and 17 and the matching scorer checks:
  - new_macro_definition: a `#define NAME ...` in a .h/.cpp file costs
    3 per definition (cap 10). Guard-style macros (name ending in
    _H/_HPP with no parameter list or replacement text) are exempt.
  - param_member_init: a member variable initialized from PARAM in a
    .h/.hpp file costs 5 per declaration (cap 10). Function default
    arguments and constructor member-initializer lists are out of
    scope (already covered by default_parameter / global_dependency).

Verification: python3 -m py_compile on all touched modules.
Smoke .h with a guard macro, an object-like macro and a function-like
macro: only the latter two are charged (3 each); the guard is exempt;
source_md/msst.h (guard only) shows no new_macro_definition finding.
Smoke .h with `= PARAM...`, `{PARAM...}`, `static const = PARAM...`,
a method default argument and a constructor init list: the three
declaration-site initializations are charged (5 each), the method and
constructor forms are not; source_base/matrix.h and source_md/md_base.h
show no param_member_init finding.
@mohanchen mohanchen added the Standards Coding standards and governance rules label Oct 16, 2026

@AsTonyshment AsTonyshment left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few small edge cases in the new checks that need refinement.

Comment thread tools/03_code_analysis/cqs_rules.py Outdated
Comment thread tools/03_code_analysis/cqs_rules.py Outdated
Comment thread tools/03_code_analysis/cqs_analyze.py Outdated
Comment thread tools/03_code_analysis/cqs_rules.py Outdated
abacus_fixer and others added 2 commits October 17, 2026 19:44
Resolve AGENTS.md rule-numbering conflict: keep upstream rules 16-19
(file-read confirmation, no shell mkdir/rm in unit tests, no
non-reentrant C stdlib functions, stream-state checks on numerical
input) and renumber the local rules to 20 (no new #define macros) and
21 (no PARAM member-variable init in headers). Update the rule-number
references in the code_quality_score tools accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes four issues raised in PR deepmodeling#8158 review:

1. complex_argument_expression false positives & negatives
   - skip declarations with any return-type prefix (e.g. `void f(int&&)`,
     `ESolver_KS_LCAO<T,TR>&&`), not just the 2-segment form
   - treat `<`/`>` as template nesting only in the glued form `Foo<int>`;
     spaced comparison operators (`a < b`, `>=`) no longer corrupt the
     call-argument depth
   - resume scanning inside the argument list so nested callees
     (`f(g(a ? b : c))`) are visited on their own

2. ifdef_in_call_args missed bare/method/keyword call forms
   - reorder _classify_opener: strip the callee name first, then decide
     call vs declaration from what remains; bare `f(`, `obj.f(`,
     `ptr->f(`, `return f(`, `else f(` are now call contexts

3. param_member_init false positives & negatives
   - new find_param_member_inits strips comments AND strings over the
     whole file, scans only top-level class bodies, and requires the
     match to sit at the class's own brace/paren depth (excludes locals
     in inline functions, default arguments, comment blocks, strings)
   - regex now matches cross-line declarations and `= <expr> PARAM...`
     initializers; reported line aligns with the declaration text

4. header_function_body template detection
   - one-line `template <...> void f(...)`, multi-line template headers
     above the signature, and members of templated classes are exempt
   - formatting (line breaks) no longer changes the verdict

Verification: py_compile of all modules; reviewer's exact samples now
score as expected; full source/ scan (1944 files) changes only 25
findings, all verified as true improvements (avg 82.6507 -> 82.6697).
@mohanchen
mohanchen merged commit 104af86 into deepmodeling:develop Oct 17, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Standards Coding standards and governance rules

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants