diff --git a/packages/compiler/src/aot/static_reflector.ts b/packages/compiler/src/aot/static_reflector.ts index 813dbbadca..3e9ce1de61 100644 --- a/packages/compiler/src/aot/static_reflector.ts +++ b/packages/compiler/src/aot/static_reflector.ts @@ -417,7 +417,9 @@ export class StaticReflector implements CompileReflector { for (const item of (expression)) { // Check for a spread expression if (item && item.__symbolic === 'spread') { - const spreadArray = simplify(item.expression); + // We call with references as 0 because we require the actual value and cannot + // tolerate a reference here. + const spreadArray = simplifyInContext(context, item.expression, depth, 0); if (Array.isArray(spreadArray)) { for (const spreadItem of spreadArray) { result.push(spreadItem); @@ -434,9 +436,10 @@ export class StaticReflector implements CompileReflector { return result; } if (expression instanceof StaticSymbol) { - // Stop simplification at builtin symbols or if we are in a reference context + // Stop simplification at builtin symbols or if we are in a reference context and + // the symbol doesn't have members. if (expression === self.injectionToken || self.conversionMap.has(expression) || - references > 0) { + (references > 0 && !expression.members.length)) { return expression; } else { const staticSymbol = expression; diff --git a/packages/compiler/test/aot/static_reflector_spec.ts b/packages/compiler/test/aot/static_reflector_spec.ts index 5fbbc5cf33..595d0f0031 100644 --- a/packages/compiler/test/aot/static_reflector_spec.ts +++ b/packages/compiler/test/aot/static_reflector_spec.ts @@ -878,6 +878,42 @@ describe('StaticReflector', () => { }); }); + // Regression #18170 + it('should continue to aggresively evaluate enum member accessors', () => { + const data = Object.create(DEFAULT_TEST_DATA); + const file = '/tmp/src/my_component.ts'; + data[file] = ` + import {Component} from '@angular/core'; + import {intermediate} from './index'; + + @Component({ + template: '
', + providers: [{provide: 'foo', useValue: [...intermediate]}] + }) + export class MyComponent { } + `; + data['/tmp/src/intermediate.ts'] = ` + import {MyEnum} from './indirect'; + export const intermediate = [{ + data: { + c: [MyEnum.Value] + } + }];`; + data['/tmp/src/index.ts'] = `export * from './intermediate';`; + data['/tmp/src/indirect.ts'] = `export * from './consts';`; + data['/tmp/src/consts.ts'] = ` + export enum MyEnum { + Value = 3 + } + `; + init(data); + + expect(reflector.annotations(reflector.getStaticSymbol(file, 'MyComponent'))[0] + .providers[0] + .useValue) + .toEqual([{data: {c: [3]}}]); + }); + }); const DEFAULT_TEST_DATA: {[key: string]: any} = {