Throw diagnostic error when main adl file is not found. (#560)
This commit is contained in:
Родитель
9427591bfe
Коммит
1a34119e65
|
@ -32,6 +32,7 @@ export class AggregateError extends Error {
|
|||
}
|
||||
}
|
||||
|
||||
export const NoTarget = Symbol("NoTarget");
|
||||
export type DiagnosticTarget = Node | Type | Sym | SourceLocation;
|
||||
export type WriteLine = (text?: string) => void;
|
||||
|
||||
|
@ -45,7 +46,7 @@ export const throwOnError: ErrorHandler = throwDiagnostic;
|
|||
|
||||
export function throwDiagnostic(
|
||||
message: Message | string,
|
||||
target: DiagnosticTarget,
|
||||
target: DiagnosticTarget | typeof NoTarget,
|
||||
args?: (string | number)[]
|
||||
): never {
|
||||
throw new DiagnosticError([createDiagnostic(message, target, args)]);
|
||||
|
@ -53,17 +54,18 @@ export function throwDiagnostic(
|
|||
|
||||
export function createDiagnostic(
|
||||
message: Message | string,
|
||||
target: DiagnosticTarget,
|
||||
target: DiagnosticTarget | typeof NoTarget,
|
||||
args?: (string | number)[]
|
||||
): Diagnostic {
|
||||
let location: SourceLocation;
|
||||
let location: Partial<SourceLocation> = {};
|
||||
let locationError: Error | undefined;
|
||||
|
||||
try {
|
||||
location = getSourceLocation(target);
|
||||
} catch (err) {
|
||||
locationError = err;
|
||||
location = createDummySourceLocation();
|
||||
if (target !== NoTarget) {
|
||||
try {
|
||||
location = getSourceLocation(target);
|
||||
} catch (err) {
|
||||
locationError = err;
|
||||
location = createDummySourceLocation();
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof message === "string") {
|
||||
|
@ -94,12 +96,17 @@ export function logDiagnostics(diagnostics: readonly Diagnostic[], writeLine: Wr
|
|||
|
||||
export function formatDiagnostic(diagnostic: Diagnostic) {
|
||||
const code = diagnostic.code ? ` ADL${diagnostic.code}` : "";
|
||||
const pos = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.pos);
|
||||
const line = pos.line + 1;
|
||||
const col = pos.character + 1;
|
||||
const severity = diagnostic.severity;
|
||||
const path = diagnostic.file.path;
|
||||
return `${path}:${line}:${col} - ${severity}${code}: ${diagnostic.message}`;
|
||||
const content = `${severity}${code}: ${diagnostic.message}`;
|
||||
if (diagnostic.file) {
|
||||
const pos = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.pos ?? 0);
|
||||
const line = pos.line + 1;
|
||||
const col = pos.character + 1;
|
||||
const path = diagnostic.file.path;
|
||||
return `${path}:${line}:${col} - ${content}`;
|
||||
} else {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
export function createSourceFile(text: string, path: string): SourceFile {
|
||||
|
|
|
@ -59,6 +59,12 @@ export const Message = {
|
|||
severity: "error",
|
||||
text: "Invalid character.",
|
||||
} as const,
|
||||
|
||||
FileNotFound: {
|
||||
code: 1109,
|
||||
text: `File {0} is not found.`,
|
||||
severity: "error",
|
||||
} as const,
|
||||
};
|
||||
|
||||
// Static assert: this won't compile if one of the entries above is invalid.
|
||||
|
|
|
@ -2,7 +2,8 @@ import { dirname, extname, isAbsolute, join, resolve } from "path";
|
|||
import resolveModule from "resolve";
|
||||
import { createBinder, createSymbolTable } from "./binder.js";
|
||||
import { createChecker } from "./checker.js";
|
||||
import { createSourceFile, DiagnosticError, throwDiagnostic } from "./diagnostics.js";
|
||||
import { createSourceFile, DiagnosticError, NoTarget, throwDiagnostic } from "./diagnostics.js";
|
||||
import { Message } from "./messages.js";
|
||||
import { CompilerOptions } from "./options.js";
|
||||
import { parse } from "./parser.js";
|
||||
import {
|
||||
|
@ -349,8 +350,7 @@ export async function createProgram(
|
|||
|
||||
const mainPath = resolve(host.getCwd(), options.mainFile);
|
||||
|
||||
const mainStat = await host.stat(mainPath);
|
||||
|
||||
const mainStat = await getMainPathStats(mainPath);
|
||||
if (mainStat.isDirectory()) {
|
||||
await loadDirectory(mainPath);
|
||||
} else {
|
||||
|
@ -358,6 +358,17 @@ export async function createProgram(
|
|||
}
|
||||
}
|
||||
|
||||
async function getMainPathStats(mainPath: string) {
|
||||
try {
|
||||
return await host.stat(mainPath);
|
||||
} catch (e) {
|
||||
if (e.code === "ENOENT") {
|
||||
throwDiagnostic(Message.FileNotFound, NoTarget, [mainPath]);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
function getOption(key: string): string | undefined {
|
||||
return (options.miscOptions || {})[key];
|
||||
}
|
||||
|
|
|
@ -507,7 +507,7 @@ export interface SourceLocation extends TextRange {
|
|||
file: SourceFile;
|
||||
}
|
||||
|
||||
export interface Diagnostic extends SourceLocation {
|
||||
export interface Diagnostic extends Partial<SourceLocation> {
|
||||
message: string;
|
||||
code?: number;
|
||||
severity: "warning" | "error";
|
||||
|
|
|
@ -20,8 +20,8 @@ export class PrettierParserError extends Error {
|
|||
public constructor(public readonly error: Diagnostic) {
|
||||
super(error.message);
|
||||
this.loc = {
|
||||
start: error.pos,
|
||||
end: error.end,
|
||||
start: error.pos ?? 0,
|
||||
end: error.end ?? 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,8 +50,8 @@ function checkChange(change: TextDocumentChangeEvent<TextDocument>) {
|
|||
const diagnostics: Diagnostic[] = [];
|
||||
|
||||
for (const each of parseDiagnostics) {
|
||||
const start = document.positionAt(each.pos);
|
||||
const end = document.positionAt(each.end);
|
||||
const start = document.positionAt(each.pos ?? 0);
|
||||
const end = document.positionAt(each.end ?? 0);
|
||||
const range = Range.create(start, end);
|
||||
const severity = convertSeverity(each.severity);
|
||||
const diagnostic = Diagnostic.create(range, each.message, severity, each.code, "ADL");
|
||||
|
|
Загрузка…
Ссылка в новой задаче