diff --git a/src/languageservice/services/yamlDefinition.ts b/src/languageservice/services/yamlDefinition.ts index aeab3033..16feb347 100644 --- a/src/languageservice/services/yamlDefinition.ts +++ b/src/languageservice/services/yamlDefinition.ts @@ -7,29 +7,34 @@ import { DefinitionParams, LocationLink, Range } from 'vscode-languageserver-pro import { TextDocument } from 'vscode-languageserver-textdocument'; import { DefinitionLink } from 'vscode-languageserver-types'; import { isAlias } from 'yaml'; +import { Telemetry } from '../../languageserver/telemetry'; import { yamlDocumentsCache } from '../parser/yaml-documents'; import { matchOffsetToDocument } from '../utils/arrUtils'; import { TextBuffer } from '../utils/textBuffer'; -export function getDefinition(document: TextDocument, params: DefinitionParams): DefinitionLink[] | undefined { - try { - const yamlDocument = yamlDocumentsCache.getYamlDocument(document); - const offset = document.offsetAt(params.position); - const currentDoc = matchOffsetToDocument(offset, yamlDocument); - if (currentDoc) { - const [node] = currentDoc.getNodeFromPosition(offset, new TextBuffer(document)); - if (node && isAlias(node)) { - const defNode = node.resolve(currentDoc.internalDocument); - if (defNode && defNode.range) { - const targetRange = Range.create(document.positionAt(defNode.range[0]), document.positionAt(defNode.range[2])); - const selectionRange = Range.create(document.positionAt(defNode.range[0]), document.positionAt(defNode.range[1])); - return [LocationLink.create(document.uri, targetRange, selectionRange)]; +export class YamlDefinition { + constructor(private readonly telemetry: Telemetry) {} + + getDefinition(document: TextDocument, params: DefinitionParams): DefinitionLink[] | undefined { + try { + const yamlDocument = yamlDocumentsCache.getYamlDocument(document); + const offset = document.offsetAt(params.position); + const currentDoc = matchOffsetToDocument(offset, yamlDocument); + if (currentDoc) { + const [node] = currentDoc.getNodeFromPosition(offset, new TextBuffer(document)); + if (node && isAlias(node)) { + const defNode = node.resolve(currentDoc.internalDocument); + if (defNode && defNode.range) { + const targetRange = Range.create(document.positionAt(defNode.range[0]), document.positionAt(defNode.range[2])); + const selectionRange = Range.create(document.positionAt(defNode.range[0]), document.positionAt(defNode.range[1])); + return [LocationLink.create(document.uri, targetRange, selectionRange)]; + } } } + } catch (err) { + this.telemetry.sendError('yaml.definition.error', { error: err.toString() }); } - } catch (err) { - this.telemetry.sendError('yaml.definition.error', { error: err.toString() }); - } - return undefined; + return undefined; + } } diff --git a/src/languageservice/yamlLanguageService.ts b/src/languageservice/yamlLanguageService.ts index 764ee425..551ec57a 100644 --- a/src/languageservice/yamlLanguageService.ts +++ b/src/languageservice/yamlLanguageService.ts @@ -54,7 +54,7 @@ import { YamlCompletion } from './services/yamlCompletion'; import { yamlDocumentsCache } from './parser/yaml-documents'; import { SettingsState } from '../yamlSettings'; import { JSONSchemaSelection } from '../languageserver/handlers/schemaSelectionHandlers'; -import { getDefinition } from './services/yamlDefinition'; +import { YamlDefinition } from './services/yamlDefinition'; export enum SchemaPriority { SchemaStore = 1, @@ -173,6 +173,7 @@ export function getLanguageService( const yamlCodeActions = new YamlCodeActions(clientCapabilities); const yamlCodeLens = new YamlCodeLens(schemaService, telemetry); const yamlLinks = new YamlLinks(telemetry); + const yamlDefinition = new YamlDefinition(telemetry); new JSONSchemaSelection(schemaService, yamlSettings, connection); @@ -210,7 +211,7 @@ export function getLanguageService( doHover: hover.doHover.bind(hover), findDocumentSymbols: yamlDocumentSymbols.findDocumentSymbols.bind(yamlDocumentSymbols), findDocumentSymbols2: yamlDocumentSymbols.findHierarchicalDocumentSymbols.bind(yamlDocumentSymbols), - doDefinition: getDefinition.bind(getDefinition), + doDefinition: yamlDefinition.getDefinition.bind(yamlDefinition), resetSchema: (uri: string) => { return schemaService.onResourceChange(uri); }, diff --git a/test/yamlDefinition.test.ts b/test/yamlDefinition.test.ts index 5846557e..d6c29153 100644 --- a/test/yamlDefinition.test.ts +++ b/test/yamlDefinition.test.ts @@ -5,19 +5,26 @@ import { setupTextDocument, TEST_URI } from './utils/testHelper'; import { expect } from 'chai'; -import { getDefinition } from '../src/languageservice/services/yamlDefinition'; +import { YamlDefinition } from '../src/languageservice/services/yamlDefinition'; import { LocationLink, Position, Range } from 'vscode-languageserver-protocol'; +import { Telemetry } from '../src/languageserver/telemetry'; describe('YAML Definition', () => { it('should not provide definition for non anchor node', () => { const doc = setupTextDocument('foo: &bar some\naaa: *bar'); - const result = getDefinition(doc, { position: Position.create(1, 2), textDocument: { uri: TEST_URI } }); + const result = new YamlDefinition({} as Telemetry).getDefinition(doc, { + position: Position.create(1, 2), + textDocument: { uri: TEST_URI }, + }); expect(result).is.undefined; }); it('should provide definition for anchor', () => { const doc = setupTextDocument('foo: &bar some\naaa: *bar'); - const result = getDefinition(doc, { position: Position.create(1, 7), textDocument: { uri: TEST_URI } }); + const result = new YamlDefinition({} as Telemetry).getDefinition(doc, { + position: Position.create(1, 7), + textDocument: { uri: TEST_URI }, + }); expect(result).is.not.undefined; expect(result[0]).is.eqls(LocationLink.create(TEST_URI, Range.create(0, 10, 1, 0), Range.create(0, 10, 0, 14))); });