Merge pull request #10211 from RyanCavanaugh/fourslashTestPerf

Speed up fourslash tests
This commit is contained in:
Ryan Cavanaugh
2016-08-12 13:33:22 -07:00
committed by GitHub
2 changed files with 30 additions and 64 deletions

View File

@@ -249,6 +249,7 @@ namespace FourSlash {
if (compilationOptions.typeRoots) {
compilationOptions.typeRoots = compilationOptions.typeRoots.map(p => ts.getNormalizedAbsolutePath(p, this.basePath));
}
compilationOptions.skipDefaultLibCheck = true;
const languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions);
this.languageServiceAdapterHost = languageServiceAdapter.getHost();
@@ -376,7 +377,7 @@ namespace FourSlash {
public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, negative: boolean) {
const startMarker = this.getMarkerByName(startMarkerName);
const endMarker = this.getMarkerByName(endMarkerName);
const predicate = function (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
const predicate = function(errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
return ((errorMinChar === startPos) && (errorLimChar === endPos)) ? true : false;
};
@@ -428,12 +429,12 @@ namespace FourSlash {
let predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => boolean;
if (after) {
predicate = function (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
predicate = function(errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
return ((errorMinChar >= startPos) && (errorLimChar >= startPos)) ? true : false;
};
}
else {
predicate = function (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
predicate = function(errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
return ((errorMinChar <= startPos) && (errorLimChar <= startPos)) ? true : false;
};
}
@@ -458,7 +459,7 @@ namespace FourSlash {
endPos = endMarker.position;
}
errors.forEach(function (error: ts.Diagnostic) {
errors.forEach(function(error: ts.Diagnostic) {
if (predicate(error.start, error.start + error.length, startPos, endPos)) {
exists = true;
}
@@ -475,7 +476,7 @@ namespace FourSlash {
Harness.IO.log("Unexpected error(s) found. Error list is:");
}
errors.forEach(function (error: ts.Diagnostic) {
errors.forEach(function(error: ts.Diagnostic) {
Harness.IO.log(" minChar: " + error.start +
", limChar: " + (error.start + error.length) +
", message: " + ts.flattenDiagnosticMessageText(error.messageText, Harness.IO.newLine()) + "\n");
@@ -1348,14 +1349,7 @@ namespace FourSlash {
}
// Enters lines of text at the current caret position
public type(text: string) {
return this.typeHighFidelity(text);
}
// Enters lines of text at the current caret position, invoking
// language service APIs to mimic Visual Studio's behavior
// as much as possible
private typeHighFidelity(text: string) {
public type(text: string, highFidelity = false) {
let offset = this.currentCaretPosition;
const prevChar = " ";
const checkCadence = (text.length >> 2) + 1;
@@ -1364,24 +1358,26 @@ namespace FourSlash {
// Make the edit
const ch = text.charAt(i);
this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset, ch);
this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, offset);
if (highFidelity) {
this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, offset);
}
this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, ch);
offset++;
if (ch === "(" || ch === ",") {
/* Signature help*/
this.languageService.getSignatureHelpItems(this.activeFile.fileName, offset);
}
else if (prevChar === " " && /A-Za-z_/.test(ch)) {
/* Completions */
this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset);
}
if (highFidelity) {
if (ch === "(" || ch === ",") {
/* Signature help*/
this.languageService.getSignatureHelpItems(this.activeFile.fileName, offset);
}
else if (prevChar === " " && /A-Za-z_/.test(ch)) {
/* Completions */
this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset);
}
if (i % checkCadence === 0) {
this.checkPostEditInvariants();
// this.languageService.getSyntacticDiagnostics(this.activeFile.fileName);
// this.languageService.getSemanticDiagnostics(this.activeFile.fileName);
if (i % checkCadence === 0) {
this.checkPostEditInvariants();
}
}
// Handle post-keystroke formatting
@@ -1389,14 +1385,12 @@ namespace FourSlash {
const edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions);
if (edits.length) {
offset += this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true);
// this.checkPostEditInvariants();
}
}
}
// Move the caret to wherever we ended up
this.currentCaretPosition = offset;
this.fixCaretPosition();
this.checkPostEditInvariants();
}
@@ -1415,7 +1409,6 @@ namespace FourSlash {
const edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, offset, this.formatCodeOptions);
if (edits.length) {
offset += this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true);
this.checkPostEditInvariants();
}
}
@@ -2269,40 +2262,12 @@ namespace FourSlash {
export function runFourSlashTestContent(basePath: string, testType: FourSlashTestType, content: string, fileName: string): void {
// Parse out the files and their metadata
const testData = parseTestData(basePath, content, fileName);
const state = new TestState(basePath, testType, testData);
let result = "";
const fourslashFile: Harness.Compiler.TestFile = {
unitName: Harness.Compiler.fourslashFileName,
content: undefined,
};
const testFile: Harness.Compiler.TestFile = {
unitName: fileName,
content: content
};
const host = Harness.Compiler.createCompilerHost(
[fourslashFile, testFile],
(fn, contents) => result = contents,
ts.ScriptTarget.Latest,
Harness.IO.useCaseSensitiveFileNames(),
Harness.IO.getCurrentDirectory());
const program = ts.createProgram([Harness.Compiler.fourslashFileName, fileName], { outFile: "fourslashTestOutput.js", noResolve: true, target: ts.ScriptTarget.ES3 }, host);
const sourceFile = host.getSourceFile(fileName, ts.ScriptTarget.ES3);
const diagnostics = ts.getPreEmitDiagnostics(program, sourceFile);
if (diagnostics.length > 0) {
throw new Error(`Error compiling ${fileName}: ` +
diagnostics.map(e => ts.flattenDiagnosticMessageText(e.messageText, Harness.IO.newLine())).join("\r\n"));
const output = ts.transpileModule(content, { reportDiagnostics: true });
if (output.diagnostics.length > 0) {
throw new Error(`Syntax error in ${basePath}: ${output.diagnostics[0].messageText}`);
}
program.emit(sourceFile);
ts.Debug.assert(!!result);
runCode(result, state);
runCode(output.outputText, state);
}
function runCode(code: string, state: TestState): void {

View File

@@ -205,12 +205,13 @@ const rangesByText = test.rangesByText();
for (const text in rangesByText) {
const ranges = rangesByText[text];
if (text === "globalVar") {
function isShadow(r) {
return r.marker && r.marker.data && r.marker.data.shadow;
}
verify.rangesReferenceEachOther(ranges.filter(isShadow));
verify.rangesReferenceEachOther(ranges.filter(r => !isShadow(r)));
} else {
verify.rangesReferenceEachOther(ranges);
}
}
function isShadow(r) {
return r.marker && r.marker.data && r.marker.data.shadow;
}