Skip to content

Commit fc97a41

Browse files
dylhunnalxhub
authored andcommitted
refactor(compiler): Add a new helper method getPrimaryAngularDecorator. (angular#47180)
This helper accepts a class, and returns the primary Angular Decorator associated with that trait (e.g. the Component, Pipe, Directive, or NgModule decorator). This will be useful for the language service import project, which needs to edit import arrays inside the decorator. PR Close angular#47180
1 parent c467eb7 commit fc97a41

File tree

17 files changed

+219
-5
lines changed

17 files changed

+219
-5
lines changed

packages/compiler-cli/src/ngtsc/annotations/component/src/handler.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ export class ComponentDecoratorHandler implements
444444
rawImports,
445445
resolvedImports,
446446
schemas,
447+
decorator: decorator?.node as ts.Decorator | null ?? null,
447448
},
448449
diagnostics,
449450
};
@@ -483,6 +484,7 @@ export class ComponentDecoratorHandler implements
483484
imports: analysis.resolvedImports,
484485
animationTriggerNames: analysis.animationTriggerNames,
485486
schemas: analysis.schemas,
487+
decorator: analysis.decorator,
486488
});
487489

488490
this.resourceRegistry.registerResources(analysis.resources, node);

packages/compiler-cli/src/ngtsc/annotations/component/src/metadata.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export interface ComponentAnalysisData {
7070
resolvedImports: Reference<ClassDeclaration>[]|null;
7171

7272
schemas: SchemaMetadata[]|null;
73+
decorator: ts.Decorator|null;
7374
}
7475

7576
export type ComponentResolutionData =

packages/compiler-cli/src/ngtsc/annotations/directive/src/handler.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export interface DirectiveHandlerData {
4141
outputs: ClassPropertyMapping;
4242
isPoisoned: boolean;
4343
isStructural: boolean;
44+
decorator: ts.Decorator|null;
4445
}
4546

4647
export class DirectiveDecoratorHandler implements
@@ -115,6 +116,7 @@ export class DirectiveDecoratorHandler implements
115116
providersRequiringFactory,
116117
isPoisoned: false,
117118
isStructural: directiveResult.isStructural,
119+
decorator: decorator?.node as ts.Decorator | null ?? null,
118120
}
119121
};
120122
}
@@ -149,6 +151,7 @@ export class DirectiveDecoratorHandler implements
149151
isStandalone: analysis.meta.isStandalone,
150152
imports: null,
151153
schemas: null,
154+
decorator: analysis.decorator,
152155
});
153156

154157
this.injectableRegistry.registerInjectable(node);

packages/compiler-cli/src/ngtsc/annotations/ng_module/src/handler.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export interface NgModuleAnalysis {
4343
providersRequiringFactory: Set<Reference<ClassDeclaration>>|null;
4444
providers: ts.Expression|null;
4545
remoteScopesMayRequireCycleProtection: boolean;
46+
decorator: ts.Decorator|null;
4647
}
4748

4849
export interface NgModuleResolution {
@@ -442,6 +443,7 @@ export class NgModuleDecoratorHandler implements
442443
node, this.reflector, this.isCore, this.annotateForClosureCompiler),
443444
factorySymbolName: node.name.text,
444445
remoteScopesMayRequireCycleProtection,
446+
decorator: decorator?.node as ts.Decorator | null ?? null,
445447
},
446448
};
447449
}
@@ -464,6 +466,7 @@ export class NgModuleDecoratorHandler implements
464466
rawDeclarations: analysis.rawDeclarations,
465467
rawImports: analysis.rawImports,
466468
rawExports: analysis.rawExports,
469+
decorator: analysis.decorator,
467470
});
468471

