diff --git a/server/src/providers/definition.ts b/server/src/providers/definition.ts index 56703c5..8eb4cd3 100644 --- a/server/src/providers/definition.ts +++ b/server/src/providers/definition.ts @@ -28,7 +28,11 @@ import * as ld from "../utils/languageDefinitions"; */ const definitionTargetRangeMaxLines: number = 10; -/** Return a `LocationLink` for class member `memberName` in class `cls` */ +/** Return a `LocationLink` for class member `memberName` in class `cls` + * + * This function queries `server` to find the source code of `cls` and locates + * the definition of `memberName` within the source code. + */ async function classMemberLocationLink( uri: string, cls: string, @@ -210,7 +214,7 @@ function findMemberInCurrentClass( } } -export async function onDefinition(params: TextDocumentPositionParams) { +export async function onDefinition(params: TextDocumentPositionParams): Promise { const doc = documents.get(params.textDocument.uri); if (doc === undefined) { return null; @@ -313,7 +317,7 @@ export async function onDefinition(params: TextDocumentPositionParams) { parsed[macrodefline][parsed[macrodefline].length - 1].p, macrodefline, parsed[macrodefline][parsed[macrodefline].length - 1].p + - parsed[macrodefline][parsed[macrodefline].length - 1].c, + parsed[macrodefline][parsed[macrodefline].length - 1].c, ), ), ) @@ -398,6 +402,32 @@ export async function onDefinition(params: TextDocumentPositionParams) { } } } + } else if ( + parsed[params.position.line][i].l == ld.cls_langindex && + i == 1 && + isClassMember( + doc + .getText( + Range.create( + params.position.line, + parsed[params.position.line][0].p, + params.position.line, + parsed[params.position.line][0].p + parsed[params.position.line][0].c, + ), + ) + .toLowerCase(), + ) + ) { + // This is a class member definition + const range = findFullRange(params.position.line, parsed, i, symbolstart, symbolend); + return findMemberInCurrentClass( + doc, + parsed, + params.textDocument.uri, + doc.getText(range), + "Method|ClassMethod|ClientMethod|Property|Relationship|Parameter|Projection|Query|Storage|Trigger|XData|ForeignKey|Index", + range, + ); } else if ( parsed[params.position.line][i].l == ld.cos_langindex && (parsed[params.position.line][i].s == ld.cos_prop_attrindex || @@ -429,7 +459,12 @@ export async function onDefinition(params: TextDocumentPositionParams) { } let membercontext: { baseclass: string; context?: string }; - if (parsed[params.position.line][i].s != ld.cos_instvar_attrindex) { + if (parsed[params.position.line][i].s == ld.cos_instvar_attrindex) { + membercontext = { + baseclass: thisclass, + context: "", + }; + } else { // Find the dot token let dottkn = 0; for (let tkn = 0; tkn < parsed[params.position.line].length; tkn++) { @@ -441,11 +476,6 @@ export async function onDefinition(params: TextDocumentPositionParams) { // Get the base class that this member is in membercontext = await getClassMemberContext(doc, parsed, dottkn, params.position.line, server); - } else { - membercontext = { - baseclass: thisclass, - context: "", - }; } if (membercontext.baseclass === "") { // If we couldn't determine the class, don't return anything @@ -1174,7 +1204,7 @@ export async function onDefinition(params: TextDocumentPositionParams) { parsed[ln][0].l == ld.cls_langindex && parsed[ln][0].s == ld.cls_keyword_attrindex && doc.getText(Range.create(ln, parsed[ln][0].p, ln, parsed[ln][0].p + parsed[ln][0].c)).toLowerCase() == - "class" + "class" ) { // This is the class definition line let seenExtends = false,