Use Better Range When Formatting TS Quick Fixes (#18135)

**Bug**
TS 2.2 includes a number of new code actions, such as implementing missing interface methods on classes. TS returns these in unedited form, so we have to format the document after applying these fixes. This formatting is not always correct using the current logic.

**Fix**
Try to determine the range to format using the set of text edits that TS returns to us. This is not perfect, but it should better match the actual edit that we make using the quick action
This commit is contained in:
Matt Bierner
2017-01-05 12:32:53 -08:00
committed by GitHub
parent 97ba3fddce
commit 5cf85c73d5

View File

@@ -5,7 +5,7 @@
'use strict';
import { CodeActionProvider, TextDocument, Range, CancellationToken, CodeActionContext, Command, commands, Uri, workspace, WorkspaceEdit, TextEdit } from 'vscode';
import { CodeActionProvider, TextDocument, Range, CancellationToken, CodeActionContext, Command, commands, Uri, workspace, WorkspaceEdit, TextEdit, Position } from 'vscode';
import * as Proto from '../protocol';
import { ITypescriptServiceClient } from '../typescriptService';
@@ -101,9 +101,27 @@ export default class TypeScriptCodeActionProvider implements CodeActionProvider
if (!success) {
return Promise.reject<boolean>(false);
}
let firstEdit: TextEdit | null = null;
for (const [uri, edits] of workspaceEdit.entries()) {
if (uri.fsPath === source.uri.fsPath) {
firstEdit = edits[0];
break;
}
}
if (!firstEdit) {
return true;
}
const newLines = firstEdit.newText.match(/\n/g);
const editedRange = new Range(
new Position(firstEdit.range.start.line, 0),
new Position(firstEdit.range.end.line + 1 + (newLines ? newLines.length : 0), 0));
// TODO: Workaround for https://github.com/Microsoft/TypeScript/issues/12249
// apply formatting to the source range until TS returns formatted results
return commands.executeCommand('vscode.executeFormatRangeProvider', source.uri, source.range, {}).then((edits: TextEdit[]) => {
return commands.executeCommand('vscode.executeFormatRangeProvider', source.uri, editedRange, {}).then((edits: TextEdit[]) => {
if (!edits || !edits.length) {
return false;
}