From 1de757993da8160a2c41887470a6f70bd8554e82 Mon Sep 17 00:00:00 2001 From: Keen Yee Liau Date: Thu, 24 Oct 2019 10:17:25 -0700 Subject: [PATCH] fix(language-service): Improve signature selection for pipes with args (#33456) Pipes with arguments like `slice:0` or `slice:0:1` should not produce diagnostic errors. PR closes https://github.com/angular/vscode-ng-language-service/issues/345 PR Close #33456 --- .../src/diagnostics/expression_diagnostics.ts | 2 +- .../src/diagnostics/typescript_symbols.ts | 4 ++-- .../language-service/test/diagnostics_spec.ts | 20 +++++++++++++++++++ .../test/project/app/parsing-cases.ts | 1 + 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/packages/compiler-cli/src/diagnostics/expression_diagnostics.ts b/packages/compiler-cli/src/diagnostics/expression_diagnostics.ts index 2253d2c077..135be11753 100644 --- a/packages/compiler-cli/src/diagnostics/expression_diagnostics.ts +++ b/packages/compiler-cli/src/diagnostics/expression_diagnostics.ts @@ -335,4 +335,4 @@ function offsetSpan(span: Span, amount: number): Span { function spanOf(sourceSpan: ParseSourceSpan): Span { return {start: sourceSpan.start.offset, end: sourceSpan.end.offset}; -} \ No newline at end of file +} diff --git a/packages/compiler-cli/src/diagnostics/typescript_symbols.ts b/packages/compiler-cli/src/diagnostics/typescript_symbols.ts index 6f2d072866..99c63d9155 100644 --- a/packages/compiler-cli/src/diagnostics/typescript_symbols.ts +++ b/packages/compiler-cli/src/diagnostics/typescript_symbols.ts @@ -557,7 +557,7 @@ class PipeSymbol implements Symbol { selectSignature(types: Symbol[]): Signature|undefined { let signature = selectSignature(this.tsType, this.context, types) !; - if (types.length == 1) { + if (types.length > 0) { const parameterType = types[0]; if (parameterType instanceof TypeWrapper) { let resultType: ts.Type|undefined = undefined; @@ -575,7 +575,7 @@ class PipeSymbol implements Symbol { } break; case 'slice': - resultType = getTypeParameterOf(parameterType.tsType, 'Array'); + resultType = parameterType.tsType; break; } if (resultType) { diff --git a/packages/language-service/test/diagnostics_spec.ts b/packages/language-service/test/diagnostics_spec.ts index 8672897401..daaa615435 100644 --- a/packages/language-service/test/diagnostics_spec.ts +++ b/packages/language-service/test/diagnostics_spec.ts @@ -76,6 +76,26 @@ describe('diagnostics', () => { } }); + it('should not produce diagnostics for slice pipe with arguments', () => { + mockHost.override(TEST_TEMPLATE, ` +
+ {{h.name}} +
`); + const diags = ngLS.getDiagnostics(TEST_TEMPLATE); + expect(diags).toEqual([]); + }); + + it('should produce diagnostics for slice pipe with args when member is invalid', () => { + mockHost.override(TEST_TEMPLATE, ` +
+ {{h.age}} +
`); + const diags = ngLS.getDiagnostics(TEST_TEMPLATE); + expect(diags.length).toBe(1); + expect(diags[0].messageText) + .toBe(`Identifier 'age' is not defined. 'Hero' does not contain such a member`); + }); + describe('in expression-cases.ts', () => { it('should report access to an unknown field', () => { const diags = ngLS.getDiagnostics(EXPRESSION_CASES).map(d => d.messageText); diff --git a/packages/language-service/test/project/app/parsing-cases.ts b/packages/language-service/test/project/app/parsing-cases.ts index a67b216bf0..8418fea484 100644 --- a/packages/language-service/test/project/app/parsing-cases.ts +++ b/packages/language-service/test/project/app/parsing-cases.ts @@ -188,6 +188,7 @@ export class TestComponent { export class TemplateReference { title = 'Some title'; hero: Hero = {id: 1, name: 'Windstorm'}; + heroes: Hero[] = [this.hero]; anyValue: any; myClick(event: any) {} }