fix(ivy): resolve enum values in host bindings (#28523)
Some applications use enum values in their host bindings: @Component({ host: { '[prop]': EnumType.Key, }, ... }) This commit changes the resolution of host properties to follow the enum declaration and extract the correct value for the binding. PR Close #28523
This commit is contained in:

committed by
Misko Hevery

parent
09af7ea4f5
commit
3477610f6d
@ -11,7 +11,7 @@ import * as ts from 'typescript';
|
|||||||
|
|
||||||
import {ErrorCode, FatalDiagnosticError} from '../../diagnostics';
|
import {ErrorCode, FatalDiagnosticError} from '../../diagnostics';
|
||||||
import {Reference, ResolvedReference} from '../../imports';
|
import {Reference, ResolvedReference} from '../../imports';
|
||||||
import {PartialEvaluator} from '../../partial_evaluator';
|
import {EnumValue, PartialEvaluator} from '../../partial_evaluator';
|
||||||
import {ClassMember, ClassMemberKind, Decorator, ReflectionHost, filterToMembersWithDecorator, reflectObjectLiteral} from '../../reflection';
|
import {ClassMember, ClassMemberKind, Decorator, ReflectionHost, filterToMembersWithDecorator, reflectObjectLiteral} from '../../reflection';
|
||||||
import {AnalysisOutput, CompileResult, DecoratorHandler} from '../../transform';
|
import {AnalysisOutput, CompileResult, DecoratorHandler} from '../../transform';
|
||||||
|
|
||||||
@ -434,6 +434,11 @@ function extractHostBindings(
|
|||||||
ErrorCode.DECORATOR_ARG_NOT_LITERAL, expr, `Decorator host metadata must be an object`);
|
ErrorCode.DECORATOR_ARG_NOT_LITERAL, expr, `Decorator host metadata must be an object`);
|
||||||
}
|
}
|
||||||
hostMetaMap.forEach((value, key) => {
|
hostMetaMap.forEach((value, key) => {
|
||||||
|
// Resolve Enum references to their declared value.
|
||||||
|
if (value instanceof EnumValue) {
|
||||||
|
value = value.resolved;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof value !== 'string' || typeof key !== 'string') {
|
if (typeof value !== 'string' || typeof key !== 'string') {
|
||||||
throw new Error(`Decorator host metadata must be a string -> string object, got ${value}`);
|
throw new Error(`Decorator host metadata must be a string -> string object, got ${value}`);
|
||||||
}
|
}
|
||||||
|
@ -1004,6 +1004,31 @@ describe('ngtsc behavioral tests', () => {
|
|||||||
expect(trim(jsContents)).toContain(trim(hostBindingsFn));
|
expect(trim(jsContents)).toContain(trim(hostBindingsFn));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should accept enum values as host bindings', () => {
|
||||||
|
env.tsconfig();
|
||||||
|
env.write(`test.ts`, `
|
||||||
|
import {Component, HostBinding, HostListener, TemplateRef} from '@angular/core';
|
||||||
|
|
||||||
|
enum HostBindings {
|
||||||
|
Hello = 'foo'
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'test',
|
||||||
|
template: 'Test',
|
||||||
|
host: {
|
||||||
|
'[attr.hello]': HostBindings.Hello,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
class FooCmp {
|
||||||
|
foo = 'test';
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
|
||||||
|
env.driveMain();
|
||||||
|
expect(env.getContents('test.js')).toContain('"hello", i0.ɵbind(ctx.foo)');
|
||||||
|
});
|
||||||
|
|
||||||
it('should generate host listeners for directives within hostBindings section', () => {
|
it('should generate host listeners for directives within hostBindings section', () => {
|
||||||
env.tsconfig();
|
env.tsconfig();
|
||||||
env.write(`test.ts`, `
|
env.write(`test.ts`, `
|
||||||
|
Reference in New Issue
Block a user