469472
if (this.factoryTracker !== null) {

packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export interface PipeHandlerData {
2424
meta: R3PipeMetadata;
2525
classMetadata: R3ClassMetadata|null;
2626
pipeNameExpr: ts.Expression;
27+
decorator: ts.Decorator|null;
2728
}
2829

2930
/**
@@ -143,6 +144,7 @@ export class PipeDecoratorHandler implements
143144
},
144145
classMetadata: extractClassMetadata(clazz, this.reflector, this.isCore),
145146
pipeNameExpr,
147+
decorator: decorator?.node as ts.Decorator | null ?? null,
146148
},
147149
};
148150
}
@@ -159,6 +161,7 @@ export class PipeDecoratorHandler implements
159161
name: analysis.meta.pipeName,
160162
nameExpr: analysis.pipeNameExpr,
161163
isStandalone: analysis.meta.isStandalone,
164+
decorator: analysis.decorator,
162165
});
163166

164167
this.injectableRegistry.registerInjectable(node);

packages/compiler-cli/src/ngtsc/core/api/src/options.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ export interface TestOnlyOptions {
2525
*/
2626
_useHostForImportGeneration?: boolean;
2727

28+
/**
29+
* Enable the Language Service APIs for template type-checking for tests.
30+
*/
31+
_enableTemplateTypeChecker?: boolean;
32+
2833
/**
2934
* An option to enable ngtsc's internal performance tracing.
3035
*

packages/compiler-cli/src/ngtsc/core/src/compiler.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ export class NgCompiler {
256256
private cycleAnalyzer: CycleAnalyzer;
257257
readonly ignoreForDiagnostics: Set<ts.SourceFile>;
258258
readonly ignoreForEmit: Set<ts.SourceFile>;
259+
readonly enableTemplateTypeChecker: boolean;
259260

260261
/**
261262
* `NgCompiler` can be reused for multiple compilations (for resource-only changes), and each
@@ -314,10 +315,12 @@ export class NgCompiler {
314315
readonly programDriver: ProgramDriver,
315316
readonly incrementalStrategy: IncrementalBuildStrategy,
316317
readonly incrementalCompilation: IncrementalCompilation,
317-
readonly enableTemplateTypeChecker: boolean,
318+
enableTemplateTypeChecker: boolean,
318319
readonly usePoisonedData: boolean,
319320
private livePerfRecorder: ActivePerfRecorder,
320321
) {
322+
this.enableTemplateTypeChecker =
323+
enableTemplateTypeChecker || (options._enableTemplateTypeChecker ?? false);
321324
this.constructionDiagnostics.push(
322325
...this.adapter.constructionDiagnostics, ...verifyCompatibleTypeCheckOptions(this.options));
323326

@@ -1064,8 +1067,8 @@ export class NgCompiler {
10641067

10651068
const templateTypeChecker = new TemplateTypeCheckerImpl(
10661069
this.inputProgram, notifyingDriver, traitCompiler, this.getTypeCheckingConfig(), refEmitter,
1067-
reflector, this.adapter, this.incrementalCompilation, scopeReader, typeCheckScopeRegistry,
1068-
this.delegatingPerfRecorder);
1070+
reflector, this.adapter, this.incrementalCompilation, metaReader, scopeReader,
1071+
typeCheckScopeRegistry, this.delegatingPerfRecorder);
10691072

10701073
// Only construct the extended template checker if the configuration is valid and usable.
10711074
const extendedTemplateChecker = this.constructionDiagnostics.length === 0 ?

packages/compiler-cli/src/ngtsc/metadata/src/api.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ export interface NgModuleMeta {
4848
* because the module came from a .d.ts file).
4949
*/
5050
rawExports: ts.Expression|null;
51+
52+
/**
53+
* The primary decorator associated with this `ngModule`.
54+
*
55+
* If this is `null`, no decorator exists, meaning it's probably from a .d.ts file.
56+
*/
57+
decorator: ts.Decorator|null;
5158
}
5259

5360
/**
@@ -161,6 +168,13 @@ export interface DirectiveMeta extends T2DirectiveMeta, DirectiveTypeCheckMeta {
161168
* For standalone components, the list of schemas declared.
162169
*/
163170
schemas: SchemaMetadata[]|null;
171+
172+
/**
173+
* The primary decorator associated with this directive.
174+
*
175+
* If this is `null`, no decorator exists, meaning it's probably from a .d.ts file.
176+
*/
177+
decorator: ts.Decorator|null;
164178
}
165179

