fix(tsickle): support ctorParams in function closure (#12876)
See https://github.com/angular/tsickle/issues/261 for context.
This commit is contained in:

committed by
Victor Berchet

parent
46d150266b
commit
75277cd94b
@ -132,7 +132,6 @@ export class StaticReflector implements ReflectorReader {
|
|||||||
const ctor = (<any[]>ctorData).find(a => a['__symbolic'] == 'constructor');
|
const ctor = (<any[]>ctorData).find(a => a['__symbolic'] == 'constructor');
|
||||||
const parameterTypes = <any[]>this.simplify(type, ctor['parameters'] || []);
|
const parameterTypes = <any[]>this.simplify(type, ctor['parameters'] || []);
|
||||||
const parameterDecorators = <any[]>this.simplify(type, ctor['parameterDecorators'] || []);
|
const parameterDecorators = <any[]>this.simplify(type, ctor['parameterDecorators'] || []);
|
||||||
|
|
||||||
parameters = [];
|
parameters = [];
|
||||||
parameterTypes.forEach((paramType, index) => {
|
parameterTypes.forEach((paramType, index) => {
|
||||||
const nestedResult: any[] = [];
|
const nestedResult: any[] = [];
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {StaticReflector, StaticReflectorHost, StaticSymbol} from '@angular/compiler-cli/src/static_reflector';
|
import {StaticReflector, StaticReflectorHost, StaticSymbol} from '@angular/compiler-cli/src/static_reflector';
|
||||||
import {HostListener, animate, group, keyframes, sequence, state, style, transition, trigger} from '@angular/core';
|
import {HostListener, Inject, animate, group, keyframes, sequence, state, style, transition, trigger} from '@angular/core';
|
||||||
import {MetadataCollector} from '@angular/tsc-wrapped';
|
import {MetadataCollector} from '@angular/tsc-wrapped';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
@ -410,6 +410,13 @@ describe('StaticReflector', () => {
|
|||||||
expect(props).toEqual({foo: []});
|
expect(props).toEqual({foo: []});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should read ctor parameters with forwardRef', () => {
|
||||||
|
const src = '/tmp/src/forward-ref.ts';
|
||||||
|
const dep = host.getStaticSymbol(src, 'Dep');
|
||||||
|
const props = reflector.parameters(host.getStaticSymbol(src, 'Forward'));
|
||||||
|
expect(props).toEqual([[dep, new Inject(dep)]]);
|
||||||
|
});
|
||||||
|
|
||||||
it('should report an error for invalid function calls', () => {
|
it('should report an error for invalid function calls', () => {
|
||||||
expect(
|
expect(
|
||||||
() =>
|
() =>
|
||||||
@ -1068,6 +1075,18 @@ class MockReflectorHost implements StaticReflectorHost {
|
|||||||
providers: [ { provider: 'a', useValue: (() => 1)() }]
|
providers: [ { provider: 'a', useValue: (() => 1)() }]
|
||||||
})
|
})
|
||||||
export class InvalidMetadata {}
|
export class InvalidMetadata {}
|
||||||
|
`,
|
||||||
|
'/tmp/src/forward-ref.ts': `
|
||||||
|
import {forwardRef} from 'angular2/core';
|
||||||
|
import {Component} from 'angular2/src/core/metadata';
|
||||||
|
import {Inject} from 'angular2/src/core/di/metadata';
|
||||||
|
@Component({})
|
||||||
|
export class Forward {
|
||||||
|
constructor(@Inject(forwardRef(() => Dep)) d: Dep) {}
|
||||||
|
}
|
||||||
|
export class Dep {
|
||||||
|
@Input f: Forward;
|
||||||
|
}
|
||||||
`
|
`
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,8 +56,12 @@ export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// API of tsickle for lowering decorators to properties on the class.
|
// API of tsickle for lowering decorators to properties on the class.
|
||||||
if ((<any>type).ctorParameters) {
|
const tsickleCtorParams = (<any>type).ctorParameters;
|
||||||
const ctorParameters = (<any>type).ctorParameters;
|
if (tsickleCtorParams) {
|
||||||
|
// Newer tsickle uses a function closure
|
||||||
|
// Retain the non-function case for compatibility with older tsickle
|
||||||
|
const ctorParameters =
|
||||||
|
typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;
|
||||||
const paramTypes = ctorParameters.map((ctorParam: any) => ctorParam && ctorParam.type);
|
const paramTypes = ctorParameters.map((ctorParam: any) => ctorParam && ctorParam.type);
|
||||||
const paramAnnotations = ctorParameters.map(
|
const paramAnnotations = ctorParameters.map(
|
||||||
(ctorParam: any) =>
|
(ctorParam: any) =>
|
||||||
|
@ -89,6 +89,25 @@ export function main() {
|
|||||||
const p = reflector.parameters(ClassWithoutDecorators);
|
const p = reflector.parameters(ClassWithoutDecorators);
|
||||||
expect(p.length).toEqual(2);
|
expect(p.length).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// See https://github.com/angular/tsickle/issues/261
|
||||||
|
it('should read forwardRef down-leveled type', () => {
|
||||||
|
class Dep {}
|
||||||
|
class ForwardLegacy {
|
||||||
|
constructor(d: Dep) {}
|
||||||
|
// Older tsickle had a bug: wrote a forward reference
|
||||||
|
static ctorParameters = [{type: Dep}];
|
||||||
|
}
|
||||||
|
expect(reflector.parameters(ForwardLegacy)).toEqual([[Dep]]);
|
||||||
|
class Forward {
|
||||||
|
constructor(d: Dep) {}
|
||||||
|
// Newer tsickle generates a functionClosure
|
||||||
|
static ctorParameters = () => [{type: ForwardDep}];
|
||||||
|
}
|
||||||
|
class ForwardDep {}
|
||||||
|
expect(reflector.parameters(Forward)).toEqual([[ForwardDep]]);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('propMetadata', () => {
|
describe('propMetadata', () => {
|
||||||
|
Reference in New Issue
Block a user