file import * as vscode from "vscode" ; import * as providers from "./providers" ; import * as hh_client from "./proxy" ; import * as utils from "./Utils" ; export class LegacyHackTypeChecker { private hhvmTypeDiag : vscode . DiagnosticCollection ; constructor ( context ) { const HACK_MODE = { language : "hack" , scheme : "file" } ; context . subscriptions . push ( vscode . languages . registerHoverProvider ( HACK_MODE , new providers . HackHoverProvider ( ) ) ) ; context . subscriptions . push ( vscode . languages . registerDocumentSymbolProvider ( HACK_MODE , new providers . HackDocumentSymbolProvider ( ) ) ) ; context . subscriptions . push ( vscode . languages . registerWorkspaceSymbolProvider ( new providers . HackWorkspaceSymbolProvider ( ) ) ) ; context . subscriptions . push ( vscode . languages . registerDocumentHighlightProvider ( HACK_MODE , new providers . HackDocumentHighlightProvider ( ) ) ) ; context . subscriptions . push ( vscode . languages . registerCompletionItemProvider ( HACK_MODE , new providers . HackCompletionItemProvider ( ) , "$" , ">" , ":" , "\\" ) ) ; 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 ( ) ) ) ; const hhvmTypeDiag = vscode . languages . createDiagnosticCollection ( "hack_typecheck" ) ; this . hhvmTypeDiag = hhvmTypeDiag ; context . subscriptions . push ( vscode . workspace . onDidSaveTextDocument ( ( ) => { this . run ( ) ; } ) ) ; context . subscriptions . push ( hhvmTypeDiag ) ; } public async run ( ) { const typecheckResult = await hh_client . check ( ) ; this . hhvmTypeDiag . clear ( ) ; if ( ! typecheckResult || typecheckResult . passed ) { return ; } const diagnosticMap = new Map ( ) ; typecheckResult . errors . forEach ( error => { const diagnostic = new vscode . Diagnostic ( new vscode . Range ( new vscode . Position ( error . message [ 0 ] . line - 1 , error . message [ 0 ] . start - 1 ) , new vscode . Position ( error . message [ 0 ] . line - 1 , error . message [ 0 ] . end ) ) , `${ error . message [ 0 ] . descr } [${ error . message [ 0 ] . code }]` , vscode . DiagnosticSeverity . Error ) ; diagnostic . code = error . message [ 0 ] . code ; diagnostic . source = "Hack" ; const relatedInformation = [ ] ; for ( let i = 1 ; i < error . message . length ; i ++ ) { relatedInformation . push ( new vscode . DiagnosticRelatedInformation ( new vscode . Location ( utils . mapToWorkspaceUri ( error . message [ i ] . path ) , new vscode . Range ( new vscode . Position ( error . message [ i ] . line - 1 , error . message [ i ] . start - 1 ) , new vscode . Position ( error . message [ i ] . line - 1 , error . message [ i ] . end ) ) ) , error . message [ i ] . descr ) ) ; } diagnostic . relatedInformation = relatedInformation ; const file = utils . mapToWorkspaceUri ( error . message [ 0 ] . path ) ; const cachedFileDiagnostics = diagnosticMap . get ( file ) ; if ( cachedFileDiagnostics ) { cachedFileDiagnostics . push ( diagnostic ) ; } else { diagnosticMap . set ( file , [ diagnostic ] ) ; } } ) ; diagnosticMap . forEach ( ( diags , file ) => { this . hhvmTypeDiag . set ( file , diags ) ; } ) ; } }