166180
/**
@@ -191,6 +205,7 @@ export interface PipeMeta {
191205
name: string;
192206
nameExpr: ts.Expression|null;
193207
isStandalone: boolean;
208+
decorator: ts.Decorator|null;
194209
}
195210

196211
/**

packages/compiler-cli/src/ngtsc/metadata/src/dts.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export class DtsMetadataReader implements MetadataReader {
5858
rawDeclarations: null,
5959
rawImports: null,
6060
rawExports: null,
61+
decorator: null,
6162
};
6263
}
6364

@@ -119,6 +120,7 @@ export class DtsMetadataReader implements MetadataReader {
119120
imports: null,
120121
// The same goes for schemas.
121122
schemas: null,
123+
decorator: null,
122124
};
123125
}
124126

@@ -153,6 +155,7 @@ export class DtsMetadataReader implements MetadataReader {
153155
name,
154156
nameExpr: null,
155157
isStandalone,
158+
decorator: null,
156159
};
157160
}
158161
}

packages/compiler-cli/src/ngtsc/scope/test/local_spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ describe('LocalModuleScopeRegistry', () => {
5757
rawDeclarations: null,
5858
rawImports: null,
5959
rawExports: null,
60+
decorator: null,
6061
});
6162

6263
const scope = scopeRegistry.getScopeOfModule(Module.node) as LocalModuleScope;
@@ -77,6 +78,7 @@ describe('LocalModuleScopeRegistry', () => {
7778
rawDeclarations: null,
7879
rawImports: null,
7980
rawExports: null,
81+
decorator: null,
8082
});
8183
metaRegistry.registerNgModuleMetadata({
8284
kind: MetaKind.NgModule,
@@ -88,6 +90,7 @@ describe('LocalModuleScopeRegistry', () => {
8890
rawDeclarations: null,
8991
rawImports: null,
9092
rawExports: null,
93+
decorator: null,
9194
});
9295
metaRegistry.registerNgModuleMetadata({
9396
kind: MetaKind.NgModule,
@@ -99,6 +102,7 @@ describe('LocalModuleScopeRegistry', () => {
99102
rawDeclarations: null,
100103
rawImports: null,
101104
rawExports: null,
105+
decorator: null,
102106
});
103107

104108
const scopeA = scopeRegistry.getScopeOfModule(ModuleA.node) as LocalModuleScope;
@@ -119,6 +123,7 @@ describe('LocalModuleScopeRegistry', () => {
119123
rawDeclarations: null,
120124
rawImports: null,
121125
rawExports: null,
126+
decorator: null,
122127
});
123128
metaRegistry.registerNgModuleMetadata({
124129
kind: MetaKind.NgModule,
@@ -130,6 +135,7 @@ describe('LocalModuleScopeRegistry', () => {
130135
rawDeclarations: null,
131136
rawImports: null,
132137
rawExports: null,
138+
decorator: null,
133139
});
134140

135141
const scopeA = scopeRegistry.getScopeOfModule(ModuleA.node) as LocalModuleScope;
@@ -150,6 +156,7 @@ describe('LocalModuleScopeRegistry', () => {
150156
rawDeclarations: null,
151157
rawImports: null,
152158
rawExports: null,
159+
decorator: null,
153160
});
154161
metaRegistry.registerNgModuleMetadata({
155162
kind: MetaKind.NgModule,
@@ -161,6 +168,7 @@ describe('LocalModuleScopeRegistry', () => {
161168
rawDeclarations: null,
162169
rawImports: null,
163170
rawExports: null,
171+
decorator: null,
164172
});
165173
metaRegistry.registerNgModuleMetadata({
166174
kind: MetaKind.NgModule,
@@ -172,6 +180,7 @@ describe('LocalModuleScopeRegistry', () => {
172180
rawDeclarations: null,
173181
rawImports: null,
174182
rawExports: null,
183+
decorator: null,
175184
});
176185

177186
const scope = scopeRegistry.getScopeOfModule(ModuleA.node) as LocalModuleScope;
@@ -199,6 +208,7 @@ describe('LocalModuleScopeRegistry', () => {
199208
rawDeclarations: null,
200209
rawImports: null,
201210
rawExports: null,
211+
decorator: null,
202212
});
203213

204214
const scope = scopeRegistry.getScopeOfModule(Module.node) as LocalModuleScope;
@@ -218,6 +228,7 @@ describe('LocalModuleScopeRegistry', () => {
218228
rawDeclarations: null,
219229
rawImports: null,
220230
rawExports: null,
231+
decorator: null,
221232
});
222233
metaRegistry.registerNgModuleMetadata({
223234
kind: MetaKind.NgModule,
@@ -229,6 +240,7 @@ describe('LocalModuleScopeRegistry', () => {
229240
rawDeclarations: null,
230241
rawImports: null,
231242
rawExports: null,
243+
decorator: null,
232244
});
233245

234246
const scopeA = scopeRegistry.getScopeOfModule(ModuleA.node) as LocalModuleScope;
@@ -248,6 +260,7 @@ describe('LocalModuleScopeRegistry', () => {
248260
rawDeclarations: null,
249261
rawImports: null,
250262
rawExports: null,
263+
decorator: null,
251264
});
252265
metaRegistry.registerNgModuleMetadata({
253266
kind: MetaKind.NgModule,
@@ -259,6 +272,7 @@ describe('LocalModuleScopeRegistry', () => {
259272
rawDeclarations: null,
260273
rawImports: null,
261274
rawExports: null,
275+
decorator: null,
262276
});
263277

264278
expect(scopeRegistry.getScopeOfModule(ModuleA.node)!.compilation.isPoisoned).toBeTrue();
@@ -297,6 +311,7 @@ function fakeDirective(ref: Reference<ClassDeclaration>): DirectiveMeta {
297311
isStandalone: false,
298312
imports: null,
299313
schemas: null,
314+
decorator: null,
300315
};
301316
}
302317

@@ -308,6 +323,7 @@ function fakePipe(ref: Reference<ClassDeclaration>): PipeMeta {
308323
name,
309324
nameExpr: null,
310325
isStandalone: false,
326+
decorator: null,
311327
};
312328
}
313329

0 commit comments

Comments
 (0)