0

I have created my own Xtext based DSL and vscode based editor with language server protocol. I create multiple models in separate files:

# filename dummy1.xyz
model { name dummy1
   elements {
      Elem { name elem1 }
   }
}}

There is a composition file which references these elements (like calling a function declared in different header files)

# filename composedmodel.abc
composedModel {
   elemCalls {
      ElemCall { elem "dummy1.elem1" }
   } 
}

If I click on "dummy1.elem1", vscode opens a new file where the elem1 is defined. I want to replicate the same behavior programmatically.

For that, I parse these composed model files with antlr4ts. I send the following command from the LSP client whenever I encounter ElemCall

public async enterRuleElemCall(ctx: RuleElemCallContext): Promise<void> {
    var resp = this.client.sendRequest(vscode_languageserver_protocol_1.DefinitionRequest.type,
            this.client.code2ProtocolConverter.asTextDocumentPositionParams(this.document, new vscode.Position(2, 45)))
                .then(this.client.protocol2CodeConverter.asDefinitionResult, (error) => {
                    return this.client.handleFailedRequest(vscode_languageserver_protocol_1.DefinitionRequest.type, error, null);
            });

As you can see, for testing purpose I have hard-coded new vscode.Position(2, 45) which is usually obtained from the cursor position.

I have 2 questions:

  1. How can I get this position of "dummy1.elem1"?
  2. Even with the hard-coded position, the response I get is the URI to the file in which the referenced object is defined, but not the position of its definition. How can I extract only the relevant section
    Elem { name elem1 }

Edit 1:

By typecasting response as LocationLink

var location = resp as unknown as LocationLink[];
        
console.log(location[0]);
console.log(location[0].targetUri);
console.log(location[0].targetRange);

For location[0] I get

$ {uri: v, range: $}
range:$ {_start: $, _end: $}
uri:v {scheme: 'file', authority: '', path: '/home/user/dummy1.xyz', query: '', fragment: '', …}

But rest of the two it is undefined

Edit 2: I am finally able to extract the path with the following code:

let location = JSON.parse(JSON.stringify(resp));
console.log(location[0].uri.path);

Any ideas why targetUri is undefined? I ask because if I typecast resp as

var location = resp as unknown as DocumentLink[];

the range is not undefined anymore, but target is still undefined.

harsh
  • 905
  • 1
  • 10
  • 21
  • shouldnt response be this: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#locationLink – Christian Dietrich Apr 22 '22 at 05:25
  • thanks for the tip! I got it with `var location = resp as unknown as vscode.LocationLink[]; if(location !== undefined) { console.log(location[0]); }` and it has `range` and `uri` members – harsh Apr 22 '22 at 11:20
  • sorry I was a bit early to respond. I have added an edit with the problem – harsh Apr 22 '22 at 13:13
  • reponse is actually `result: Location | Location[] | LocationLink[] | null ` – Christian Dietrich Apr 23 '22 at 14:13

0 Answers0