Skip to content

Accept heuristics.calls in the rules loader for cross-analyzer parity #187

Description

@rahlk

Is your feature request related to a problem? Please describe.

codeanalyzer/entrypoints/rules.py accepts exactly one matcher kind under heuristics: — decorators — and rejects unknown keys by design (_TOP_LEVEL_KEYS, and the comment at rules.py:22: blocks not implemented are "deliberately absent here rather than accepted-and-ignored, so a user file using them fails loudly instead of loading clean and doing nothing").

codeanalyzer-typescript is adding a second matcher kind to the same block, heuristics.calls, because its ecosystem declares entrypoints by call as often as by decorator — Express, Koa and Fastify are app.get('/p', handler), not @Get('/p'). Design and rationale: codeanalyzer-typescript docs/design/specs/entrypoint-detection.md, section "The heuristic tier".

The semantics are the ones #185 defined — written spelling, no resolution, runs on every node regardless of frameworks_detected, confidence: heuristic forced by the loader, runs last, never doubles a record a framework rule made — applied to a call expression's callee instead of a decorator. Same tier, same engine, one more shape.

Consequence today: a rules file shared between the two analyzers that contains heuristics.calls is a hard error in python. That is the loader working as intended, which is exactly why this needs a decision rather than a workaround.

Describe the solution you'd like

  • heuristics.calls is a known key: validated for shape (a list of rules with id, match, and the same optional route/methods spec as decorators, plus handler), then ignored
  • A rules file carrying both heuristics.decorators and heuristics.calls loads clean
  • heuristics.<anything else> still fails loudly, so the "no silent no-ops" property is kept

Describe alternatives you've considered

Not stated in the original issue.

Additional context

Scope boundary

Loader acceptance only. Python does not need to act on calls: — it has no call-declared entrypoint frameworks in its shipped ruleset.

Not in scope: implementing a call-site matcher in python.

Caveats and known risks

  • Accepted-and-ignored is the thing rules.py:22 argues against, and rightly. The distinction here: calls: is not an unimplemented python feature a user might be relying on — it is a matcher kind that has no python meaning. Validating its shape while not acting on it keeps a malformed rule loud without pretending python matches calls. Worth stating in the code comment, so the next reader does not see it as an exception to the rule.
  • If python ever grows a call-declared framework worth shipping rules for, the key is already there.

Definition of done

  • The shared-format test loads a file with both keys and asserts python produced entrypoints only from decorators
  • A heuristics.calls entry with a malformed shape still raises RulesError
  • An unknown key under heuristics still raises RulesError

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions