All files / languages/turtle turtle-token-provider.ts

100% Statements 30/30
100% Branches 0/0
100% Functions 4/4
100% Lines 29/29

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 113 114 115 116 117 118 119 120                                                                                                      9x 9x 9x 9x 9x 9x 9x 9x 9x   9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x     9x   9x 9x 9x   9x 33x                       13x       34x                                          
import * as vscode from 'vscode';
import { container } from 'tsyringe';
import { VocabularyRepository } from '@faubulous/mentor-rdf';
import { ServiceToken } from '@src/services/tokens';
import { IDocumentContextService } from '@src/services/document';
import { IPrefixLookupService, IPresetDocumentService } from '@src/services/document';
import { IWorkspaceIndexerService, IWorkspaceRenameService } from '@src/services/core';
import { ShaclValidationService } from '@src/services/validation/shacl-validation-service';
import { ISparqlConnectionRegistry, IDocumentConnectionService } from '@src/languages/sparql/services';
import {
	ResourceReferenceProvider,
	ResourceDefinitionProvider,
	WorkspaceGraphDefinitionProvider,
	NotebookCellSlugCodeLensProvider
} from '@src/providers';
import {
	TurtleAutoDefinePrefixProvider,
	TurtleCodeActionsProvider,
	TurtleUsageCodeLensProvider,
	TurtleCompletionItemProvider,
	TurtlePrefixCompletionProvider,
	TurtleRenameProvider,
	TurtleCodeFormattingProvider,
	TurtleValidationCodeLensProvider,
	TurtleConnectionCodeLensProvider
} from '@src/languages/turtle/providers';
import {
	TurtlePrefixDefinitionService
} from '@src/languages/turtle/services/turtle-prefix-definition-service';
 
/**
 * Registers the language feature providers for the Turtle language family.
 *
 * This is a composition point: services are resolved from the container once
 * and passed into the provider constructors.
 */
export class TurtleTokenProvider {
	private readonly _codeActionsProvider: TurtleCodeActionsProvider;
	private readonly _codelensProvider: TurtleUsageCodeLensProvider;
	private readonly _completionProvider: TurtleCompletionItemProvider;
	private readonly _definitionProvider: ResourceDefinitionProvider;
	private readonly _notebookSlugCodelensProvider: NotebookCellSlugCodeLensProvider;
	private readonly _workspaceGraphDefinitionProvider: WorkspaceGraphDefinitionProvider;
	private readonly _prefixCompletionProvider: TurtlePrefixCompletionProvider;
	private readonly _referenceProvider: ResourceReferenceProvider;
	private readonly _renameProvider: TurtleRenameProvider;
	private readonly _formattingProvider: TurtleCodeFormattingProvider;
	private readonly _validationCodelensProvider: TurtleValidationCodeLensProvider;
	private readonly _connectionCodelensProvider: TurtleConnectionCodeLensProvider;
 
	constructor() {
		const contextService = container.resolve<IDocumentContextService>(ServiceToken.DocumentContextService);
		const vocabulary = container.resolve<VocabularyRepository>(ServiceToken.VocabularyRepository);
		const prefixLookup = container.resolve<IPrefixLookupService>(ServiceToken.PrefixLookupService);
		const workspaceIndexer = container.resolve<IWorkspaceIndexerService>(ServiceToken.WorkspaceIndexerService);
		const presetDocuments = container.resolve<IPresetDocumentService>(ServiceToken.PresetDocumentService);
		const validationService = container.resolve<ShaclValidationService>(ServiceToken.ShaclValidationService);
		const connectionRegistry = container.resolve<ISparqlConnectionRegistry>(ServiceToken.SparqlConnectionRegistry);
		const documentConnectionService = container.resolve<IDocumentConnectionService>(ServiceToken.DocumentConnectionService);
		const renameService = container.resolve<IWorkspaceRenameService>(ServiceToken.WorkspaceRenameService);
 
		this._codeActionsProvider = new TurtleCodeActionsProvider(contextService);
		this._codelensProvider = new TurtleUsageCodeLensProvider(contextService, workspaceIndexer, vocabulary);
		this._completionProvider = new TurtleCompletionItemProvider(contextService, vocabulary);
		this._definitionProvider = new ResourceDefinitionProvider(contextService, workspaceIndexer, presetDocuments);
		this._notebookSlugCodelensProvider = new NotebookCellSlugCodeLensProvider(contextService);
		this._workspaceGraphDefinitionProvider = new WorkspaceGraphDefinitionProvider(contextService);
		this._prefixCompletionProvider = new TurtlePrefixCompletionProvider((uri) => ` <${uri}> .`, contextService, prefixLookup);
		this._referenceProvider = new ResourceReferenceProvider(contextService);
		this._renameProvider = new TurtleRenameProvider(contextService, renameService);
		this._formattingProvider = new TurtleCodeFormattingProvider();
		this._validationCodelensProvider = new TurtleValidationCodeLensProvider(contextService, workspaceIndexer, validationService);
		this._connectionCodelensProvider = new TurtleConnectionCodeLensProvider(connectionRegistry, documentConnectionService);
 
		// Self-register with the extension context for automatic disposal
		const context = container.resolve<vscode.ExtensionContext>(ServiceToken.ExtensionContext);
 
		const prefixDefinitionService = container.resolve<TurtlePrefixDefinitionService>(ServiceToken.TurtlePrefixDefinitionService);
		const autoDefinePrefixProvider = new TurtleAutoDefinePrefixProvider(this.getLanguages(), prefixDefinitionService, contextService);
		context.subscriptions.push(autoDefinePrefixProvider);
 
		for (const language of this.getLanguages()) {
			context.subscriptions.push(...this.registerForLanguage(language));
		}
	}
 
	/**
	 * Returns the languages this provider should register for. One instance
	 * covers the whole Turtle family: separate instances per language would
	 * multiply the event subscriptions, and every extra `onDidChangeCodeLenses`
	 * fire makes VS Code re-request the lenses of all visible documents.
	 * Override in subclasses to register for different languages.
	 */
	protected getLanguages(): string[] {
		return ['ntriples', 'nquads', 'turtle', 'n3', 'trig'];
	}
 
	protected registerForLanguage(language: string): vscode.Disposable[] {
		return [
			// The metadata lets VS Code skip this provider entirely for requests
			// of other action kinds (e.g. source.* rounds on save).
			vscode.languages.registerCodeActionsProvider({ language }, this._codeActionsProvider, {
				providedCodeActionKinds: TurtleCodeActionsProvider.providedCodeActionKinds
			}),
			vscode.languages.registerCodeLensProvider({ language }, this._codelensProvider),
			vscode.languages.registerCompletionItemProvider({ language }, this._completionProvider, ':'),
			vscode.languages.registerDefinitionProvider({ language }, this._definitionProvider),
			vscode.languages.registerDefinitionProvider({ language }, this._workspaceGraphDefinitionProvider),
			vscode.languages.registerDocumentFormattingEditProvider({ language }, this._formattingProvider),
			vscode.languages.registerInlineCompletionItemProvider({ language }, this._prefixCompletionProvider),
			vscode.languages.registerReferenceProvider({ language }, this._referenceProvider),
			vscode.languages.registerRenameProvider({ language }, this._renameProvider),
			// Note: Load same-line code lenses in inverted order of appearance.
			vscode.languages.registerCodeLensProvider({ language }, this._connectionCodelensProvider),
			vscode.languages.registerCodeLensProvider({ language }, this._validationCodelensProvider),
			vscode.languages.registerCodeLensProvider({ language }, this._notebookSlugCodelensProvider),
		]
	}
}