From c35671c0a408c0a2f7f119b6e2c4f24efb68f39b Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Tue, 4 Feb 2020 12:23:54 -0800 Subject: [PATCH] fix(ivy): template type-check errors from TS should not use NG error codes (#35146) A bug previously caused the template type-checking diagnostics produced by TypeScript for template expressions to use -99-prefixed error codes. These codes are converted to "NG" errors instead of "TS" errors during diagnostic printing. This commit fixes the issue. PR Close #35146 --- .../src/ngtsc/typecheck/src/diagnostics.ts | 10 ++++++---- packages/compiler-cli/src/ngtsc/typecheck/src/dom.ts | 7 ++++--- packages/compiler-cli/src/ngtsc/typecheck/src/oob.ts | 9 +++++---- .../compiler-cli/test/ngtsc/template_typecheck_spec.ts | 2 ++ 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/diagnostics.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/diagnostics.ts index 1e28d57109..b65fa8d818 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/diagnostics.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/diagnostics.ts @@ -8,7 +8,6 @@ import {AbsoluteSourceSpan, ParseSourceSpan} from '@angular/compiler'; import * as ts from 'typescript'; -import {ErrorCode, ngErrorCode} from '../../diagnostics'; import {getTokenAtPosition} from '../../util/src/typescript'; import {ExternalTemplateSourceMapping, TemplateId, TemplateSourceMapping} from './api'; @@ -146,7 +145,7 @@ export function translateDiagnostic( */ export function makeTemplateDiagnostic( mapping: TemplateSourceMapping, span: ParseSourceSpan, category: ts.DiagnosticCategory, - code: ErrorCode, messageText: string | ts.DiagnosticMessageChain, relatedMessage?: { + code: number, messageText: string | ts.DiagnosticMessageChain, relatedMessage?: { text: string, span: ParseSourceSpan, }): TemplateDiagnostic { @@ -167,7 +166,9 @@ export function makeTemplateDiagnostic( // directly into the bytes of the source file. return { source: 'ngtsc', - code: ngErrorCode(code), category, messageText, + code, + category, + messageText, file: mapping.node.getSourceFile(), componentFile: mapping.node.getSourceFile(), start: span.start.offset, @@ -216,7 +217,8 @@ export function makeTemplateDiagnostic( return { source: 'ngtsc', category, - code: ngErrorCode(code), messageText, + code, + messageText, file: sf, componentFile: componentSf, start: span.start.offset, diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/dom.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/dom.ts index 48733b5d9e..480577cbdc 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/dom.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/dom.ts @@ -9,7 +9,7 @@ import {DomElementSchemaRegistry, ParseSourceSpan, SchemaMetadata, TmplAstElement} from '@angular/compiler'; import * as ts from 'typescript'; -import {ErrorCode} from '../../diagnostics'; +import {ErrorCode, ngErrorCode} from '../../diagnostics'; import {TemplateId} from './api'; import {TemplateSourceResolver, makeTemplateDiagnostic} from './diagnostics'; @@ -92,7 +92,7 @@ export class RegistryDomSchemaChecker implements DomSchemaChecker { const diag = makeTemplateDiagnostic( mapping, element.sourceSpan, ts.DiagnosticCategory.Error, - ErrorCode.SCHEMA_INVALID_ELEMENT, errorMsg); + ngErrorCode(ErrorCode.SCHEMA_INVALID_ELEMENT), errorMsg); this._diagnostics.push(diag); } } @@ -117,7 +117,8 @@ export class RegistryDomSchemaChecker implements DomSchemaChecker { } const diag = makeTemplateDiagnostic( - mapping, span, ts.DiagnosticCategory.Error, ErrorCode.SCHEMA_INVALID_ATTRIBUTE, errorMsg); + mapping, span, ts.DiagnosticCategory.Error, + ngErrorCode(ErrorCode.SCHEMA_INVALID_ATTRIBUTE), errorMsg); this._diagnostics.push(diag); } } diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/oob.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/oob.ts index 6a5404d4c9..58096e4fdb 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/oob.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/oob.ts @@ -66,7 +66,7 @@ export class OutOfBandDiagnosticRecorderImpl implements OutOfBandDiagnosticRecor const errorMsg = `No directive found with exportAs '${value}'.`; this._diagnostics.push(makeTemplateDiagnostic( mapping, ref.valueSpan || ref.sourceSpan, ts.DiagnosticCategory.Error, - ErrorCode.MISSING_REFERENCE_TARGET, errorMsg)); + ngErrorCode(ErrorCode.MISSING_REFERENCE_TARGET), errorMsg)); } missingPipe(templateId: TemplateId, ast: BindingPipe): void { @@ -79,7 +79,8 @@ export class OutOfBandDiagnosticRecorderImpl implements OutOfBandDiagnosticRecor `Assertion failure: no SourceLocation found for usage of pipe '${ast.name}'.`); } this._diagnostics.push(makeTemplateDiagnostic( - mapping, sourceSpan, ts.DiagnosticCategory.Error, ErrorCode.MISSING_PIPE, errorMsg)); + mapping, sourceSpan, ts.DiagnosticCategory.Error, ngErrorCode(ErrorCode.MISSING_PIPE), + errorMsg)); } illegalAssignmentToTemplateVar( @@ -93,8 +94,8 @@ export class OutOfBandDiagnosticRecorderImpl implements OutOfBandDiagnosticRecor throw new Error(`Assertion failure: no SourceLocation found for property binding.`); } this._diagnostics.push(makeTemplateDiagnostic( - mapping, sourceSpan, ts.DiagnosticCategory.Error, ErrorCode.WRITE_TO_READ_ONLY_VARIABLE, - errorMsg, { + mapping, sourceSpan, ts.DiagnosticCategory.Error, + ngErrorCode(ErrorCode.WRITE_TO_READ_ONLY_VARIABLE), errorMsg, { text: `The variable ${assignment.name} is declared here.`, span: target.valueSpan || target.sourceSpan, })); diff --git a/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts b/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts index 4a33626b73..d97a9ac640 100644 --- a/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts +++ b/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts @@ -135,6 +135,8 @@ export declare class AnimationEvent { const diags = env.driveDiagnostics(); expect(diags.length).toBe(1); expect(diags[0].messageText).toEqual(`Type 'string' is not assignable to type 'number'.`); + // The reported error code should be in the TS error space, not a -99 "NG" code. + expect(diags[0].code).toBeGreaterThan(0); }); it('should support inputs and outputs with names that are not JavaScript identifiers', () => {