All files / languages/turtle/providers turtle-rename-provider.ts

100% Statements 54/54
96.87% Branches 31/32
100% Functions 4/4
100% Lines 47/47

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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112                            1x       5x   5x 2x     3x   3x 1x     2x 1x   1x         11x 11x   11x 1x     10x   10x 1x     9x 2x 2x   2x 3x   3x     3x   3x 3x   3x   2x     2x         2x 1x   7x 3x 3x   3x   2x     5x   5x   4x   4x   3x 3x   3x   2x   2x   1x       7x    
import * as vscode from 'vscode';
import { container } from 'tsyringe';
import { ServiceToken } from '@src/services/tokens';
import { IDocumentContextService } from '@src/services/document';
import { RdfToken, isVariableToken } from '@faubulous/mentor-rdf-parsers';
import { getIriFromToken } from '@src/utilities';
import { TurtleDocument } from '@src/languages/turtle/turtle-document';
import { TurtleFeatureProvider } from '@src/languages/turtle/turtle-feature-provider';
 
/**
 * Provides renaming for URIs, resources labels and prefixes.
 */
export class TurtleRenameProvider extends TurtleFeatureProvider implements vscode.RenameProvider {
	private get contextService() {
		return container.resolve<IDocumentContextService>(ServiceToken.DocumentContextService);
	}
 
	public async prepareRename(document: vscode.TextDocument, position: vscode.Position): Promise<vscode.Range | null> {
		const context = this.contextService.getDocumentContext(document, TurtleDocument);
 
		if (!context) {
			return null;
		}
 
		const token = context.getTokenAtPosition(position);
 
		if (!token) {
			throw new Error('No token found at the given position.');
		}
 
		if (context.isPrefixTokenAtPosition(token, position)) {
			return this.getPrefixEditRange(token);
		} else {
			return this.getLabelEditRange(token);
		}
	}
 
	public provideRenameEdits(document: vscode.TextDocument, position: vscode.Position, newName: string): vscode.ProviderResult<vscode.WorkspaceEdit> {
		const edits = new vscode.WorkspaceEdit();
		const context = this.contextService.getDocumentContext(document, TurtleDocument);
 
		if (!context) {
			return edits;
		}
 
		const token = context.getTokenAtPosition(position);
 
		if (!token) {
			return edits;
		}
 
		if (context.isPrefixTokenAtPosition(token, position)) {
			const i = token.image.indexOf(":");
			const prefix = token.image.substring(0, i);
 
			for (const t of context.tokens) {
				const tokenType = t.tokenType.name;
 
				switch (tokenType) {
					case RdfToken.PNAME_NS.name:
					case RdfToken.PNAME_LN.name: {
						const p = t.image.split(":")[0];
 
						Eif (p === prefix) {
							const r = this.getPrefixEditRange(t);
 
							if (!r) continue;
 
							edits.replace(document.uri, r, newName);
						}
 
						break;
					}
				}
			}
 
			if (edits.size > 0) {
				context.updateNamespacePrefix(prefix, newName);
			}
		} else if (isVariableToken(token)) {
			for (const t of context.tokens.filter(t => t.image === token.image)) {
				const r = this.getLabelEditRange(t);
 
				if (!r) continue;
 
				edits.replace(document.uri, r, newName);
			}
		} else {
			const u = getIriFromToken(context.namespaces, token);
 
			if (!u) return edits;
 
			const references = context.references[u];
 
			if (!references) return edits;
 
			for (let range of references) {
				const token = context.getTokenAtPosition(range.start);
 
				if (!token) continue;
 
				const editRange = this.getLabelEditRange(token);
 
				if (!editRange) continue;
 
				edits.replace(document.uri, editRange, newName);
			}
		}
 
		return edits;
	}
}