mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 12:19:12 +00:00
Merge deno_cli_snapshots into deno_cli (#3064)
This commit is contained in:
parent
9049213867
commit
b81e5db17a
148 changed files with 38 additions and 83 deletions
217
cli/js/diagnostics.ts
Normal file
217
cli/js/diagnostics.ts
Normal file
|
@ -0,0 +1,217 @@
|
|||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// Diagnostic provides an abstraction for advice/errors received from a
|
||||
// compiler, which is strongly influenced by the format of TypeScript
|
||||
// diagnostics.
|
||||
|
||||
/** The log category for a diagnostic message */
|
||||
export enum DiagnosticCategory {
|
||||
Log = 0,
|
||||
Debug = 1,
|
||||
Info = 2,
|
||||
Error = 3,
|
||||
Warning = 4,
|
||||
Suggestion = 5
|
||||
}
|
||||
|
||||
export interface DiagnosticMessageChain {
|
||||
message: string;
|
||||
category: DiagnosticCategory;
|
||||
code: number;
|
||||
next?: DiagnosticMessageChain[];
|
||||
}
|
||||
|
||||
export interface DiagnosticItem {
|
||||
/** A string message summarizing the diagnostic. */
|
||||
message: string;
|
||||
|
||||
/** An ordered array of further diagnostics. */
|
||||
messageChain?: DiagnosticMessageChain;
|
||||
|
||||
/** Information related to the diagnostic. This is present when there is a
|
||||
* suggestion or other additional diagnostic information */
|
||||
relatedInformation?: DiagnosticItem[];
|
||||
|
||||
/** The text of the source line related to the diagnostic */
|
||||
sourceLine?: string;
|
||||
|
||||
/** The line number that is related to the diagnostic */
|
||||
lineNumber?: number;
|
||||
|
||||
/** The name of the script resource related to the diagnostic */
|
||||
scriptResourceName?: string;
|
||||
|
||||
/** The start position related to the diagnostic */
|
||||
startPosition?: number;
|
||||
|
||||
/** The end position related to the diagnostic */
|
||||
endPosition?: number;
|
||||
|
||||
/** The category of the diagnostic */
|
||||
category: DiagnosticCategory;
|
||||
|
||||
/** A number identifier */
|
||||
code: number;
|
||||
|
||||
/** The the start column of the sourceLine related to the diagnostic */
|
||||
startColumn?: number;
|
||||
|
||||
/** The end column of the sourceLine related to the diagnostic */
|
||||
endColumn?: number;
|
||||
}
|
||||
|
||||
export interface Diagnostic {
|
||||
/** An array of diagnostic items. */
|
||||
items: DiagnosticItem[];
|
||||
}
|
||||
|
||||
interface SourceInformation {
|
||||
sourceLine: string;
|
||||
lineNumber: number;
|
||||
scriptResourceName: string;
|
||||
startColumn: number;
|
||||
endColumn: number;
|
||||
}
|
||||
|
||||
function fromDiagnosticCategory(
|
||||
category: ts.DiagnosticCategory
|
||||
): DiagnosticCategory {
|
||||
switch (category) {
|
||||
case ts.DiagnosticCategory.Error:
|
||||
return DiagnosticCategory.Error;
|
||||
case ts.DiagnosticCategory.Message:
|
||||
return DiagnosticCategory.Info;
|
||||
case ts.DiagnosticCategory.Suggestion:
|
||||
return DiagnosticCategory.Suggestion;
|
||||
case ts.DiagnosticCategory.Warning:
|
||||
return DiagnosticCategory.Warning;
|
||||
default:
|
||||
throw new Error(
|
||||
`Unexpected DiagnosticCategory: "${category}"/"${
|
||||
ts.DiagnosticCategory[category]
|
||||
}"`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceInformation(
|
||||
sourceFile: ts.SourceFile,
|
||||
start: number,
|
||||
length: number
|
||||
): SourceInformation {
|
||||
const scriptResourceName = sourceFile.fileName;
|
||||
const {
|
||||
line: lineNumber,
|
||||
character: startColumn
|
||||
} = sourceFile.getLineAndCharacterOfPosition(start);
|
||||
const endPosition = sourceFile.getLineAndCharacterOfPosition(start + length);
|
||||
const endColumn =
|
||||
lineNumber === endPosition.line ? endPosition.character : startColumn;
|
||||
const lastLineInFile = sourceFile.getLineAndCharacterOfPosition(
|
||||
sourceFile.text.length
|
||||
).line;
|
||||
const lineStart = sourceFile.getPositionOfLineAndCharacter(lineNumber, 0);
|
||||
const lineEnd =
|
||||
lineNumber < lastLineInFile
|
||||
? sourceFile.getPositionOfLineAndCharacter(lineNumber + 1, 0)
|
||||
: sourceFile.text.length;
|
||||
const sourceLine = sourceFile.text
|
||||
.slice(lineStart, lineEnd)
|
||||
.replace(/\s+$/g, "")
|
||||
.replace("\t", " ");
|
||||
return {
|
||||
sourceLine,
|
||||
lineNumber,
|
||||
scriptResourceName,
|
||||
startColumn,
|
||||
endColumn
|
||||
};
|
||||
}
|
||||
|
||||
/** Converts a TypeScript diagnostic message chain to a Deno one. */
|
||||
function fromDiagnosticMessageChain(
|
||||
messageChain: ts.DiagnosticMessageChain[] | undefined
|
||||
): DiagnosticMessageChain[] | undefined {
|
||||
if (!messageChain) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return messageChain.map(({ messageText: message, code, category, next }) => {
|
||||
return {
|
||||
message,
|
||||
code,
|
||||
category: fromDiagnosticCategory(category),
|
||||
next: fromDiagnosticMessageChain(next)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/** Parse out information from a TypeScript diagnostic structure. */
|
||||
function parseDiagnostic(
|
||||
item: ts.Diagnostic | ts.DiagnosticRelatedInformation
|
||||
): DiagnosticItem {
|
||||
const {
|
||||
messageText,
|
||||
category: sourceCategory,
|
||||
code,
|
||||
file,
|
||||
start: startPosition,
|
||||
length
|
||||
} = item;
|
||||
const sourceInfo =
|
||||
file && startPosition && length
|
||||
? getSourceInformation(file, startPosition, length)
|
||||
: undefined;
|
||||
const endPosition =
|
||||
startPosition && length ? startPosition + length : undefined;
|
||||
const category = fromDiagnosticCategory(sourceCategory);
|
||||
|
||||
let message: string;
|
||||
let messageChain: DiagnosticMessageChain | undefined;
|
||||
if (typeof messageText === "string") {
|
||||
message = messageText;
|
||||
} else {
|
||||
message = messageText.messageText;
|
||||
messageChain = fromDiagnosticMessageChain([messageText])![0];
|
||||
}
|
||||
|
||||
const base = {
|
||||
message,
|
||||
messageChain,
|
||||
code,
|
||||
category,
|
||||
startPosition,
|
||||
endPosition
|
||||
};
|
||||
|
||||
return sourceInfo ? { ...base, ...sourceInfo } : base;
|
||||
}
|
||||
|
||||
/** Convert a diagnostic related information array into a Deno diagnostic
|
||||
* array. */
|
||||
function parseRelatedInformation(
|
||||
relatedInformation: readonly ts.DiagnosticRelatedInformation[]
|
||||
): DiagnosticItem[] {
|
||||
const result: DiagnosticItem[] = [];
|
||||
for (const item of relatedInformation) {
|
||||
result.push(parseDiagnostic(item));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Convert TypeScript diagnostics to Deno diagnostics. */
|
||||
export function fromTypeScriptDiagnostic(
|
||||
diagnostics: readonly ts.Diagnostic[]
|
||||
): Diagnostic {
|
||||
const items: DiagnosticItem[] = [];
|
||||
for (const sourceDiagnostic of diagnostics) {
|
||||
const item: DiagnosticItem = parseDiagnostic(sourceDiagnostic);
|
||||
if (sourceDiagnostic.relatedInformation) {
|
||||
item.relatedInformation = parseRelatedInformation(
|
||||
sourceDiagnostic.relatedInformation
|
||||
);
|
||||
}
|
||||
items.push(item);
|
||||
}
|
||||
return { items };
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue