refactor(compiler-cli): create diagnostics using `ts.DiagnosticRelatedInformation` (#37587)
Previously, an anonymous type was used for creating a diagnostic with related information. The anonymous type would then be translated into the necessary `ts.DiagnosticRelatedInformation` shape within `makeDiagnostic`. This commit switches the `makeDiagnostic` signature over to taking `ts.DiagnosticRelatedInformation` directly and introduces `makeRelatedInformation` to easily create such objects. This is done to aid in making upcoming work more readable. PR Close #37587
This commit is contained in:
parent
5103d908c8
commit
d2fb552116
|
@ -8,7 +8,7 @@
|
|||
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {ErrorCode, makeDiagnostic} from '../../diagnostics';
|
||||
import {ErrorCode, makeDiagnostic, makeRelatedInformation} from '../../diagnostics';
|
||||
import {Reference} from '../../imports';
|
||||
import {InjectableClassRegistry, MetadataReader} from '../../metadata';
|
||||
import {PartialEvaluator} from '../../partial_evaluator';
|
||||
|
@ -44,7 +44,7 @@ Either add the @Injectable() decorator to '${
|
|||
provider.node.name
|
||||
.text}', or configure a different provider (such as a provider with 'useFactory').
|
||||
`,
|
||||
[{node: provider.node, messageText: `'${provider.node.name.text}' is declared here.`}]));
|
||||
[makeRelatedInformation(provider.node, `'${provider.node.name.text}' is declared here.`)]));
|
||||
}
|
||||
|
||||
return diagnostics;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import {compileInjector, compileNgModule, CUSTOM_ELEMENTS_SCHEMA, Expression, ExternalExpr, InvokeFunctionExpr, LiteralArrayExpr, LiteralExpr, NO_ERRORS_SCHEMA, R3Identifiers, R3InjectorMetadata, R3NgModuleMetadata, R3Reference, SchemaMetadata, Statement, STRING_TYPE, WrappedNodeExpr} from '@angular/compiler';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {ErrorCode, FatalDiagnosticError, makeDiagnostic} from '../../diagnostics';
|
||||
import {ErrorCode, FatalDiagnosticError, makeDiagnostic, makeRelatedInformation} from '../../diagnostics';
|
||||
import {DefaultImportRecorder, Reference, ReferenceEmitter} from '../../imports';
|
||||
import {InjectableClassRegistry, MetadataReader, MetadataRegistry} from '../../metadata';
|
||||
import {PartialEvaluator, ResolvedValue, ResolvedValueArray} from '../../partial_evaluator';
|
||||
|
@ -133,10 +133,8 @@ export class NgModuleDecoratorHandler implements
|
|||
`Cannot declare '${
|
||||
ref.node.name
|
||||
.text}' in an NgModule as it's not a part of the current compilation.`,
|
||||
[{
|
||||
node: ref.node.name,
|
||||
messageText: `'${ref.node.name.text}' is declared here.`,
|
||||
}]));
|
||||
[makeRelatedInformation(
|
||||
ref.node.name, `'${ref.node.name.text}' is declared here.`)]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import {Expression, ExternalExpr, LiteralExpr, ParseLocation, ParseSourceFile, ParseSourceSpan, R3DependencyMetadata, R3Reference, R3ResolvedDependencyType, ReadPropExpr, WrappedNodeExpr} from '@angular/compiler';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {ErrorCode, FatalDiagnosticError, makeDiagnostic} from '../../diagnostics';
|
||||
import {ErrorCode, FatalDiagnosticError, makeDiagnostic, makeRelatedInformation} from '../../diagnostics';
|
||||
import {DefaultImportRecorder, ImportFlags, Reference, ReferenceEmitter} from '../../imports';
|
||||
import {ForeignFunctionResolver, PartialEvaluator} from '../../partial_evaluator';
|
||||
import {ClassDeclaration, CtorParameter, Decorator, Import, isNamedClassDeclaration, ReflectionHost, TypeValueReference} from '../../reflection';
|
||||
|
@ -408,7 +408,7 @@ export function wrapFunctionExpressionsInParens(expression: ts.Expression): ts.E
|
|||
*/
|
||||
export function makeDuplicateDeclarationError(
|
||||
node: ClassDeclaration, data: DeclarationData[], kind: string): ts.Diagnostic {
|
||||
const context: {node: ts.Node; messageText: string;}[] = [];
|
||||
const context: ts.DiagnosticRelatedInformation[] = [];
|
||||
for (const decl of data) {
|
||||
if (decl.rawDeclarations === null) {
|
||||
continue;
|
||||
|
@ -416,11 +416,10 @@ export function makeDuplicateDeclarationError(
|
|||
// Try to find the reference to the declaration within the declarations array, to hang the
|
||||
// error there. If it can't be found, fall back on using the NgModule's name.
|
||||
const contextNode = decl.ref.getOriginForDiagnostics(decl.rawDeclarations, decl.ngModule.name);
|
||||
context.push({
|
||||
node: contextNode,
|
||||
messageText: `'${node.name.text}' is listed in the declarations of the NgModule '${
|
||||
decl.ngModule.name.text}'.`,
|
||||
});
|
||||
context.push(makeRelatedInformation(
|
||||
contextNode,
|
||||
`'${node.name.text}' is listed in the declarations of the NgModule '${
|
||||
decl.ngModule.name.text}'.`));
|
||||
}
|
||||
|
||||
// Finally, produce the diagnostic.
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
export {FatalDiagnosticError, isFatalDiagnosticError, makeDiagnostic} from './src/error';
|
||||
export {FatalDiagnosticError, isFatalDiagnosticError, makeDiagnostic, makeRelatedInformation} from './src/error';
|
||||
export {ErrorCode, ngErrorCode} from './src/error_code';
|
||||
export {replaceTsWithNgInErrors} from './src/util';
|
||||
|
|
|
@ -23,33 +23,32 @@ export class FatalDiagnosticError {
|
|||
}
|
||||
}
|
||||
|
||||
export function makeDiagnostic(code: ErrorCode, node: ts.Node, messageText: string, relatedInfo?: {
|
||||
node: ts.Node,
|
||||
messageText: string,
|
||||
}[]): ts.DiagnosticWithLocation {
|
||||
export function makeDiagnostic(
|
||||
code: ErrorCode, node: ts.Node, messageText: string,
|
||||
relatedInformation?: ts.DiagnosticRelatedInformation[]): ts.DiagnosticWithLocation {
|
||||
node = ts.getOriginalNode(node);
|
||||
const diag: ts.DiagnosticWithLocation = {
|
||||
return {
|
||||
category: ts.DiagnosticCategory.Error,
|
||||
code: Number('-99' + code.valueOf()),
|
||||
file: ts.getOriginalNode(node).getSourceFile(),
|
||||
start: node.getStart(undefined, false),
|
||||
length: node.getWidth(),
|
||||
messageText,
|
||||
relatedInformation,
|
||||
};
|
||||
if (relatedInfo !== undefined) {
|
||||
diag.relatedInformation = relatedInfo.map(info => {
|
||||
const infoNode = ts.getOriginalNode(info.node);
|
||||
}
|
||||
|
||||
export function makeRelatedInformation(
|
||||
node: ts.Node, messageText: string): ts.DiagnosticRelatedInformation {
|
||||
node = ts.getOriginalNode(node);
|
||||
return {
|
||||
category: ts.DiagnosticCategory.Message,
|
||||
code: 0,
|
||||
file: infoNode.getSourceFile(),
|
||||
start: infoNode.getStart(),
|
||||
length: infoNode.getWidth(),
|
||||
messageText: info.messageText,
|
||||
file: node.getSourceFile(),
|
||||
start: node.getStart(),
|
||||
length: node.getWidth(),
|
||||
messageText,
|
||||
};
|
||||
});
|
||||
}
|
||||
return diag;
|
||||
}
|
||||
|
||||
export function isFatalDiagnosticError(err: any): err is FatalDiagnosticError {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import {ExternalExpr, SchemaMetadata} from '@angular/compiler';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {ErrorCode, makeDiagnostic} from '../../diagnostics';
|
||||
import {ErrorCode, makeDiagnostic, makeRelatedInformation} from '../../diagnostics';
|
||||
import {AliasingHost, Reexport, Reference, ReferenceEmitter} from '../../imports';
|
||||
import {DirectiveMeta, MetadataReader, MetadataRegistry, NgModuleMeta, PipeMeta} from '../../metadata';
|
||||
import {ClassDeclaration} from '../../reflection';
|
||||
|
@ -358,7 +358,8 @@ export class LocalModuleScopeRegistry implements MetadataRegistry, ComponentScop
|
|||
ngModule.ref.node.name
|
||||
.text}', but is not a directive, a component, or a pipe. ` +
|
||||
`Either remove it from the NgModule's declarations, or add an appropriate Angular decorator.`,
|
||||
[{node: decl.node.name, messageText: `'${decl.node.name.text}' is declared here.`}]));
|
||||
[makeRelatedInformation(
|
||||
decl.node.name, `'${decl.node.name.text}' is declared here.`)]));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -643,8 +644,8 @@ function reexportCollision(
|
|||
To fix this problem please re-export one or both classes directly from this file.
|
||||
`.trim(),
|
||||
[
|
||||
{node: refA.node.name, messageText: childMessageText},
|
||||
{node: refB.node.name, messageText: childMessageText},
|
||||
makeRelatedInformation(refA.node.name, childMessageText),
|
||||
makeRelatedInformation(refB.node.name, childMessageText),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue