fix(compiler): do not consider a reference with members as a reference (#19454)

Fixes: #18170
This commit is contained in:
Chuck Jazdzewski 2017-09-28 10:52:52 -07:00 committed by Victor Berchet
parent 2b84b86fc0
commit b3db3f80ba
2 changed files with 42 additions and 3 deletions

View File

@ -417,7 +417,9 @@ export class StaticReflector implements CompileReflector {
for (const item of (<any>expression)) { for (const item of (<any>expression)) {
// Check for a spread expression // Check for a spread expression
if (item && item.__symbolic === 'spread') { 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)) { if (Array.isArray(spreadArray)) {
for (const spreadItem of spreadArray) { for (const spreadItem of spreadArray) {
result.push(spreadItem); result.push(spreadItem);
@ -434,9 +436,10 @@ export class StaticReflector implements CompileReflector {
return result; return result;
} }
if (expression instanceof StaticSymbol) { 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) || if (expression === self.injectionToken || self.conversionMap.has(expression) ||
references > 0) { (references > 0 && !expression.members.length)) {
return expression; return expression;
} else { } else {
const staticSymbol = expression; const staticSymbol = expression;

View File

@ -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: '<div></div>',
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} = { const DEFAULT_TEST_DATA: {[key: string]: any} = {