fix(directive): compile inputs:/outputs: declared in decorator metadata - #493
Open
ashley-hunter wants to merge 1 commit into
Open
ashley-hunter wants to merge 1 commit into
ashley-hunter wants to merge 1 commit into
Conversation
…tadata
`@Directive({ inputs: [...] })` and `@Component({ inputs: [...], outputs: [...] })`
were ignored by the decorator parsers, so metadata-declared inputs and outputs
were silently dropped from the compiled definition and template bindings went
to the element instead of the directive.
Both parsers now read `inputs:` (`'name'`, `'name: alias'`,
`{ name, alias?, required?, transform? }`) and `outputs:` (`'name'`,
`'name: alias'`) and merge them with `@Input`/`@Output`/signal members the way
ngtsc does: keyed by class property, a member declaration replacing a metadata
entry in place, a repeated metadata entry keeping its first position.
Values are read through a single-file model of ngtsc's partial evaluator
(`directive/evaluator.rs`): literals, template strings, arrays and objects with
spreads, and same-file `const`/`let`/`var`, so `inputs: [...SHARED, 'x']`
resolves like it does in ngtsc. Forms ngtsc rejects now report its diagnostics
word for word instead of being dropped (non-array values, invalid entries,
entries without a `name`, signal members also listed in metadata). Values
imported from another file can't be evaluated from one file and are reported
as unresolvable.
`decorator_metadata_ngtsc_test.rs` compares diagnostics, inputs/outputs maps
and `.d.ts` declarations against a snapshot of `@angular/compiler-cli` 22.1.7's
output for Angular's own specs covering decorator `inputs`/`outputs`, plus
probes of the evaluator.
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.
Stack (1/4): #493 inputs/outputs → #494 transform validation → #495
queries:→ #496.d.tstransform types. This is #493.Fixes
inputs:andoutputs:declared in@Directive/@Componentmetadata being silently dropped from the compiled definition.The bug
compiled to
ɵɵdefineDirective({ type: A, selectors: [["a"]] }): noinputsat all. The decorator parsers never read theinputs/outputskeys, so there was no error either, and a binding like[x]="..."went to the element as a property instead of reaching the directive. The same happened for@Component, foroutputs:, and on abstract@Directive()bases (whose subclasses then inherited nothing).The fix
Both decorator parsers now read
inputs:('name','name: alias',{ name, alias?, required?, transform? }) andoutputs:('name','name: alias') and merge them with@Input/@Output/signal members the way ngtsc does ({...inputsFromMeta, ...inputsFromFields}): keyed by class property, a member replacing a metadata entry in place, a repeated metadata entry keeping its first position, and anything after a second:ignored.Values are read through
directive/evaluator.rs, a single-file model of ngtsc's partial evaluator: literals, template strings, arrays and objects with spreads, and same-fileconst/let/var. Soinputs: [...SHARED, 'x']with a same-fileSHAREDresolves like it does in ngtsc. Each file's top-level declarations are only collected when a decorator actually needs one, and eachconstis evaluated once.Forms ngtsc rejects now report its diagnostic word for word instead of being dropped: a non-array
inputs:/outputs:, entries that aren't strings or object literals, objects without a stringname, and a signalinput()/output()/model()also listed in the metadata. Like ngtsc, only the first error per class is reported.Values imported from another file can't be evaluated from one file, so they're reported as unresolvable, where ngtsc would follow the import. Operators and calls in metadata (
inputs: cond ? a : b) are also reported rather than evaluated.Tests
decorator_inputs_outputs_test.rs: the original report, which failed before the fix.decorator_metadata_ngtsc_test.rscompares diagnostics, the inputs/outputs maps and the.d.tsdeclarations with a snapshot of@angular/compiler-cli22.1.7's output (tests/fixtures/decorator_metadata_ngtsc.json). The cases are Angular's own specs for decoratorinputs/outputs(ngtsc_spec,authoring_{inputs,outputs,models}_spec, theorder_bindingscompliance case, and thedirective_specacceptance cases), plus probes of the evaluator and its diagnostics. Maps are compared ignoring whitespace and parentheses, which the two emitters place differently.decorator-metadata-angular-spec.fixture.ts), which diffs the full file against a live ngtsc.