import * as Is from '../common/utils/is' ; import { Connection , _ , _Connection , Features , WatchDog , createConnection as createCommonConnection } from '../common/server' ; import * as fm from './files' ; import { ConnectionStrategy , ConnectionOptions , MessageReader , MessageWriter , IPCMessageReader , IPCMessageWriter , createServerPipeTransport , createServerSocketTransport , InitializeParams , createProtocolConnection , Logger , ProtocolConnection } from 'vscode-languageserver-protocol/node' ; export * from 'vscode-languageserver-protocol/node' ; export * from '../common/api' ; export namespace Files { export let uriToFilePath = fm . uriToFilePath ; export let resolveGlobalNodePath = fm . resolveGlobalNodePath ; export let resolveGlobalYarnPath = fm . resolveGlobalYarnPath ; export let resolve = fm . resolve ; export let resolveModulePath = fm . resolveModulePath ; } let _protocolConnection ; function endProtocolConnection ( ) { if ( _protocolConnection === undefined ) { return ; } try { _protocolConnection . end ( ) ; } catch ( _err ) { } } let _shutdownReceived = false ; let exitTimer = undefined ; function setupExitTimer ( ) { const argName = '--clientProcessId' ; function runTimer ( value ) { try { let processId = parseInt ( value ) ; if ( ! isNaN ( processId ) ) { exitTimer = setInterval ( ( ) => { try { process . kill ( processId , < any > 0 ) ; } catch ( ex ) { endProtocolConnection ( ) ; process . exit ( _shutdownReceived ? 0 : 1 ) ; } } , 3000 ) ; } } catch ( e ) { } } for ( let i = 2 ; i < process . argv . length ; i ++ ) { let arg = process . argv [ i ] ; if ( arg === argName && i + 1 < process . argv . length ) { runTimer ( process . argv [ i + 1 ] ) ; return ; } else { let args = arg . split ( '=' ) ; if ( args [ 0 ] === argName ) { runTimer ( args [ 1 ] ) ; } } } } setupExitTimer ( ) ; const watchDog = { initialize : ( params ) : void => { const processId = params . processId ; if ( Is . number ( processId ) && exitTimer === undefined ) { setInterval ( ( ) => { try { process . kill ( processId , < any > 0 ) ; } catch ( ex ) { process . exit ( _shutdownReceived ? 0 : 1 ) ; } } , 3000 ) ; } } , get shutdownReceived ( ) : boolean { return _shutdownReceived ; } , set shutdownReceived ( value ) { _shutdownReceived = value ; } , exit : ( code ) : void => { endProtocolConnection ( ) ; process . exit ( code ) ; } } ; param options export function createConnection ( options ? ) ; param inputStream param outputStream param options return export function createConnection ( inputStream , outputStream , options ? ) ; param reader param writer param options export function createConnection ( reader , writer , options ? ) ; param factories param options export function createConnection < PConsole = _ , PTracer = _ , PTelemetry = _ , PClient = _ , PWindow = _ , PWorkspace = _ , PLanguages = _ > ( factories , options ? ) ; param inputStream param outputStream param options return export function createConnection < PConsole = _ , PTracer = _ , PTelemetry = _ , PClient = _ , PWindow = _ , PWorkspace = _ , PLanguages = _ > ( factories , inputStream , outputStream , options ? ) ; param reader param writer param options export function createConnection < PConsole = _ , PTracer = _ , PTelemetry = _ , PClient = _ , PWindow = _ , PWorkspace = _ , PLanguages = _ > ( factories , reader , writer , options ? ) ; export function createConnection ( arg1 ? , arg2 ? , arg3 ? , arg4 ? ) { let factories ; let input ; let output ; let options ; if ( arg1 !== void 0 && ( arg1 as Features ) . __brand === 'features' ) { factories = arg1 ; arg1 = arg2 ; arg2 = arg3 ; arg3 = arg4 ; } if ( ConnectionStrategy . is ( arg1 ) || ConnectionOptions . is ( arg1 ) ) { options = arg1 ; } else { input = arg1 ; output = arg2 ; options = arg3 ; } return _createConnection ( input , output , options , factories ) ; } function _createConnection < PConsole = _ , PTracer = _ , PTelemetry = _ , PClient = _ , PWindow = _ , PWorkspace = _ , PLanguages = _ > ( input ? , output ? , options ? , factories ? ) { if ( ! input && ! output && process . argv . length > 2 ) { let port = void 0 ; let pipeName = void 0 ; let argv = process . argv . slice ( 2 ) ; for ( let i = 0 ; i < argv . length ; i ++ ) { let arg = argv [ i ] ; if ( arg === '--node-ipc' ) { input = new IPCMessageReader ( process ) ; output = new IPCMessageWriter ( process ) ; break ; } else if ( arg === '--stdio' ) { input = process . stdin ; output = process . stdout ; break ; } else if ( arg === '--socket' ) { port = parseInt ( argv [ i + 1 ] ) ; break ; } else if ( arg === '--pipe' ) { pipeName = argv [ i + 1 ] ; break ; } else { var args = arg . split ( '=' ) ; if ( args [ 0 ] === '--socket' ) { port = parseInt ( args [ 1 ] ) ; break ; } else if ( args [ 0 ] === '--pipe' ) { pipeName = args [ 1 ] ; break ; } } } if ( port ) { let transport = createServerSocketTransport ( port ) ; input = transport [ 0 ] ; output = transport [ 1 ] ; } else if ( pipeName ) { let transport = createServerPipeTransport ( pipeName ) ; input = transport [ 0 ] ; output = transport [ 1 ] ; } } var commandLineMessage = 'Use arguments of createConnection or set command line parameters: \'--node-ipc\', \'--stdio\' or \'--socket={number}\'' ; if ( ! input ) { throw new Error ( 'Connection input stream is not set. ' + commandLineMessage ) ; } if ( ! output ) { throw new Error ( 'Connection output stream is not set. ' + commandLineMessage ) ; } if ( Is . func ( ( input as NodeJS . ReadableStream ) . read ) && Is . func ( ( input as NodeJS . ReadableStream ) . on ) ) { let inputStream = < NodeJS . ReadableStream > input ; inputStream . on ( 'end' , ( ) => { endProtocolConnection ( ) ; process . exit ( _shutdownReceived ? 0 : 1 ) ; } ) ; inputStream . on ( 'close' , ( ) => { endProtocolConnection ( ) ; process . exit ( _shutdownReceived ? 0 : 1 ) ; } ) ; } const connectionFactory = ( logger ) : ProtocolConnection => { const result = createProtocolConnection ( input as any , output as any , logger , options ) ; return result ; } ; return createCommonConnection ( connectionFactory , watchDog , factories ) ; }