import { createConnection , TextDocuments , Diagnostic , ProposedFeatures , InitializeParams , TextDocumentPositionParams , CompletionItem , TextDocumentSyncKind } from 'vscode-languageserver/node' ; import { TextDocument } from 'vscode-languageserver-textdocument' ; import { SystemVerilogCompiler , compilerType } from './compiling/SystemVerilogCompiler' ; import { ANTLRBackend } from './compiling/ANTLRBackend' ; const connection = createConnection ( ProposedFeatures . all ) ; const documents = new TextDocuments ( TextDocument ) ; let documentCompiler ; const configurations = new Map ( ) ; const compilerConfigurationsKeys = [ 'systemverilog.compilerType' , 'systemverilog.compileOnSave' , 'systemverilog.launchConfigurationVerilator' , 'systemverilog.launchConfigurationVCS' , 'systemverilog.launchConfigurationVerible' , 'systemverilog.antlrVerification' , 'systemverilog.verifyOnOpen' , 'systemverilog.excludeCompiling' ] ; const backend = new ANTLRBackend ( ) ; connection . onInitialize ( ( _params ) => ( { capabilities : { textDocumentSync : TextDocumentSyncKind . Incremental } } ) ) ; connection . onInitialized ( async ( ) => { await updateConfigurationsSettings ( ) ; } ) ; param _textDocumentPosition connection . onCompletion ( ( _textDocumentPosition ) : CompletionItem [ ] => [ ] ) ; param item connection . onCompletionResolve ( ( item ) : CompletionItem => item ) ; connection . onNotification ( 'workspaceRootPath' , ( rootPath ) => { documentCompiler = new SystemVerilogCompiler ( connection , documents , rootPath , configurations , compilerConfigurationsKeys ) ; } ) ; connection . onNotification ( 'onDidChangeConfiguration' , async ( ) => { await updateConfigurationsSettings ( ) ; } ) ; /**
 * Updates `configurations` map with the most recent value of the settings
 */ function updateConfigurationsSettings ( ) { return Promise . all ( compilerConfigurationsKeys . map ( async ( configuration ) => { await connection . workspace . getConfiguration ( { section : configuration } ) . then ( ( value ) => { configurations . set ( configuration , value ) ; } ) ; } ) ) ; } param saveEvent documents . onDidSave ( ( saveEvent ) => { if ( configurations . get ( compilerConfigurationsKeys [ 1 ] ) ) { let doCompile = true ; if ( configurations . get ( compilerConfigurationsKeys [ 7 ] ) ) { var globToRegExp = require ( 'glob-to-regexp' ) ; var re = globToRegExp ( configurations . get ( compilerConfigurationsKeys [ 7 ] ) ) ; if ( re . test ( saveEvent . document . uri ) ) { doCompile = false ; } } if ( doCompile ) { compile ( saveEvent . document ) . catch ( ( error ) => { connection . window . showErrorMessage ( error ) ; } ) ; } } } ) ; param uri function verifyDocument ( uri ) { if ( configurations . get ( compilerConfigurationsKeys [ 5 ] ) ) { backend . getDiagnostics ( documents . get ( uri ) ) . then ( ( diagnosticCollection ) => { for ( const [ uri , diagnostics ] of diagnosticCollection . entries ( ) ) { connection . sendDiagnostics ( { uri , diagnostics } ) ; } } ) . catch ( ( error ) => { connection . window . showErrorMessage ( error ) ; } ) ; } } param openEvent documents . onDidOpen ( async ( openEvent ) => { await new Promise ( ( resolve ) => setTimeout ( resolve , 200 ) ) ; if ( configurations . get ( compilerConfigurationsKeys [ 6 ] ) ) { verifyDocument ( openEvent . document . uri ) ; } } ) ; param changeEvent documents . onDidChangeContent ( async ( changeEvent ) => { verifyDocument ( changeEvent . document . uri ) ; } ) ; connection . onNotification ( 'compileOpenedDocument' , ( uri ) => { compile ( documents . get ( uri ) ) . then ( ( ) => { connection . sendNotification ( 'closeWindowProgress' ) ; } ) . catch ( ( error ) => { connection . window . showErrorMessage ( error ) ; } ) ; } ) ; param document async function compile ( document ) { if ( ! documentCompiler ) { return ; } connection . sendDiagnostics ( { uri : document . uri , diagnostics : [ ] } ) ; const type = < compilerType > compilerType [ < string > configurations . get ( compilerConfigurationsKeys [ 0 ] ) ] ; documentCompiler . validateTextDocument ( document , type ) . then ( ( diagnosticCollection ) => { for ( const [ uri , diagnostics ] of diagnosticCollection . entries ( ) ) { connection . sendDiagnostics ( { uri , diagnostics } ) ; } } ) . catch ( ( error ) => { connection . window . showErrorMessage ( error ) ; } ) ; } documents . listen ( connection ) ; connection . listen ( ) ;