From f8d294ba02c41870cad8e214d506bc9f8f7932ef Mon Sep 17 00:00:00 2001 From: George Kalpakas Date: Wed, 16 Oct 2019 19:15:01 +0300 Subject: [PATCH 1/2] fix(ngcc): avoid warning when reflecting on index signature member 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 --- .../ngcc/src/host/esm2015_host.ts | 4 +++- .../ngcc/test/host/esm2015_host_spec.ts | 24 +++++++++++++++++++ 2 files changed, 27 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 ad72c248203ae..ed1725c1142d6 100644 --- a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts +++ b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts @@ -1212,7 +1212,9 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N let name: string|null = null; let nameNode: ts.Identifier|null = null; - if (!isClassMemberType(node)) { + if (!isClassMemberType(node) || ts.isIndexSignatureDeclaration(node)) { + // `node` is not a class member or is an index signature, for example on an abstract class: + // `abstract class Foo { [key: string]: any; }` return null; } 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 b43c32d8399c1..d85f29e9beec7 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); From 7f54d5b43c4ea05e9542d9e151dea07de5497690 Mon Sep 17 00:00:00 2001 From: George Kalpakas Date: Thu, 17 Oct 2019 22:17:53 +0300 Subject: [PATCH 2/2] fixup! fix(ngcc): avoid warning when reflecting on index signature member --- packages/compiler-cli/ngcc/src/host/esm2015_host.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts index ed1725c1142d6..5a14f1cd5f860 100644 --- a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts +++ b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts @@ -1212,9 +1212,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N let name: string|null = null; let nameNode: ts.Identifier|null = null; - if (!isClassMemberType(node) || ts.isIndexSignatureDeclaration(node)) { - // `node` is not a class member or is an index signature, for example on an abstract class: - // `abstract class Foo { [key: string]: any; }` + if (!isClassMemberType(node)) { return null; } @@ -1780,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); } /**