Skip to content

Commit

Permalink
fix(compiler-cli): Support resolve animation name from the DTS (#45169)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ivanwonder authored and thePunderWoman committed Feb 24, 2022
1 parent 6c61d20 commit 6c906a5
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 11 deletions.
5 changes: 3 additions & 2 deletions packages/compiler-cli/src/ngtsc/annotations/src/component.ts
Expand Up @@ -33,7 +33,7 @@ import {DirectiveSymbol, extractDirectiveMetadata, parseFieldArrayValue} from '.
import {compileDeclareFactory, compileNgFactoryDefField} from './factory';
import {extractClassMetadata} from './metadata';
import {NgModuleSymbol} from './ng_module';
import {compileResults, findAngularDecorator, isAngularCoreReference, isExpressionForwardReference, readBaseClass, resolveProvidersRequiringFactory, toFactoryMetadata, unwrapExpression, wrapFunctionExpressionsInParens} from './util';
import {animationTriggerResolver, compileResults, findAngularDecorator, isAngularCoreReference, isExpressionForwardReference, readBaseClass, resolveProvidersRequiringFactory, toFactoryMetadata, unwrapExpression, wrapFunctionExpressionsInParens} from './util';

const EMPTY_MAP = new Map<string, Expression>();
const EMPTY_ARRAY: any[] = [];
Expand Down Expand Up @@ -352,7 +352,8 @@ export class ComponentDecoratorHandler implements
let animationTriggerNames: AnimationTriggerNames|null = null;
if (component.has('animations')) {
animations = new WrappedNodeExpr(component.get('animations')!);
const animationsValue = this.evaluator.evaluate(component.get('animations')!);
const animationsValue =
this.evaluator.evaluate(component.get('animations')!, animationTriggerResolver);
animationTriggerNames = {includesDynamicAnimations: false, staticTriggerNames: []};
collectAnimationNames(animationsValue, animationTriggerNames);
}
Expand Down
22 changes: 22 additions & 0 deletions packages/compiler-cli/src/ngtsc/annotations/src/util.ts
Expand Up @@ -596,3 +596,25 @@ export function toFactoryMetadata(
target
};
}

export function isAngularAnimationsReference(reference: Reference, symbolName: string): boolean {
return reference.ownedByModuleGuess === '@angular/animations' &&
reference.debugName === symbolName;
}

export const animationTriggerResolver: ForeignFunctionResolver = (ref, args) => {
const animationTriggerMethodName = 'trigger';
if (!isAngularAnimationsReference(ref, animationTriggerMethodName)) {
return null;
}
const triggerNameExpression = args[0];
if (!triggerNameExpression) {
return null;
}
const factory = ts.factory;
return factory.createObjectLiteralExpression(
[
factory.createPropertyAssignment(factory.createIdentifier('name'), triggerNameExpression),
],
true);
};
27 changes: 18 additions & 9 deletions packages/compiler-cli/src/ngtsc/annotations/test/component_spec.ts
Expand Up @@ -407,13 +407,16 @@ runInEachFileSystem(() => {
name: _('/node_modules/@angular/core/index.d.ts'),
contents: 'export const Component: any;',
},
{
name: _('/node_modules/@angular/animations/index.d.ts'),
contents: 'export declare function trigger(name: any): any',
},
{
name: _('/entry.ts'),
contents: `
import {Component} from '@angular/core';
function trigger(name) {
return {name};
}
import {trigger} from '@angular/animations';
@Component({
template: '',
animations: [
Expand Down Expand Up @@ -446,13 +449,16 @@ runInEachFileSystem(() => {
name: _('/node_modules/@angular/core/index.d.ts'),
contents: 'export const Component: any;',
},
{
name: _('/node_modules/@angular/animations/index.d.ts'),
contents: 'export declare function trigger(name: any): any',
},
{
name: _('/entry.ts'),
contents: `
import {Component} from '@angular/core';
function trigger(name) {
return {name};
}
import {trigger} from '@angular/animations';
function buildComplexAnimations() {
const name = 'complex';
return [trigger(name)];
Expand Down Expand Up @@ -487,13 +493,16 @@ runInEachFileSystem(() => {
name: _('/node_modules/@angular/core/index.d.ts'),
contents: 'export const Component: any;',
},
{
name: _('/node_modules/@angular/animations/index.d.ts'),
contents: 'export declare function trigger(name: any): any',
},
{
name: _('/entry.ts'),
contents: `
import {Component} from '@angular/core';
function trigger(name) {
return {name};
}
import {trigger} from '@angular/animations';
function buildComplexAnimations() {
const name = 'complex';
return [trigger(name)];
Expand Down

0 comments on commit 6c906a5

Please sign in to comment.