fix(schema): decorator qualified_name is the import-table resolution or absent - #152
Merged
Merged
Conversation
…or absent
`TSDecorator.qualified_name` was documented as "checker-resolved FQN when available".
It was ts-morph's `Decorator.getFullName()` -- the written expression text -- and the
builder never consulted the checker. Measured with `import { Get as HttpGet }`, where
resolution is trivial: the field emitted `HttpGet`, the alias as typed.
Now `qualified_name` is 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, else None") minus the Jedi tier TypeScript does not have. Aliases map
back to the exported name; module specifiers are kept verbatim, which is the spelling
a rule names.
`name` becomes the spelling as WRITTEN (`http.route`, not `route`). The full spelling
used to survive only in `qualified_name`; once that is resolved-or-absent, an unresolved
dotted decorator would otherwise lose it from the output entirely. Python's `name` is
the written spelling for the same reason.
Effect on #143's Neo4j merge (`qualified_name || name`): imported decorators now merge
on a package-qualified key, same-file ones on their written spelling. That is what
the PR described and the opposite of what it did -- a local `@Get` and NestJS's `@Get`
collapsed into one node.
The resolver is its own module because the entrypoint pass (#72 units 2-3) needs the
same import table for base classes and the unresolved counter.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #151. Unit 0 of the entrypoint spec (#150), ahead of the decorator matcher.
TSDecorator.qualified_namewas documented as "checker-resolved FQN when available". It was ts-morph'sDecorator.getFullName()— the written expression text — and the builder never consulted the checker.Measured with
import { Get as HttpGet } from "./decorators", where resolution is trivial: the fieldemitted
HttpGet, the alias as typed.What changes
qualified_nameis now the import-table resolution of the written spelling, or absent when thedecorator's head is not an imported binding. Python's rule — "Jedi, else the import table, else
None" —minus the Jedi tier TypeScript does not have.
nameis the spelling as written.namebefore → afterqualified_namebefore → after@Getfrom@nestjs/commonGet→GetGet→@nestjs/common.Get@HttpGetviaimport { Get as HttpGet }HttpGet→HttpGetHttpGet→<module>.Get@http.routeviaimport * as httproute→http.routehttp.route→<module>.route@Dflt.decoviaimport Dflt fromdeco→Dflt.decoDflt.deco→<module>.default.deco@Localdeclared in the same fileLocal→LocalLocal→ absentWhy
namechanges too. The full spelling used to survive only inqualified_name. Once that isresolved-or-absent, an unresolved dotted decorator would lose its spelling from the output entirely.
Python's
nameis the written spelling for the same reason, and the entrypoint pass's unresolved counterneeds it.
Effect on #143. Its
:TSDecoratornode merges onqualified_name || name. Before this, a project'slocal
@Getand NestJS's@Getcollapsed into one node — the opposite of the "two spellings, onedecorator" behaviour the PR described. Now imported decorators merge on a package-qualified key and
same-file ones on their written spelling.
The resolver lives in its own module (
importResolver.ts) because the entrypoint pass needs the sametable for base classes and the unresolved counter.
Verification
bun test— 242 pass, 0 fail (3 new): the import table's mapping, all five rows above end-to-end,and the absent case asserted as key not present, not
undefinedgetFullName()fails 2 of the 3 new testsbun run typecheckcleanNot a breaking change, but a visible one
The field was documented as resolved and never was, so this is a
fix. But anything that matched on theold bare
qualified_namesees different values, and dotted decorators'namegains its prefix. Bothare called out here rather than left for a consumer to discover.