Skip to content

fix(injectable): read flag arrays in useFactory/useClass deps - #636

Open
edbzn wants to merge 1 commit into
voidzero-dev:mainfrom
edbzn:fix/deps-flag-arrays
Open

edbzn wants to merge 1 commit into
voidzero-dev:mainfrom
edbzn:fix/deps-flag-arrays

Conversation

@edbzn

@edbzn edbzn commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Fixes #629.

Problem

An @Injectable({ useFactory | useClass, deps }) entry written as flags plus a token, such as [new Optional(), new Self(), Dep], was converted to a token as a whole. The output was ɵɵinject([new Optional(), new Self(), Dep]), which fails at runtime. ngc emits ɵɵinject(Dep, 10).

Fix

extract_dependency (injectable/decorator.rs) now ports ngtsc's getDep (packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts). For an array entry, each element is read in turn:

  • Optional, Self or SkipSelf, bare or as new X(), sets that flag.
  • new Inject(T) sets the token to T.
  • Any other element sets the token, and the last one wins.

Like ngtsc, a flag only counts when the identifier is imported from @angular/core (under any alias). To check this, the file's consts are passed down to the useClass/useFactory deps extraction. That import check moved out of angular_core_decorator into a new helper, angular_core_identifier, which both now use. Like getDep, Host and Attribute are not handled in deps arrays.

Checks

  • New tests/injectable_provider_deps_test.rs:
    • use_factory_deps_with_array_literal_tokens: port of the ngtsc spec "should compile Injectables with providedIn and factory with deps with array literal tokens".
    • use_class_deps_with_bare_flag_identifiers
    • inject_entry_sets_the_token
    • flags_not_imported_from_angular_core_are_tokens
  • All four fail on main and pass with this change.
  • cargo test -p oxc_angular_compiler --all-features: 3520 passed, 0 failed, 1 ignored.

🤖 Generated with Claude Code

An `@Injectable` `deps` entry like `[new Optional(), new Self(), Dep]` was
passed whole as the DI token. Port ngtsc's `getDep`: `Inject`, `Optional`,
`SkipSelf` and `Self` from `@angular/core` set the flags (or the token, for
`new Inject(T)`), and any other element is the token.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@Injectable deps entries written as [new Optional(), new Self(), Dep] inject the array as the token

1 participant