Context
The @analogjs/angular-compiler introduces JSX-style prop spreading in Angular templates:
At build time, the compiler expands this into individual input bindings ([name]="props.name" [title]="props.title") using a component registry that maps selectors to their declared inputs. The Angular Language Service doesn't understand {...} syntax, so the extension needs to provide editor support for it.
Architecture
Component Registry
A persistent ComponentRegistry (Map<string, RegistryEntry>) built from two sources:
- Project source files — scan
.ts files using scanFile() from @analogjs/angular-compiler. Extracts selectors, inputs, and outputs from @Component/@Directive decorators and signal APIs (input(), output(), model()).
- Installed packages — scan
.d.ts files in node_modules using scanPackageDts(). Reads Ivy declaration types (ɵɵComponentDeclaration, etc.) to extract metadata from pre-compiled Angular packages.
Built on server startup and incrementally updated via file watchers.
Volar Service Plugin
A custom Volar LanguageServicePlugin named analog-spread providing three features:
Hover (provideHover)
When the cursor is over a {...identifier} expression, show:
- The matched component selector and class name
- The list of inputs that will be expanded (name, type, required/optional, signal-based)
- Which inputs are skipped due to explicit bindings on the same element
Completions (provideCompletionItems)
When typing inside {...}:
- Triggered by
{ character
- Offer
{... snippet when { is typed inside an opening tag
- Suggest variables in scope that could be spread
Diagnostics (provideDiagnostics)
Scan the template for {...} patterns using scanSpreads() and report:
- Unknown component: spread on an element whose selector isn't in the registry
- Missing required inputs: spread identifier doesn't cover all
required inputs
- Multiple spreads: more than one spread on the same element
Files to Create/Modify
New files
packages/language-server/src/registry.ts — Wraps @analogjs/angular-compiler scanning APIs (initial scan, incremental updates, lookup by selector)
packages/language-server/src/plugins/spreadPlugin.ts — Volar LanguageServicePlugin with hover, completions, and diagnostics
Modified files
packages/language-server/package.json — Add dependency on @analogjs/angular-compiler
packages/language-server/src/index.ts — Import and register the spread plugin
Key Dependencies
@analogjs/angular-compiler — scanFile(), scanDtsFile(), scanPackageDts(), collectImportedPackages(), scanSpreads()
- Brings
oxc-parser (Rust-based, fast) and magic-string
- Peer deps
@angular/compiler and @angular/compiler-cli are only needed for the compile() function, NOT for registry scanning
Verification
Context
The
@analogjs/angular-compilerintroduces JSX-style prop spreading in Angular templates:At build time, the compiler expands this into individual input bindings (
[name]="props.name" [title]="props.title") using a component registry that maps selectors to their declared inputs. The Angular Language Service doesn't understand{...}syntax, so the extension needs to provide editor support for it.Architecture
Component Registry
A persistent
ComponentRegistry(Map<string, RegistryEntry>) built from two sources:.tsfiles usingscanFile()from@analogjs/angular-compiler. Extracts selectors, inputs, and outputs from@Component/@Directivedecorators and signal APIs (input(),output(),model())..d.tsfiles innode_modulesusingscanPackageDts(). Reads Ivy declaration types (ɵɵComponentDeclaration, etc.) to extract metadata from pre-compiled Angular packages.Built on server startup and incrementally updated via file watchers.
Volar Service Plugin
A custom Volar
LanguageServicePluginnamedanalog-spreadproviding three features:Hover (
provideHover)When the cursor is over a
{...identifier}expression, show:Completions (
provideCompletionItems)When typing inside
{...}:{character{...snippet when{is typed inside an opening tagDiagnostics (
provideDiagnostics)Scan the template for
{...}patterns usingscanSpreads()and report:requiredinputsFiles to Create/Modify
New files
packages/language-server/src/registry.ts— Wraps@analogjs/angular-compilerscanning APIs (initial scan, incremental updates, lookup by selector)packages/language-server/src/plugins/spreadPlugin.ts— VolarLanguageServicePluginwith hover, completions, and diagnosticsModified files
packages/language-server/package.json— Add dependency on@analogjs/angular-compilerpackages/language-server/src/index.ts— Import and register the spread pluginKey Dependencies
@analogjs/angular-compiler—scanFile(),scanDtsFile(),scanPackageDts(),collectImportedPackages(),scanSpreads()oxc-parser(Rust-based, fast) andmagic-string@angular/compilerand@angular/compiler-cliare only needed for thecompile()function, NOT for registry scanningVerification
@analogjs/angular-compilerand verify build succeedsinput()signals{...props}shows component inputs