// SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers // // SPDX-License-Identifier: MPL-2.0 import LanguageServerProtocol import PterodactylBuild import TSCBasic import llbuild2fx actor SourceTreeManager { private let buildEngine: FXEngine private let casClient: LLBCASFSClient private let casContext: TSCUtility.Context private(set) var sourceTree: LLBCASFileTree init(buildEngine: FXEngine, casClient: LLBCASFSClient, casContext: TSCUtility.Context, sourceTree: LLBCASFileTree? = nil) async throws { self.buildEngine = buildEngine self.casClient = casClient self.casContext = casContext if let sourceTree { self.sourceTree = sourceTree } else { self.sourceTree = try await casClient.storeDir(.dir([:]), casContext).get() } } func setBufferText(uri: DocumentUri, text: String) async throws { let path = try AbsolutePath.fromDocumentUri(uri) let singletonDeclTree = LLBDeclFileTree.file(absolutePath: path, contents: text) let singletonTree: LLBCASFileTree = try await casClient.storeDir(singletonDeclTree, casContext).get() self.sourceTree = try await sourceTree.merge(with: singletonTree, in: casClient.db, casContext).get() } func getBufferText(uri: DocumentUri) async throws -> String? { let path = try AbsolutePath.fromDocumentUri(uri) guard let (id, _) = try await sourceTree.lookup(path: path, in: casClient.db, casContext).get() else { return nil } return try await buildEngine.build(key: Keys.Blob.ReadContents(blobId: id), casContext).get() } }