Skip to content

Commit 6c906a5

Browse files
ivanwonderthePunderWoman
authored andcommitted
fix(compiler-cli): Support resolve animation name from the DTS (#45169)
Before this, the compiler resolves the value in the DTS as dynamic. If the `trigger` is imported from `@angular/animations`, this PR will use FFR to simulate the actual implementation in JS and extracts the animation name. PR Close #45169
1 parent 6c61d20 commit 6c906a5

3 files changed

Lines changed: 43 additions & 11 deletions

File tree

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import {DirectiveSymbol, extractDirectiveMetadata, parseFieldArrayValue} from '.
3333
import {compileDeclareFactory, compileNgFactoryDefField} from './factory';
3434
import {extractClassMetadata} from './metadata';
3535
import {NgModuleSymbol} from './ng_module';
36-
import {compileResults, findAngularDecorator, isAngularCoreReference, isExpressionForwardReference, readBaseClass, resolveProvidersRequiringFactory, toFactoryMetadata, unwrapExpression, wrapFunctionExpressionsInParens} from './util';
36+
import {animationTriggerResolver, compileResults, findAngularDecorator, isAngularCoreReference, isExpressionForwardReference, readBaseClass, resolveProvidersRequiringFactory, toFactoryMetadata, unwrapExpression, wrapFunctionExpressionsInParens} from './util';
3737

3838
const EMPTY_MAP = new Map<string, Expression>();
3939
const EMPTY_ARRAY: any[] = [];
@@ -352,7 +352,8 @@ export class ComponentDecoratorHandler implements
352352
let animationTriggerNames: AnimationTriggerNames|null = null;
353353
if (component.has('animations')) {
354354
animations = new WrappedNodeExpr(component.get('animations')!);
355-
const animationsValue = this.evaluator.evaluate(component.get('animations')!);
355+
const animationsValue =
356+
this.evaluator.evaluate(component.get('animations')!, animationTriggerResolver);
356357
animationTriggerNames = {includesDynamicAnimations: false, staticTriggerNames: []};
357358
collectAnimationNames(animationsValue, animationTriggerNames);
358359
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,3 +596,25 @@ export function toFactoryMetadata(
596596
target
597597
};
598598
}
599+
600+
export function isAngularAnimationsReference(reference: Reference, symbolName: string): boolean {
601+
return reference.ownedByModuleGuess === '@angular/animations' &&
602+
reference.debugName === symbolName;
603+
}
604+
605+
export const animationTriggerResolver: ForeignFunctionResolver = (ref, args) => {
606+
const animationTriggerMethodName = 'trigger';
607+
if (!isAngularAnimationsReference(ref, animationTriggerMethodName)) {
608+
return null;
609+
}
610+
const triggerNameExpression = args[0];
611+
if (!triggerNameExpression) {
612+
return null;
613+
}
614+
const factory = ts.factory;
615+
return factory.createObjectLiteralExpression(
616+
[
617+
factory.createPropertyAssignment(factory.createIdentifier('name'), triggerNameExpression),
618+
],
619+
true);
620+
};

packages/compiler-cli/src/ngtsc/annotations/test/component_spec.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -407,13 +407,16 @@ runInEachFileSystem(() => {
407407
name: _('/node_modules/@angular/core/index.d.ts'),
408408
contents: 'export const Component: any;',
409409
},
410+
{
411+
name: _('/node_modules/@angular/animations/index.d.ts'),
412+
contents: 'export declare function trigger(name: any): any',
413+
},
410414
{
411415
name: _('/entry.ts'),
412416
contents: `
413417
import {Component} from '@angular/core';
414-
function trigger(name) {
415-
return {name};
416-
}
418+
import {trigger} from '@angular/animations';
419+
417420
@Component({
418421
template: '',
419422
animations: [
@@ -446,13 +449,16 @@ runInEachFileSystem(() => {
446449
name: _('/node_modules/@angular/core/index.d.ts'),
447450
contents: 'export const Component: any;',
448451
},
452+
{
453+
name: _('/node_modules/@angular/animations/index.d.ts'),
454+
contents: 'export declare function trigger(name: any): any',
455+
},
449456
{
450457
name: _('/entry.ts'),
451458
contents: `
452459
import {Component} from '@angular/core';
453-
function trigger(name) {
454-
return {name};
455-
}
460+
import {trigger} from '@angular/animations';
461+
456462
function buildComplexAnimations() {
457463
const name = 'complex';
458464
return [trigger(name)];
@@ -487,13 +493,16 @@ runInEachFileSystem(() => {
487493
name: _('/node_modules/@angular/core/index.d.ts'),
488494
contents: 'export const Component: any;',
489495
},
496+
{
497+
name: _('/node_modules/@angular/animations/index.d.ts'),
498+
contents: 'export declare function trigger(name: any): any',
499+
},
490500
{
491501
name: _('/entry.ts'),
492502
contents: `
493503
import {Component} from '@angular/core';
494-
function trigger(name) {
495-
return {name};
496-
}
504+
import {trigger} from '@angular/animations';
505+
497506
function buildComplexAnimations() {
498507
const name = 'complex';
499508
return [trigger(name)];

0 commit comments

Comments
 (0)