fix(ngcc): fix undecorated child migration when `exportAs` is present (#34014)

The undecorated child migration creates a synthetic decorator, which
contained `"exportAs": ["exportName"]` as obtained from the metadata of
the parent class. This is a problem, as `exportAs` needs to specified
as a comma-separated string instead of an array. This commit fixes the
bug by transforming the array of export names back to a comma-separated
string.

PR Close #34014
This commit is contained in:
JoostK 2019-11-23 19:33:18 +01:00 committed by Andrew Kushnir
parent 95429d55ff
commit ead169a402
2 changed files with 8 additions and 11 deletions

View File

@ -51,7 +51,7 @@ export function createDirectiveDecorator(
metaArgs.push(property('selector', metadata.selector));
}
if (metadata.exportAs !== null) {
metaArgs.push(property('exportAs', metadata.exportAs));
metaArgs.push(property('exportAs', metadata.exportAs.join(', ')));
}
args.push(reifySourceFile(ts.createObjectLiteral(metaArgs)));
}
@ -77,7 +77,7 @@ export function createComponentDecorator(
metaArgs.push(property('selector', metadata.selector));
}
if (metadata.exportAs !== null) {
metaArgs.push(property('exportAs', metadata.exportAs));
metaArgs.push(property('exportAs', metadata.exportAs.join(', ')));
}
return {
name: 'Component',
@ -105,13 +105,8 @@ export function createInjectableDecorator(clazz: ClassDeclaration): Decorator {
};
}
function property(name: string, value: string | string[]): ts.PropertyAssignment {
if (typeof value === 'string') {
return ts.createPropertyAssignment(name, ts.createStringLiteral(value));
} else {
return ts.createPropertyAssignment(
name, ts.createArrayLiteral(value.map(v => ts.createStringLiteral(v))));
}
function property(name: string, value: string): ts.PropertyAssignment {
return ts.createPropertyAssignment(name, ts.createStringLiteral(value));
}
const EMPTY_SF = ts.createSourceFile('(empty)', '', ts.ScriptTarget.Latest);

View File

@ -972,6 +972,7 @@ runInEachFileSystem(() => {
@Directive({
selector: '[base]',
exportAs: 'base1, base2',
})
export class BaseDir {}
@ -994,13 +995,14 @@ runInEachFileSystem(() => {
const jsContents = fs.readFile(_(`/node_modules/test-package/index.js`));
expect(jsContents)
.toContain(
'DerivedDir.ɵdir = ɵngcc0.ɵɵdefineDirective({ type: DerivedDir, selectors: [["", "base", ""]], ' +
'DerivedDir.ɵdir = ɵngcc0.ɵɵdefineDirective({ type: DerivedDir, ' +
'selectors: [["", "base", ""]], exportAs: ["base1", "base2"], ' +
'features: [ɵngcc0.ɵɵInheritDefinitionFeature, ɵngcc0.ɵɵCopyDefinitionFeature] });');
const dtsContents = fs.readFile(_(`/node_modules/test-package/index.d.ts`));
expect(dtsContents)
.toContain(
'static ɵdir: ɵngcc0.ɵɵDirectiveDefWithMeta<DerivedDir, "[base]", never, {}, {}, never>;');
'static ɵdir: ɵngcc0.ɵɵDirectiveDefWithMeta<DerivedDir, "[base]", ["base1", "base2"], {}, {}, never>;');
});
it('should generate a component definition with CopyDefinitionFeature for an undecorated child component',