Repository navigation
Description
Problem
TSDecorator.qualified_name is documented as "checker-resolved FQN when available". It is not
resolved by anything. It is ts-morph's Decorator.getFullName() — the written expression text —
and the builder never consults the checker (src/syntactic_analysis/builders.ts, decoratorsOf).
Measured with a decorator imported as import { Get as HttpGet } from "./decorators", where
resolution is trivial: the field emits HttpGet, the alias as typed. So the field is a second copy
of name with dots, and every consumer that trusted the comment — including #143 — was misled.
Consequence in #143 as shipped: :TSDecorator merges on qualified_name || name, so a project's
local @Get and NestJS's @Get collapse into one node. The "two spellings, one decorator"
behaviour that PR describes works in the opposite direction from python's.
Found while propagating python 1.4.1's entrypoint changes; this is unit 0 of
docs/design/specs/entrypoint-detection.md
(#150), and blocks the decorator matcher there.
Scope boundary
The two decorator identity fields only. No entrypoint detection, no rules file, no changes to
argument capture.
Goals
-
qualified_nameis the import-table resolution of the written spelling, or absent when
the decorator's head is not an imported binding — python's rule ("Jedi, else the import table,
elseNone") minus the Jedi step TypeScript does not have -
nameis the decorator as written (http.route, notroute), so an unresolved dotted
decorator keeps its spelling in the output — python'snameis the written spelling for the
same reason - The resolver is reusable: the entrypoint pass (units 2-3) needs the same import table for base
classes and the unresolved counter - Schema comments say what the fields actually hold
Caveats and known risks
This changes emitted values, so it is a fix with a visible effect rather than an invisible one:
| decorator | name before → after |
qualified_name before → after |
|---|---|---|
@Get from @nestjs/common |
Get → Get |
Get → @nestjs/common.Get |
@HttpGet via import { Get as HttpGet } |
HttpGet → HttpGet |
HttpGet → <module>.Get |
@http.route via import * as http |
route → http.route |
http.route → <module>.route |
@Local declared in the same file |
Local → Local |
Local → absent |
Neo4j :TSDecorator merge key (qualified_name || name) therefore becomes package-qualified for
imported decorators and stays the written spelling for local ones — which is what #143 meant.
Not a breaking change: the field was documented as resolved and never was. But anything that
matched on the old bare qualified_name sees different values.
Definition of done
- The four rows above are asserted end-to-end, including the alias and namespace cases
- A same-file decorator emits no
qualified_name bun testgreen; the feat(neo4j): project decorators, matching python #143 test still passes (its decorators are same-file, so the merge key is
unchanged there)- Container tests run against live Neo4j
Activity