'use strict' ; import { Uri , TextDocument , ExtensionContext , workspace , window , TextEditorRevealType } from 'vscode' ; import { instrumentOperationAsVsCodeCommand } from "vscode-extension-telemetry-wrapper" ; import { toLanguage , isAnyPddl } from './workspaceUtils' ; import { FileInfo } from 'pddl-workspace' ; import { PddlWorkspace } from 'pddl-workspace' ; import { DocumentPositionResolver } from 'pddl-workspace' ; import { CodeDocumentPositionResolver } from './CodeDocumentPositionResolver' ; import { utils } from 'pddl-workspace' ; import { DomainInfo } from 'pddl-workspace' ; import { showError , toRange , toURI , toUri } from '../utils' ; import { PddlConfiguration } from '../configuration/configuration' ; import { ProblemInfo } from 'pddl-workspace' ; export class CodePddlWorkspace { param pddlWorkspace param context param pddlConfiguration private constructor ( public readonly pddlWorkspace , private context ? , pddlConfiguration ? ) { if ( context ) { subscribeToWorkspace ( this , context , pddlConfiguration ) ; } } registerCommands ( ) { const revealActionCommand = instrumentOperationAsVsCodeCommand ( 'pddl.revealAction' , ( domainFileUri , actionName ) => { revealAction ( this . pddlWorkspace . getFileInfo ( toURI ( domainFileUri ) ) as DomainInfo , actionName ) . catch ( showError ) ; } ) ; if ( this . context ) { this . context . subscriptions . push ( revealActionCommand ) ; } return this ; } static getInstance ( pddlWorkspace , context , pddlConfiguration ) { return new CodePddlWorkspace ( pddlWorkspace , context , pddlConfiguration ) . registerCommands ( ) ; } static getInstanceForTestingOnly ( pddlWorkspace ) { return new CodePddlWorkspace ( pddlWorkspace ) ; } async upsertFile ( document , force = false ) { const language = toLanguage ( document ) ; if ( language === undefined ) { return undefined ; } return await this . pddlWorkspace . upsertFile ( toURI ( document . uri ) , language , document . version , document . getText ( ) , this . createPositionResolver ( document ) , force ) ; } async upsertAndParseFile ( document ) { const language = toLanguage ( document ) ; if ( language === undefined ) { return undefined ; } return this . pddlWorkspace . upsertAndParseFile ( toURI ( document . uri ) , language , document . version , document . getText ( ) , this . createPositionResolver ( document ) ) ; } getFileInfoByUri < T extends FileInfo > ( uri ) { return this . pddlWorkspace . getFileInfo ( toURI ( uri ) ) ; } getFileInfo < T extends FileInfo > ( document ) { return this . getFileInfoByUri ( document . uri ) ; } async removeFile ( textDoc ) { const fileExists = await utils . afs . exists ( textDoc . fileName ) ; return this . pddlWorkspace . removeFile ( toURI ( textDoc . uri ) , { removeAllReferences : ! fileExists } ) ; } getDomainFilesFor ( problemFileInfo ) { const domainFiles = this . pddlWorkspace . getDomainFilesFor ( problemFileInfo ) ; return domainFiles . filter ( domainInfo => this . isRealFile ( domainInfo ) ) ; } private static readonly GIT_SCHEME = "git" ; private isRealFile ( domainInfo ) { return domainInfo . fileUri . scheme !== CodePddlWorkspace . GIT_SCHEME ; } static isRealDocument ( document ) { return document . uri . scheme !== this . GIT_SCHEME ; } setEpsilon ( epsilon ) { this . pddlWorkspace . epsilon = epsilon ; } private createPositionResolver ( document ) { return new CodeDocumentPositionResolver ( document ) ; } } function subscribeToWorkspace ( pddlWorkspace , context , pddlConfiguration ? ) { workspace . textDocuments . filter ( textDoc => isAnyPddl ( textDoc ) ) . filter ( textDoc => CodePddlWorkspace . isRealDocument ( textDoc ) ) . forEach ( textDoc => { pddlWorkspace . upsertFile ( textDoc ) ; } ) ; context . subscriptions . push ( workspace . onDidOpenTextDocument ( textDoc => { if ( isAnyPddl ( textDoc ) && CodePddlWorkspace . isRealDocument ( textDoc ) ) { pddlWorkspace . upsertFile ( textDoc ) ; } } ) ) ; context . subscriptions . push ( workspace . onDidChangeTextDocument ( docEvent => { if ( isAnyPddl ( docEvent . document ) && CodePddlWorkspace . isRealDocument ( docEvent . document ) ) { pddlWorkspace . upsertFile ( docEvent . document ) ; } else { pddlWorkspace . pddlWorkspace . getAllFilesIf < ProblemInfo > ( f => f . isProblem ( ) ) . filter ( problemInfo => ! ! problemInfo . getPreParsingPreProcessor ( ) ) . filter ( problemInfo => problemInfo . getPreParsingPreProcessor ( ) ?. getInputFiles ( ) . some ( inputFile => docEvent . document . fileName . endsWith ( inputFile ) ) ) . forEach ( async ( problemInfo ) => { const problemFile = await workspace . openTextDocument ( toUri ( problemInfo . fileUri ) ) ; pddlWorkspace . upsertFile ( problemFile , true ) ; } ) ; } } ) ) ; context . subscriptions . push ( workspace . onDidDeleteFiles ( deletionEvent => { const deletionSuccesses = deletionEvent . files . map ( deletedUri => pddlWorkspace . pddlWorkspace . removeFile ( toURI ( deletedUri ) , { removeAllReferences : false } ) ) ; if ( deletionSuccesses . some ( s => ! s ) ) { console . error ( `Some files were not removed from the PDDL repository model` ) ; } } ) ) ; if ( pddlConfiguration ) { workspace . onDidChangeConfiguration ( ( ) => { pddlWorkspace . setEpsilon ( pddlConfiguration . getEpsilonTimeStep ( ) ) ; } ) ; } } async function revealAction ( domainInfo , actionName ) { const document = await workspace . openTextDocument ( toUri ( domainInfo . fileUri ) ) ; const actionFound = domainInfo . getActions ( ) . find ( a => a ?. name ?. toLowerCase ( ) === actionName . toLowerCase ( ) ) ; const actionRange = actionFound && toRange ( actionFound . getLocation ( ) ) ; const openEditor = window . visibleTextEditors . find ( e => e . document . uri . toString ( ) === document . uri . toString ( ) ) ; if ( openEditor && actionRange ) { openEditor . revealRange ( actionRange , TextEditorRevealType . AtTop ) ; } else { window . showTextDocument ( document . uri , { preserveFocus : true , selection : actionRange , preview : true } ) ; } }