file import * as vscode from "vscode" ; import { HandleDiagnosticsSignature , LanguageClient , RevealOutputChannelOn , LanguageClientOptions , ServerOptions } from "vscode-languageclient" ; import * as config from "./Config" ; import { HackCoverageChecker } from "./coveragechecker" ; import * as remote from "./remote" ; import * as hack from "./types/hack" ; import * as utils from "./Utils" ; import { ShowStatusRequest } from "./types/lsp" ; export class LSPHackTypeChecker { private context : vscode . ExtensionContext ; private versionText : string ; private status : vscode . StatusBarItem ; constructor ( context , version ) { this . context = context ; this . versionText = this . getVersionText ( version ) ; this . status = vscode . window . createStatusBarItem ( vscode . StatusBarAlignment . Left ) ; context . subscriptions . push ( this . status ) ; } public static IS_SUPPORTED ( version ) { return version . api_version >= 5 ; } public async run ( ) { const context = this . context ; const serverOptions = { command : remote . getCommand ( config . clientPath ) , args : remote . getArgs ( config . clientPath , [ "lsp" , "--from" , "vscode-hack" ] ) } ; const clientOptions = { documentSelector : [ { language : "hack" , scheme : "file" } ] , initializationOptions : { useTextEditAutocomplete : true } , uriConverters : { code2Protocol : utils . mapFromWorkspaceUri , protocol2Code : utils . mapToWorkspaceUri } , middleware : { handleDiagnostics : this . handleDiagnostics } , revealOutputChannelOn : RevealOutputChannelOn . Never } ; const languageClient = new LanguageClient ( "hack" , "Hack Language Server" , serverOptions , clientOptions ) ; languageClient . onReady ( ) . then ( async ( ) => { languageClient . onRequest ( "window/showStatus" , ( params ) => { if ( params . shortMessage ) { this . status . text = this . versionText + " " + params . shortMessage ; } else { this . status . text = this . versionText ; } this . status . tooltip = params . message || "" ; if ( params . type === 1 || params . type === 2 ) { this . status . text = "$(alert) " + this . status . text ; } this . status . show ( ) ; return { } ; } ) ; if ( config . enableCoverageCheck && languageClient . initializeResult && ( < any > languageClient . initializeResult . capabilities ) . typeCoverageProvider ) { await new HackCoverageChecker ( languageClient ) . start ( context ) ; } } ) ; context . subscriptions . push ( languageClient . start ( ) ) ; } private handleDiagnostics ( uri , diagnostics , next ) { next ( uri , diagnostics . map ( d => { let kind ; switch ( Math . floor ( < number > d . code / 1000 ) ) { case 1 : kind = "Parsing" ; break ; case 2 : kind = "Naming" ; break ; case 3 : kind = "NastCheck" ; break ; case 4 : kind = "Typing" ; break ; case 5 : kind = "Lint" ; break ; case 8 : kind = "Init" ; break ; default : kind = "Other" ; } d . message = `${ kind }[${ d . code }] ${ d . message }` ; return d ; } ) ) ; } private getVersionText ( version ) { const hhvmVersion = version . commit . split ( "-" ) . pop ( ) ; let statusText = hhvmVersion ? `HHVM ${ hhvmVersion }` : "HHVM" ; if ( config . remoteEnabled && config . remoteType === "ssh" ) { statusText += " (Remote)" ; } else if ( config . remoteEnabled && config . remoteType === "docker" ) { statusText += " (Docker)" ; } return statusText ; } }