module author Paolo Masci
 *  date copyright import { spawn , ChildProcess } from 'child_process' ; import * as fsUtils from '../../../common/fsUtils' ; import { Diagnostic } from 'vscode-languageserver' ; import * as path from 'path' ; export declare interface ParserDiagnostics extends Diagnostic { fileName : string ; fileExtension : string ; contextFolder : string ; "math-objects" : { types : number ; definitions : number ; lemmas : number ; } ; "parse-time" : { ms : number ; } ; "errors" ? : Diagnostic [ ] ; } ; export declare interface Outline { contextFolder : string ; fileName : string ; fileExtension : string ; outline : { types : [ { line : number ; character : number ; identifier : string ; } ] ; functions : [ { line : number ; character : number ; identifier : string ; } ] ; formulas : [ { line : number ; character : number ; identifier : string ; } ] ; locals : [ { line : number ; character : number ; identifier : string ; } ] ; } ; "parse-time" : { ms : number ; } ; } export class PvsParser { protected workers : { [ fname ] : ChildProcess ; } = { } ; protected processWorker ( fname , args ) { return new Promise ( ( resolve , reject ) => { const worker = spawn ( "java" , args . concat ( fname ) ) ; this . workers [ fname ] = worker ; worker . stdout . setEncoding ( "utf8" ) ; worker . stderr . setEncoding ( "utf8" ) ; worker . stdout . on ( "data" , ( diags ) => { resolve ( diags ) ; } ) ; worker . stderr . on ( "data" , ( data ) => { console . error ( data ) ; } ) ; worker . on ( "error" , ( err ) => { console . log ( "[pvs-parser] Process error " , err ) ; } ) ; worker . on ( "exit" , ( code , signal ) => { resolve ( null ) ; } ) ; worker . on ( "message" , ( message ) => { console . log ( "[pvs-parser] Process message" , message ) ; } ) ; } ) ; } stop ( ) { if ( this . workers ) { const keys = Object . keys ( this . workers ) ; for ( let key in keys ) { this . workers [ key ] . kill ( ) ; } } } async parseExpression ( expr ) { return null ; } param desc async parseFile ( desc ) { const fname = fsUtils . desc2fname ( desc ) ; console . info ( `[vscode-pvs-parser] Parsing ${ fname }` ) ; let diags = null ; const libFolder = path . join ( __dirname , "../../../../out/core/lib" ) ; const args = [ "-jar" , `${ libFolder }/PvsParser.jar` ] ; try { const ans = await this . processWorker ( fname , args ) ; if ( ans ) { console . log ( ans ) ; diags = JSON . parse ( ans ) ; if ( diags . errors ) { console . log ( `[vscode-pvs-parser] File ${ desc . fileName }${ desc . fileExtension } parsed with errors in ${ diags [ "parse-time" ] . ms }ms` ) ; } else { console . log ( `[vscode-pvs-parser] File ${ desc . fileName }${ desc . fileExtension } parsed successfully in ${ diags [ "parse-time" ] . ms }ms` ) ; } } } catch ( parserError ) { console . log ( parserError ) ; } finally { return diags ; } } param desc async getStats ( desc ) { const fname = fsUtils . desc2fname ( desc ) ; console . info ( `[vscode-pvs-parser] Parsing ${ fname }` ) ; let diagnostics = [ ] ; const libFolder = path . join ( __dirname , "../../../../out/core/lib" ) ; const start = Date . now ( ) ; const options = "-stats" ; const args = [ "-jar" , `${ libFolder }/PvsParser.jar` , options ] ; try { const diags = await this . processWorker ( fname , args ) ; const stats = Date . now ( ) - start ; if ( diags ) { console . log ( diags ) ; diagnostics = JSON . parse ( diags ) ; console . log ( `[vscode-pvs-parser] File ${ desc . fileName }${ desc . fileExtension } parsed with errors in ${ stats }ms` ) ; } else { console . log ( `[vscode-pvs-parser] File ${ desc . fileName }${ desc . fileExtension } parsed successfully in ${ stats }ms` ) ; } } catch ( parserError ) { console . log ( parserError ) ; } finally { return diagnostics ; } } param desc async getOutline ( desc ) { const fname = fsUtils . desc2fname ( desc ) ; console . info ( `[vscode-pvs-parser] Building outline for ${ fname }` ) ; let res = null ; const libFolder = path . join ( __dirname , "../../../../out/core/lib" ) ; const start = Date . now ( ) ; const options = "-outline" ; const args = [ "-jar" , `${ libFolder }/PvsParser.jar` , options ] ; try { const outline = await this . processWorker ( fname , args ) ; const stats = Date . now ( ) - start ; if ( outline ) { console . log ( outline ) ; res = JSON . parse ( outline ) ; console . log ( `[vscode-pvs-parser] File ${ desc . fileName }${ desc . fileExtension } parsed with errors in ${ stats }ms` ) ; } else { console . log ( `[vscode-pvs-parser] File ${ desc . fileName }${ desc . fileExtension } parsed successfully in ${ stats }ms` ) ; } } catch ( parserError ) { console . log ( parserError ) ; } finally { return res ; } } }