Fix: Don't format a file that has parsing errors (#549)

This commit is contained in:
Timothee Guerin 2021-05-13 15:57:33 -07:00 коммит произвёл GitHub
Родитель bf53463205
Коммит bb82633b6c
4 изменённых файлов: 51 добавлений и 13 удалений

Просмотреть файл

@ -327,7 +327,7 @@ async function main() {
break;
}
case "format":
await formatADLFiles(args["include"]!);
await formatADLFiles(args["include"]!, { debug: args.debug });
break;
}
}

Просмотреть файл

@ -2,6 +2,7 @@ import { readFile, writeFile } from "fs/promises";
import glob from "glob";
import prettier from "prettier";
import * as adlPrettierPlugin from "../formatter/index.js";
import { PrettierParserError } from "../formatter/parser.js";
export async function formatADL(code: string): Promise<string> {
const output = prettier.format(code, {
@ -15,10 +16,19 @@ export async function formatADL(code: string): Promise<string> {
* Format all the adl files.
* @param patterns List of wildcard pattern searching for adl files.
*/
export async function formatADLFiles(patterns: string[]) {
export async function formatADLFiles(patterns: string[], { debug }: { debug?: boolean }) {
const files = await findFiles(patterns);
for (const file of files) {
await formatADLFile(file);
try {
await formatADLFile(file);
} catch (e) {
if (e instanceof PrettierParserError) {
const details = debug ? e.message : "";
console.error(`File '${file}' failed to fromat. ${details}`);
} else {
throw e;
}
}
}
}

Просмотреть файл

@ -1,11 +1,27 @@
import { Parser, ParserOptions } from "prettier";
import { parse as adlParse } from "../compiler/parser.js";
import { ADLScriptNode } from "../compiler/types.js";
import { ADLScriptNode, Diagnostic } from "../compiler/types.js";
export function parse(
text: string,
parsers: { [parserName: string]: Parser },
opts: ParserOptions & { parentParser?: string }
): ADLScriptNode {
return adlParse(text, { comments: true });
const result = adlParse(text, { comments: true });
const errors = result.parseDiagnostics.filter((x) => x.severity === "error");
if (errors.length > 0) {
throw new PrettierParserError(errors[0]);
}
return result;
}
export class PrettierParserError extends Error {
public loc: { start: number; end: number };
public constructor(public readonly error: Diagnostic) {
super(error.message);
this.loc = {
start: error.pos,
end: error.end,
};
}
}

Просмотреть файл

@ -1,4 +1,4 @@
import { strictEqual } from "assert";
import { strictEqual, throws } from "assert";
import prettier from "prettier";
import * as plugin from "../../formatter/index.js";
@ -16,6 +16,12 @@ function assertFormat({ code, expected }: { code: string; expected: string }) {
}
describe("adl: prettier formatter", () => {
it("throws error if there is a parsing issue", () => {
const code = `namespace this is invalid`;
throws(() => format(code));
});
it("format imports", () => {
assertFormat({
code: `
@ -191,11 +197,11 @@ alias Bar = "one" | "two";
it("format generic alias", () => {
assertFormat({
code: `
alias Foo< A, B> = A | B
alias Foo< A, B> = A | B;
alias Bar<
A, B> =
A |
B
B;
`,
expected: `
alias Foo<A, B> = A | B;
@ -317,12 +323,19 @@ enum Bar {
assertFormat({
code: `
namespace Foo;
namespace Foo . Bar;
`,
expected: `
namespace Foo;
`,
});
});
it("format global nested namespace", () => {
assertFormat({
code: `
namespace Foo . Bar;
`,
expected: `
namespace Foo.Bar;
`,
});
@ -371,8 +384,7 @@ namespace Foo.Bar {
assertFormat({
code: `
namespace Foo {
namespace Foo . Bar {
namespace Bar {
op some(): string;
}
}
@ -381,7 +393,7 @@ op some(): string;
`,
expected: `
namespace Foo {
namespace Foo.Bar {
namespace Bar {
op some(): string;
}
}