All files / services/core workspace-file-operation-service.ts

100% Statements 15/15
100% Branches 0/0
100% Functions 6/6
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78                                    6x               6x 6x 6x   6x 1x 1x                         3x     3x     3x     3x                 2x             7x 12x     7x      
import * as vscode from 'vscode';
import { IDocumentConnectionService } from '@src/languages/sparql/services';
import { ShaclValidationService } from '@src/services/validation/shacl-validation-service';
import { ReferenceUpdateService } from './reference-update-service';
 
/**
 * A file or folder rename reported by `vscode.workspace.onDidRenameFiles`.
 */
type FileRename = { readonly oldUri: vscode.Uri; readonly newUri: vscode.Uri };
 
/**
 * Service that keeps per-document settings and `workspace:` URI references in sync with
 * files and folders that are renamed or deleted in VS Code.
 */
export class WorkspaceFileOperationService implements vscode.Disposable {
	/**
	 * The subscriptions to the workspace file operation events.
	 */
	private readonly _subscriptions: vscode.Disposable[] = [];
 
	/**
	 * @param _referenceUpdateService Updates the `workspace:` URI references of indexed documents.
	 * @param _documentConnectionService Stores the SPARQL connection settings of documents.
	 * @param _shaclValidationService Stores the SHACL validation settings of documents.
	 */
	constructor(
		private readonly _referenceUpdateService: ReferenceUpdateService,
		private readonly _documentConnectionService: IDocumentConnectionService,
		private readonly _shaclValidationService: ShaclValidationService
	) {
		this._subscriptions.push(
			vscode.workspace.onDidRenameFiles(e => this.handleRenames(e.files)),
			vscode.workspace.onDidDeleteFiles(e => this.handleDeletes(e.files))
		);
	}
 
	/**
	 * Migrates the per-document settings of renamed files and updates the `workspace:` URI
	 * references to them in the indexed documents.
	 * @param renames The renamed files and folders.
	 */
	async handleRenames(renames: ReadonlyArray<FileRename>): Promise<void> {
		// Compute the reference changes first: they are derived from the indexed
		// contexts of the old files, which the workspace index removes once it has
		// processed the rename.
		const changes = this._referenceUpdateService.buildChangesForRenames(renames);
 
		// Migrate SPARQL workspaceState keys (document connection + inference settings).
		await this._documentConnectionService.handleFileRenames(renames);
 
		// Migrate SHACL workspace settings (profile shapes and document assignments).
		await this._shaclValidationService.settingsSync.migrateShaclSettings(renames);
 
		// Update all workspace: URI references across indexed documents.
		await this._referenceUpdateService.batchUpdate(changes);
	}
 
	/**
	 * Prunes the SHACL assignments of deleted documents and warns about validation
	 * profiles that still reference deleted shape files.
	 * @param files The deleted files and folders.
	 */
	async handleDeletes(files: ReadonlyArray<vscode.Uri>): Promise<void> {
		await this._shaclValidationService.settingsSync.handleFileDeletes(files);
	}
 
	/**
	 * Unsubscribes from the workspace file operation events.
	 */
	dispose(): void {
		for (const subscription of this._subscriptions) {
			subscription.dispose();
		}
 
		this._subscriptions.length = 0;
	}
}