fix(compiler): do not consider arguments when determining recursion
The static reflectory check for macro function recursion was too agressive and disallowed calling a function with argument that also calls the same function. For example, it disallowed nested animation groups. Fixes: #17467
This commit is contained in:
parent
cc2a4c41f9
commit
e64b54b67b
|
@ -376,7 +376,6 @@ export class StaticReflector implements CompileReflector {
|
||||||
if (calling.get(functionSymbol)) {
|
if (calling.get(functionSymbol)) {
|
||||||
throw new Error('Recursion not supported');
|
throw new Error('Recursion not supported');
|
||||||
}
|
}
|
||||||
calling.set(functionSymbol, true);
|
|
||||||
try {
|
try {
|
||||||
const value = targetFunction['value'];
|
const value = targetFunction['value'];
|
||||||
if (value && (depth != 0 || value.__symbolic != 'error')) {
|
if (value && (depth != 0 || value.__symbolic != 'error')) {
|
||||||
|
@ -387,6 +386,7 @@ export class StaticReflector implements CompileReflector {
|
||||||
if (defaults && defaults.length > args.length) {
|
if (defaults && defaults.length > args.length) {
|
||||||
args.push(...defaults.slice(args.length).map((value: any) => simplify(value)));
|
args.push(...defaults.slice(args.length).map((value: any) => simplify(value)));
|
||||||
}
|
}
|
||||||
|
calling.set(functionSymbol, true);
|
||||||
const functionScope = BindingScope.build();
|
const functionScope = BindingScope.build();
|
||||||
for (let i = 0; i < parameters.length; i++) {
|
for (let i = 0; i < parameters.length; i++) {
|
||||||
functionScope.define(parameters[i], args[i]);
|
functionScope.define(parameters[i], args[i]);
|
||||||
|
|
|
@ -462,6 +462,20 @@ describe('StaticReflector', () => {
|
||||||
expect(annotations[0].providers[0].useValue.members[0]).toEqual('staticMethod');
|
expect(annotations[0].providers[0].useValue.members[0]).toEqual('staticMethod');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to get metadata for a class calling a macro function', () => {
|
||||||
|
const annotations = reflector.annotations(
|
||||||
|
reflector.getStaticSymbol('/tmp/src/call-macro-function.ts', 'MyComponent'));
|
||||||
|
expect(annotations.length).toBe(1);
|
||||||
|
expect(annotations[0].providers.useValue).toBe(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to get metadata for a class calling a nested macro function', () => {
|
||||||
|
const annotations = reflector.annotations(
|
||||||
|
reflector.getStaticSymbol('/tmp/src/call-macro-function.ts', 'MyComponentNested'));
|
||||||
|
expect(annotations.length).toBe(1);
|
||||||
|
expect(annotations[0].providers.useValue.useValue).toBe(100);
|
||||||
|
});
|
||||||
|
|
||||||
// #13605
|
// #13605
|
||||||
it('should not throw on unknown decorators', () => {
|
it('should not throw on unknown decorators', () => {
|
||||||
const data = Object.create(DEFAULT_TEST_DATA);
|
const data = Object.create(DEFAULT_TEST_DATA);
|
||||||
|
@ -1392,6 +1406,25 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||||
static VALUE = 'Some string';
|
static VALUE = 'Some string';
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
'/tmp/src/macro-function.ts': `
|
||||||
|
export function v(value: any) {
|
||||||
|
return { provide: 'a', useValue: value };
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
'/tmp/src/call-macro-function.ts': `
|
||||||
|
import {Component} from '@angular/core';
|
||||||
|
import {v} from './macro-function';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
providers: v(100)
|
||||||
|
})
|
||||||
|
export class MyComponent { }
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
providers: v(v(100))
|
||||||
|
})
|
||||||
|
export class MyComponentNested { }
|
||||||
|
`,
|
||||||
'/tmp/src/static-field-reference.ts': `
|
'/tmp/src/static-field-reference.ts': `
|
||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import {MyModule} from './static-field';
|
import {MyModule} from './static-field';
|
||||||
|
|
Loading…
Reference in New Issue