fix(compiler): do not consider a reference with members as a reference (#19454)
Fixes: #18170
This commit is contained in:
parent
2b84b86fc0
commit
b3db3f80ba
|
@ -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;
|
||||||
|
|
|
@ -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} = {
|
||||||
|
|
Loading…
Reference in New Issue