Skip to content

Commit

Permalink
feat: #709 - Check and display syntax diagnostics when a manipulation…
Browse files Browse the repository at this point in the history
… error occurs.
  • Loading branch information
dsherret committed Sep 28, 2019
1 parent 666febb commit 07c42b1
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 7 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
},
"dependencies": {
"@dsherret/to-absolute-glob": "^2.0.2",
"chalk": "^2.4.2",
"code-block-writer": "^10.0.0",
"fs-extra": "^8.1.0",
"glob-parent": "^5.0.0",
Expand All @@ -90,7 +91,6 @@
"@types/node": "^12.7.5",
"@types/ts-nameof": "^3.2.0",
"chai": "^4.2.0",
"chalk": "^2.4.2",
"conditional-type-checks": "^1.0.1",
"coveralls": "^3.0.6",
"cross-env": "^6.0.0",
Expand Down
37 changes: 31 additions & 6 deletions src/manipulation/manipulations/doManipulation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* barrel:ignore */
import { SourceFile } from "../../compiler";
import chalk from "chalk";
import { SourceFile, Diagnostic } from "../../compiler";
import { Project, ProjectOptions } from "../../Project";
import * as errors from "../../errors";
import { NodeHandler } from "../nodeHandlers";
import { TextManipulator } from "../textManipulators";
Expand All @@ -15,10 +17,33 @@ export function doManipulation(sourceFile: SourceFile, textManipulator: TextMani
);
nodeHandler.handleNode(sourceFile, replacementSourceFile, replacementSourceFile);
} catch (err) {
throw new errors.InvalidOperationError(err.message + "\n"
+ `-- Details --\n`
+ `Path: ${sourceFile.getFilePath()}\n`
+ `Text: ${JSON.stringify(textManipulator.getTextForError(newFileText))}\n`
+ `Stack: ${err.stack}`);
const diagnostics = getSyntacticDiagnostics(sourceFile, newFileText);
const errorDetails = chalk.yellow(err.message) + "\n\n"
+ chalk.blue(`-- Details --\n`)
+ chalk.gray("Path: ") + sourceFile.getFilePath() + "\n"
+ chalk.gray("Text: ") + JSON.stringify(textManipulator.getTextForError(newFileText)) + "\n"
+ chalk.gray("Stack: ") + err.stack;

if (diagnostics.length > 0) {
throw new errors.InvalidOperationError(
chalk.red("Manipulation error: ") + chalk.yellow("A syntax error was inserted.") + "\n\n"
+ sourceFile._context.project.formatDiagnosticsWithColorAndContext(diagnostics, { newLineChar: "\n" })
+ "\n" + errorDetails
);
}

throw new errors.InvalidOperationError(chalk.red("Manipulation error: ") + errorDetails);
}
}

function getSyntacticDiagnostics(sourceFile: SourceFile, newText: string) {
try {
// hack to avoid circular references
const projectOptions: ProjectOptions = { useVirtualFileSystem: true };
const project = new (sourceFile._context.project.constructor as any)(projectOptions) as Project;
const newFile = project.createSourceFile(sourceFile.getFilePath(), newText);
return project.getProgram().getSyntacticDiagnostics(newFile);
} catch (err) {
return [] as Diagnostic[];
}
}
23 changes: 23 additions & 0 deletions src/tests/manipulation/manipulations/doManipulationTests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { expect } from "chai";
import { getInfoFromText } from "../../compiler/testHelpers";
import { SyntaxKind } from "../../../typescript";
import { Block } from "../../../compiler";

describe("doManipulation", () => {
it("should display the syntactic diagnostics if the user inserts a syntax error", () => {
const { sourceFile } = getInfoFromText("if (true) {\n}");
const ifStatement = sourceFile.getStatementByKindOrThrow(SyntaxKind.IfStatement);
const body = ifStatement.getThenStatement() as Block;
let foundErr: any;
try {
body.addStatements("testing {");
} catch (err) {
foundErr = err;
}

// don't bother with the rest because it will change between ts versions...
const expectedText = `Manipulation error: A syntax error was inserted.`;
const message: string = foundErr.message;
expect(message.replace(/\u001b\[[0-9][0-9]?m/g, "").substring(0, expectedText.length)).to.equal(expectedText);
});
});

0 comments on commit 07c42b1

Please sign in to comment.