Skip to content

Commit cb5057c

Browse files
committed
Add implementation for definition request
Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
1 parent 34d75f6 commit cb5057c

File tree

6 files changed

+80
-5
lines changed

6 files changed

+80
-5
lines changed

src/languageserver/handlers/languageHandlers.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ import {
1717
Connection,
1818
TextDocumentPositionParams,
1919
CodeLensParams,
20+
DefinitionParams,
2021
} from 'vscode-languageserver';
21-
import { CodeLens, DocumentSymbol, Hover, SymbolInformation, TextEdit } from 'vscode-languageserver-types';
22+
import { CodeLens, DefinitionLink, DocumentSymbol, Hover, SymbolInformation, TextEdit } from 'vscode-languageserver-types';
2223
import { isKubernetesAssociatedDocument } from '../../languageservice/parser/isKubernetes';
2324
import { LanguageService } from '../../languageservice/yamlLanguageService';
2425
import { SettingsState } from '../../yamlSettings';
@@ -57,6 +58,7 @@ export class LanguageHandlers {
5758
this.connection.onDocumentOnTypeFormatting((params) => this.formatOnTypeHandler(params));
5859
this.connection.onCodeLens((params) => this.codeLensHandler(params));
5960
this.connection.onCodeLensResolve((params) => this.codeLensResolveHandler(params));
61+
this.connection.onDefinition((params) => this.definitionHandler(params));
6062

6163
this.yamlSettings.documents.onDidChangeContent((change) => this.cancelLimitExceededWarnings(change.document.uri));
6264
this.yamlSettings.documents.onDidClose((event) => this.cancelLimitExceededWarnings(event.document.uri));
@@ -219,6 +221,15 @@ export class LanguageHandlers {
219221
return this.languageService.resolveCodeLens(param);
220222
}
221223

224+
definitionHandler(params: DefinitionParams): DefinitionLink[] {
225+
const textDocument = this.yamlSettings.documents.get(params.textDocument.uri);
226+
if (!textDocument) {
227+
return;
228+
}
229+
230+
return this.languageService.doDefinition(textDocument, params);
231+
}
232+
222233
// Adapted from:
223234
// https://github.com/microsoft/vscode/blob/94c9ea46838a9a619aeafb7e8afd1170c967bb55/extensions/json-language-features/server/src/jsonServer.ts#L172
224235
private cancelLimitExceededWarnings(uri: string): void {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Red Hat, Inc. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { DefinitionParams, LocationLink, Range } from 'vscode-languageserver-protocol';
7+
import { TextDocument } from 'vscode-languageserver-textdocument';
8+
import { DefinitionLink } from 'vscode-languageserver-types';
9+
import { isAlias } from 'yaml';
10+
import { yamlDocumentsCache } from '../parser/yaml-documents';
11+
import { matchOffsetToDocument } from '../utils/arrUtils';
12+
import { TextBuffer } from '../utils/textBuffer';
13+
14+
export function getDefinition(document: TextDocument, params: DefinitionParams): DefinitionLink[] | undefined {
15+
try {
16+
const yamlDocument = yamlDocumentsCache.getYamlDocument(document);
17+
const offset = document.offsetAt(params.position);
18+
const currentDoc = matchOffsetToDocument(offset, yamlDocument);
19+
if (currentDoc) {
20+
const [node] = currentDoc.getNodeFromPosition(offset, new TextBuffer(document));
21+
if (node && isAlias(node)) {
22+
const defNode = node.resolve(currentDoc.internalDocument);
23+
if (defNode && defNode.range) {
24+
const targetRange = Range.create(document.positionAt(defNode.range[0]), document.positionAt(defNode.range[2]));
25+
const selectionRange = Range.create(document.positionAt(defNode.range[0]), document.positionAt(defNode.range[1]));
26+
return [LocationLink.create(document.uri, targetRange, selectionRange)];
27+
}
28+
}
29+
}
30+
} catch (err) {
31+
this.telemetry.sendError('yaml.definition.error', { error: err });
32+
}
33+
34+
return undefined;
35+
}

src/languageservice/yamlLanguageService.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ import {
2121
TextEdit,
2222
DocumentLink,
2323
CodeLens,
24+
DefinitionLink,
2425
} from 'vscode-languageserver-types';
2526
import { JSONSchema } from './jsonSchema';
2627
import { YAMLDocumentSymbols } from './services/documentSymbols';
2728
import { YAMLHover } from './services/yamlHover';
2829
import { YAMLValidation } from './services/yamlValidation';
2930
import { YAMLFormatter } from './services/yamlFormatter';
30-
import { JSONDocument, DefinitionLink, TextDocument, DocumentSymbolsContext } from 'vscode-json-languageservice';
31+
import { DocumentSymbolsContext } from 'vscode-json-languageservice';
3132
import { findLinks } from './services/yamlLinks';
3233
import {
3334
FoldingRange,
@@ -37,7 +38,9 @@ import {
3738
Connection,
3839
DocumentOnTypeFormattingParams,
3940
CodeLensParams,
41+
DefinitionParams,
4042
} from 'vscode-languageserver/node';
43+
import { TextDocument } from 'vscode-languageserver-textdocument';
4144
import { getFoldingRanges } from './services/yamlFolding';
4245
import { FoldingRangesContext } from './yamlTypes';
4346
import { YamlCodeActions } from './services/yamlCodeActions';
@@ -49,6 +52,7 @@ import { Telemetry } from '../languageserver/telemetry';
4952
import { YamlVersion } from './parser/yamlParser07';
5053
import { YamlCompletion } from './services/yamlCompletion';
5154
import { yamlDocumentsCache } from './parser/yaml-documents';
55+
import { getDefinition } from './services/yamlDefinition';
5256

5357
export enum SchemaPriority {
5458
SchemaStore = 1,
@@ -132,10 +136,10 @@ export interface LanguageService {
132136
doHover(document: TextDocument, position: Position): Promise<Hover | null>;
133137
findDocumentSymbols(document: TextDocument, context: DocumentSymbolsContext): SymbolInformation[];
134138
findDocumentSymbols2(document: TextDocument, context: DocumentSymbolsContext): DocumentSymbol[];
135-
findDefinition(document: TextDocument, position: Position, doc: JSONDocument): Promise<DefinitionLink[]>;
136139
findLinks(document: TextDocument): Promise<DocumentLink[]>;
137140
resetSchema(uri: string): boolean;
138141
doFormat(document: TextDocument, options: CustomFormatterOptions): TextEdit[];
142+
doDefinition(document: TextDocument, params: DefinitionParams): DefinitionLink[] | undefined;
139143
doDocumentOnTypeFormatting(document: TextDocument, params: DocumentOnTypeFormattingParams): TextEdit[] | undefined;
140144
addSchema(schemaID: string, schema: JSONSchema): void;
141145
deleteSchema(schemaID: string): void;
@@ -185,13 +189,13 @@ export function getLanguageService(
185189
registerCustomSchemaProvider: (schemaProvider: CustomSchemaProvider) => {
186190
schemaService.registerCustomSchemaProvider(schemaProvider);
187191
},
188-
findDefinition: () => Promise.resolve([]),
189192
findLinks,
190193
doComplete: completer.doComplete.bind(completer),
191194
doValidation: yamlValidation.doValidation.bind(yamlValidation),
192195
doHover: hover.doHover.bind(hover),
193196
findDocumentSymbols: yamlDocumentSymbols.findDocumentSymbols.bind(yamlDocumentSymbols),
194197
findDocumentSymbols2: yamlDocumentSymbols.findHierarchicalDocumentSymbols.bind(yamlDocumentSymbols),
198+
doDefinition: getDefinition.bind(getDefinition),
195199
resetSchema: (uri: string) => {
196200
return schemaService.onResourceChange(uri);
197201
},

src/yamlServerInit.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export class YAMLServerInit {
101101
firstTriggerCharacter: '\n',
102102
},
103103
documentRangeFormattingProvider: false,
104+
definitionProvider: true,
104105
documentLinkProvider: {},
105106
// disabled until we not get parser which parse comments as separate nodes
106107
foldingRangeProvider: false,

test/findLinks.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { DocumentLink } from 'vscode-languageserver';
99
import { SettingsState, TextDocumentTestManager } from '../src/yamlSettings';
1010
import { LanguageHandlers } from '../src/languageserver/handlers/languageHandlers';
1111

12-
describe('FindDefintion Tests', () => {
12+
describe('Find Links Tests', () => {
1313
let languageHandler: LanguageHandlers;
1414
let yamlSettings: SettingsState;
1515

test/yamlDefinition.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Red Hat, Inc. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { setupTextDocument, TEST_URI } from './utils/testHelper';
7+
import { expect } from 'chai';
8+
import { getDefinition } from '../src/languageservice/services/yamlDefinition';
9+
import { LocationLink, Position, Range } from 'vscode-languageserver-protocol';
10+
11+
describe('YAML Definition', () => {
12+
it('should not provide definition for non anchor node', () => {
13+
const doc = setupTextDocument('foo: &bar some\naaa: *bar');
14+
const result = getDefinition(doc, { position: Position.create(1, 2), textDocument: { uri: TEST_URI } });
15+
expect(result).is.undefined;
16+
});
17+
18+
it('should provide definition for anchor', () => {
19+
const doc = setupTextDocument('foo: &bar some\naaa: *bar');
20+
const result = getDefinition(doc, { position: Position.create(1, 7), textDocument: { uri: TEST_URI } });
21+
expect(result).is.not.undefined;
22+
expect(result[0]).is.eqls(LocationLink.create(TEST_URI, Range.create(0, 10, 1, 0), Range.create(0, 10, 0, 14)));
23+
});
24+
});

0 commit comments

Comments
 (0)