fix(ngcc): ensure that "inline exports" can be interpreted correctly (#39267)
Previously, inline exports of the form `exports.foo = <implementation>;` were being interpreted (by the ngtsc `PartialInterpeter`) as `Reference` objects. This is not what is desired since it prevents the value of the export from being unpacked, such as when analyzing `NgModule` declarations: ``` exports.directives = [Directive1, Directive2]; @NgImport({declarations: [exports.directives]}) class AppModule {} ``` In this example the interpreter would think that `exports.directives` was a reference rather than an array that needs to be unpacked. This bug was picked up by the ngcc-validation repository. See https://github.com/angular/ngcc-validation/pull/1990 and https://circleci.com/gh/angular/ngcc-validation/17130 PR Close #39267
This commit is contained in:

committed by
atscott

parent
ac0016cd82
commit
822b838fbc
@ -2422,9 +2422,10 @@ exports.MissingClass2 = MissingClass2;
|
||||
const file = getSourceFileOrError(bundle.program, _('/inline_export.js'));
|
||||
const exportDeclarations = host.getExportsOfModule(file);
|
||||
expect(exportDeclarations).not.toBeNull();
|
||||
const decl = exportDeclarations!.get('directives')!;
|
||||
const decl = exportDeclarations!.get('directives') as InlineDeclaration;
|
||||
expect(decl).toBeDefined();
|
||||
expect(decl.node).toBeDefined();
|
||||
expect(decl.node.getText()).toEqual('exports.directives');
|
||||
expect(decl.implementation!.getText()).toEqual('[foo]');
|
||||
expect(decl.kind).toEqual(DeclarationKind.Inline);
|
||||
});
|
||||
|
||||
|
@ -2750,13 +2750,13 @@ runInEachFileSystem(() => {
|
||||
const exportDeclarations = host.getExportsOfModule(file);
|
||||
expect(exportDeclarations).not.toBe(null);
|
||||
expect(exportDeclarations!.size).toEqual(1);
|
||||
const classDecl = exportDeclarations!.get('DecoratedClass')!;
|
||||
const classDecl = exportDeclarations!.get('DecoratedClass') as InlineDeclaration;
|
||||
expect(classDecl).toBeDefined();
|
||||
expect(classDecl.kind).toEqual(DeclarationKind.Inline);
|
||||
expect(classDecl.known).toBe(null);
|
||||
expect(classDecl.viaModule).toBe(null);
|
||||
expect(classDecl.node.getText()).toEqual('exports.DecoratedClass');
|
||||
expect(classDecl.node.parent.parent.getText()).toContain('function DecoratedClass() {');
|
||||
expect(classDecl.implementation!.getText()).toContain('function DecoratedClass() {');
|
||||
});
|
||||
|
||||
it('should handle wildcard re-exports of other modules (with emitted helpers)', () => {
|
||||
@ -2824,9 +2824,10 @@ runInEachFileSystem(() => {
|
||||
const file = getSourceFileOrError(bundle.program, INLINE_EXPORT_FILE.name);
|
||||
const exportDeclarations = host.getExportsOfModule(file);
|
||||
expect(exportDeclarations).not.toBe(null);
|
||||
const decl = exportDeclarations!.get('directives')!;
|
||||
const decl = exportDeclarations!.get('directives') as InlineDeclaration;
|
||||
expect(decl).toBeDefined();
|
||||
expect(decl.node).toBeDefined();
|
||||
expect(decl.node.getText()).toEqual('exports.directives');
|
||||
expect(decl.implementation!.getText()).toEqual('[foo]');
|
||||
expect(decl.kind).toEqual(DeclarationKind.Inline);
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user