From 78214e72ea454db328d9833b33540e879f1c0eb2 Mon Sep 17 00:00:00 2001 From: George Kalpakas Date: Wed, 16 Oct 2019 19:15:01 +0300 Subject: [PATCH] fix(ngcc): avoid warning when reflecting on index signature member (#33198) Previously, when `ngcc` was reflecting on class members it did not account for the fact that a member could be of the kind `IndexSignature`. This can happen, for example, on abstract classes (as is the case for [JsonCallbackContext][1]). Trying to reflect on such members (and failing to recognize their kind), resulted in warnings, such as: ``` Warning: Unknown member type: "[key: string]: (data: any) => void; ``` While these warnings are harmless, they can be confusing and worrisome for users. This commit avoids such warnings by detecting class members of the `IndexSignature` kind and ignoring them. [1]: https://github.com/angular/angular/blob/4659cc26e/packages/common/http/src/jsonp.ts#L39 PR Close #33198 --- .../ngcc/src/host/esm2015_host.ts | 5 +++- .../ngcc/test/host/esm2015_host_spec.ts | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts index ad72c24820..5a14f1cd5f 100644 --- a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts +++ b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts @@ -1778,7 +1778,10 @@ function isNamedDeclaration(node: ts.Declaration): node is ts.NamedDeclaration& function isClassMemberType(node: ts.Declaration): node is ts.ClassElement| ts.PropertyAccessExpression|ts.BinaryExpression { - return ts.isClassElement(node) || isPropertyAccess(node) || ts.isBinaryExpression(node); + return (ts.isClassElement(node) || isPropertyAccess(node) || ts.isBinaryExpression(node)) && + // Additionally, ensure `node` is not an index signature, for example on an abstract class: + // `abstract class Foo { [key: string]: any; }` + !ts.isIndexSignatureDeclaration(node); } /** diff --git a/packages/compiler-cli/ngcc/test/host/esm2015_host_spec.ts b/packages/compiler-cli/ngcc/test/host/esm2015_host_spec.ts index b43c32d839..d85f29e9be 100644 --- a/packages/compiler-cli/ngcc/test/host/esm2015_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/esm2015_host_spec.ts @@ -46,6 +46,7 @@ runInEachFileSystem(() => { let TYPINGS_DTS_FILES: TestFile[]; let MODULE_WITH_PROVIDERS_PROGRAM: TestFile[]; let NAMESPACED_IMPORT_FILE: TestFile; + let INDEX_SIGNATURE_PROP_FILE: TestFile; beforeEach(() => { _ = absoluteFrom; @@ -690,6 +691,15 @@ runInEachFileSystem(() => { ]; ` }; + + INDEX_SIGNATURE_PROP_FILE = { + name: _('/index_signature_prop.d.ts'), + contents: ` + abstract class IndexSignatureClass { + [key: string]: any; + } + `, + }; }); describe('getDecoratorsOfDeclaration()', () => { @@ -941,6 +951,20 @@ runInEachFileSystem(() => { expect(staticProperty.value !.getText()).toEqual(`'static'`); }); + it('should ignore index signature properties', () => { + loadTestFiles([INDEX_SIGNATURE_PROP_FILE]); + const logger = new MockLogger(); + const {program} = makeTestBundleProgram(INDEX_SIGNATURE_PROP_FILE.name); + const host = new Esm2015ReflectionHost(logger, false, program.getTypeChecker()); + const classNode = getDeclaration( + program, INDEX_SIGNATURE_PROP_FILE.name, 'IndexSignatureClass', + isNamedClassDeclaration); + const members = host.getMembersOfClass(classNode); + + expect(members).toEqual([]); + expect(logger.logs.warn).toEqual([]); + }); + it('should throw if the symbol is not a class', () => { loadTestFiles([FOO_FUNCTION_FILE]); const {program} = makeTestBundleProgram(FOO_FUNCTION_FILE.name);