Skip to content

Commit

Permalink
Add CodeActions provider to suppress typechecker errors via HH_FIXME …
Browse files Browse the repository at this point in the history
…comment.
  • Loading branch information
PranayAgarwal committed Apr 7, 2017
1 parent 2964104 commit 65912d8
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 2 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ It is published in the Visual Studio Marketplace [here](https://marketplace.visu

## Releases

### v0.5.0
- Added Code Actions to automatically suppress typechecker errors via HH_FIXME comments.

### v0.4.0
- Fixed document symbol outline (⇧⌘O) break in newer hh_client versions.
- Added a new setting to enable type coverage checking (now off by default).
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vscode-hack",
"version": "0.4.0",
"version": "0.5.0",
"publisher": "pranayagarwal",
"engines": {
"vscode": "^1.5.0"
Expand Down
5 changes: 5 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as vscode from 'vscode';
import { HackCoverageChecker } from './coveragechecker';
import * as providers from './providers';
import * as hh_client from './proxy';
import * as suppressions from './suppressions';
import { HackTypeChecker } from './typechecker';

export async function activate(context: vscode.ExtensionContext) {
Expand Down Expand Up @@ -35,6 +36,10 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.languages.registerDocumentFormattingEditProvider(HACK_MODE, new providers.HackDocumentFormattingEditProvider()));
context.subscriptions.push(vscode.languages.registerReferenceProvider(HACK_MODE, new providers.HackReferenceProvider()));
context.subscriptions.push(vscode.languages.registerDefinitionProvider(HACK_MODE, new providers.HackDefinitionProvider()));
context.subscriptions.push(vscode.languages.registerCodeActionsProvider(HACK_MODE, new providers.HackCodeActionProvider()));

// add command to add an error suppression comment
context.subscriptions.push(vscode.commands.registerCommand('hack.suppressError', suppressions.suppressError));

// create typechecker and run when workspace is first loaded and on every file save
const hhvmTypeDiag: vscode.DiagnosticCollection = vscode.languages.createDiagnosticCollection('hack_typecheck');
Expand Down
27 changes: 27 additions & 0 deletions src/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,30 @@ export class HackDefinitionProvider implements vscode.DefinitionProvider {
return definition;
}
}

export class HackCodeActionProvider implements vscode.CodeActionProvider {
public async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken):
Promise<vscode.Command[]> {
const filteredErrors = context.diagnostics.filter(d => d.source === 'Hack' && d.code !== 0);
if (filteredErrors.length === 0) {
return;
}
const commands = [];
for (const error of filteredErrors) {
commands.push({
title: 'Suppress: ' + error.code,
command: 'hack.suppressError',
arguments: [document, error.range.start.line, [ error.code ]]
});
}
if (commands.length > 1) {
const allCodes = filteredErrors.map(f => f.code);
commands.push({
title: 'Suppress All',
command: 'hack.suppressError',
arguments: [document, filteredErrors[0].range.start.line, allCodes]
});
}
return commands;
}
}
16 changes: 16 additions & 0 deletions src/suppressions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @file Function triggered from 'hack.suppressError' command to add a suppress error comment before the given line.
*/

import * as vscode from 'vscode';

export function suppressError(document: vscode.TextDocument, line: number, errorCodes: number[]) {
const edit = new vscode.WorkspaceEdit();
const fullLine = document.lineAt(line);
const prefixIndex = fullLine.firstNonWhitespaceCharacterIndex;
const prefix = fullLine.text.substr(0, prefixIndex);
errorCodes.forEach(code => {
edit.insert(document.uri, new vscode.Position(line, 0), prefix + '/* HH_FIXME[' + code + '] */\n');
});
return vscode.workspace.applyEdit(edit);
}
5 changes: 5 additions & 0 deletions src/typechecker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ export class HackTypeChecker {
const diagnosticMap: Map<string, vscode.Diagnostic[]> = new Map();
typecheckResult.errors.forEach(error => {
let fullMessage = '';
let code: number = 0;
error.message.forEach(messageUnit => {
if (code === 0) {
code = messageUnit.code;
}
fullMessage = fullMessage + messageUnit.descr + ' [' + messageUnit.code + ']' + '\n';
});
const diagnostic = new vscode.Diagnostic(
Expand All @@ -31,6 +35,7 @@ export class HackTypeChecker {
new vscode.Position(error.message[0].line - 1, error.message[0].end)),
fullMessage,
vscode.DiagnosticSeverity.Error);
diagnostic.code = code;
diagnostic.source = 'Hack';
const file = error.message[0].path;
if (diagnosticMap.has(file)) {
Expand Down
2 changes: 1 addition & 1 deletion tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"chai-vague-errors": true,
"class-name": true,
"comment-format": true,
"export-name": true,
"export-name": false,
"function-name": true,
"import-name": true,
"interface-name": true,
Expand Down

0 comments on commit 65912d8

Please sign in to comment.