From 057e5774035416227f1a9b263ec6117518b355fb Mon Sep 17 00:00:00 2001 From: Daniel Trevino <23410540+danieltre23@users.noreply.github.com> Date: Thu, 22 Jul 2021 21:18:04 +0000 Subject: [PATCH] refactor(compiler-cli): add makeTemplateDiagnostic wrapper (#42937) Add a `makeTemplateDiagnostic` wrapper in the `TemplateTypeChecker`. This requiers less parameters to create template diagnostics, since the `TemplateTypeChecker` can get the templateId and mapping from it's scope with the `ts.ClassDeclartion`. The `TemplateTypeChecker` is often used to determine if a diagnostic should be produced, so it makes sense to have a function in it that helps create them. Refs #42966 PR Close #42937 --- .../src/ngtsc/typecheck/api/BUILD.bazel | 1 + .../src/ngtsc/typecheck/api/checker.ts | 15 ++++++++++++- .../src/ngtsc/typecheck/src/checker.ts | 22 +++++++++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/packages/compiler-cli/src/ngtsc/typecheck/api/BUILD.bazel b/packages/compiler-cli/src/ngtsc/typecheck/api/BUILD.bazel index 0ee8e61fcc..ef61fe05f1 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/api/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/typecheck/api/BUILD.bazel @@ -9,6 +9,7 @@ ts_library( deps = [ "//packages:types", "//packages/compiler", + "//packages/compiler-cli/src/ngtsc/diagnostics", "//packages/compiler-cli/src/ngtsc/file_system", "//packages/compiler-cli/src/ngtsc/imports", "//packages/compiler-cli/src/ngtsc/metadata", diff --git a/packages/compiler-cli/src/ngtsc/typecheck/api/checker.ts b/packages/compiler-cli/src/ngtsc/typecheck/api/checker.ts index d2b022f603..84635508b8 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/api/checker.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/api/checker.ts @@ -6,9 +6,10 @@ * found in the LICENSE file at https://angular.io/license */ -import {AST, MethodCall, ParseError, PropertyRead, SafeMethodCall, SafePropertyRead, TmplAstElement, TmplAstNode, TmplAstTemplate} from '@angular/compiler'; +import {AST, MethodCall, ParseError, ParseSourceSpan, PropertyRead, SafeMethodCall, SafePropertyRead, TmplAstElement, TmplAstNode, TmplAstTemplate} from '@angular/compiler'; import {AbsoluteFsPath} from '@angular/compiler-cli/src/ngtsc/file_system'; import * as ts from 'typescript'; +import {ErrorCode} from '../../diagnostics'; import {FullTemplateMapping, TypeCheckableDirectiveMeta} from './api'; import {GlobalCompletion} from './completion'; @@ -154,6 +155,18 @@ export interface TemplateTypeChecker { * the next request. */ invalidateClass(clazz: ts.ClassDeclaration): void; + + /** + * Constructs a `ts.Diagnostic` for a given `ParseSourceSpan` within a template. + */ + makeTemplateDiagnostic( + clazz: ts.ClassDeclaration, sourceSpan: ParseSourceSpan, category: ts.DiagnosticCategory, + errorCode: ErrorCode, message: string, relatedInformation?: { + text: string, + start: number, + end: number, + sourceFile: ts.SourceFile, + }[]): ts.Diagnostic; } /** diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts index 6a4608dc1b..a3bd6f5394 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts @@ -6,8 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ -import {AST, CssSelector, DomElementSchemaRegistry, MethodCall, ParseError, parseTemplate, PropertyRead, SafeMethodCall, SafePropertyRead, TmplAstElement, TmplAstNode, TmplAstReference, TmplAstTemplate, TmplAstVariable} from '@angular/compiler'; +import {AST, CssSelector, DomElementSchemaRegistry, MethodCall, ParseError, ParseSourceSpan, parseTemplate, PropertyRead, SafeMethodCall, SafePropertyRead, TmplAstElement, TmplAstNode, TmplAstReference, TmplAstTemplate, TmplAstVariable} from '@angular/compiler'; import * as ts from 'typescript'; +import {ErrorCode} from '../../diagnostics'; import {absoluteFrom, absoluteFromSourceFile, AbsoluteFsPath, getSourceFileOrError} from '../../file_system'; import {Reference, ReferenceEmitter} from '../../imports'; @@ -19,7 +20,7 @@ import {ComponentScopeReader, TypeCheckScopeRegistry} from '../../scope'; import {isShim} from '../../shims'; import {getSourceFileOrNull, isSymbolWithValueDeclaration} from '../../util/src/typescript'; import {DirectiveInScope, ElementSymbol, FullTemplateMapping, GlobalCompletion, OptimizeFor, PipeInScope, ProgramTypeCheckAdapter, ShimLocation, Symbol, TemplateId, TemplateSymbol, TemplateTypeChecker, TypeCheckableDirectiveMeta, TypeCheckingConfig} from '../api'; -import {TemplateDiagnostic} from '../diagnostics'; +import {makeTemplateDiagnostic, TemplateDiagnostic} from '../diagnostics'; import {CompletionEngine} from './completion'; import {InliningMode, ShimTypeCheckingData, TemplateData, TypeCheckContextImpl, TypeCheckingHost} from './context'; @@ -297,6 +298,23 @@ export class TemplateTypeCheckerImpl implements TemplateTypeChecker { this.isComplete = false; } + makeTemplateDiagnostic( + clazz: ts.ClassDeclaration, sourceSpan: ParseSourceSpan, category: ts.DiagnosticCategory, + errorCode: ErrorCode, message: string, relatedInformation?: { + text: string, + start: number, + end: number, + sourceFile: ts.SourceFile, + }[]): TemplateDiagnostic { + const sfPath = absoluteFromSourceFile(clazz.getSourceFile()); + const fileRecord = this.state.get(sfPath)!; + const templateId = fileRecord.sourceManager.getTemplateId(clazz); + const mapping = fileRecord.sourceManager.getSourceMapping(templateId); + + return makeTemplateDiagnostic( + templateId, mapping, sourceSpan, category, errorCode, message, relatedInformation); + } + private getOrCreateCompletionEngine(component: ts.ClassDeclaration): CompletionEngine|null { if (this.completionCache.has(component)) { return this.completionCache.get(component)!;