How to implement go to definition functionality?

SyntaxEditor .NET Languages Add-on for WPF Forum

The latest build of this product (v21.1.3) was released 16 days ago, which was before this thread was created.
Posted 15 days ago by Seito Shirata
Version: 19.1.0684
Avatar

Hello,
I would like to implement Go To Definition functionality.

I tried to implement it by referring to this forum, but it doesn't work.
Go To Definition functionality

My code is below

private void OnKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.F12)
    {
        this.MoveCaretToDefinition();
    }
}

private void MoveCaretToDefinition()
{
    // CSharp editor is SyntaxEditor class
    var snapshotOffset = this.CSharpEditor.ActiveView.Selection.EndSnapshotOffset;
    var context = new CSharpContextFactory().CreateContext(snapshotOffset);
    var results = context?.Resolve();
    if (results == null || results.Results.Count == 0) return;
    var result = results.Results[0];
    var type = result?.Type;
    var def = type as ITypeDefinition;
    var locationCollection = def?.SourceFileLocations;
    if (locationCollection == null || locationCollection.Count == 0) return;
    var offset = locationCollection[0].NavigationOffset;
    if (offset.HasValue)
    {
        this.CSharpEditor.ActiveView.Selection.CaretOffset = offset.Value;
    }
}

By this code, when selecting `this` identifier and press F12 in the tareget C# code, it was possible to move caret to the class declaration.
Otherwise, it does not work.
For example, if select a member defined in the class, the type cannot cast  to ITypeDefinition and def is null.
Also, if argument in the method, cast is ok but the locationCollection is empty collection.

Thanks.

Comments (6)

Posted 14 days ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

The sample code you provided is looking at IResolverResult.Type and only handling when it returns an ITypeDefinition. There are several different resolver results that must be handled to fully implement functionality like "Go To Definition".

Please refer to the following help topic that introduces the various outcomes from a Resolve operation:

Performing a Resolve Operation

Please reach out if you need additional assistance after implementing the additional result types.


Actipro Software Support

Posted 11 days ago by Seito Shirata
Avatar

Hello, 

I decided to branch the process according to the kind of resolver results.
However, in the following cases for example, I cannot understand how to get the file location information.

  • IParameterResolver.Param
  • IIVariableResolverResult.Variable
  • ITypeMemberResolverResult.Member and its member type is field.

Is it possible to get the file location information from these?

Thanks.

Answer - Posted 10 days ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

It appears that events and fields weren't properly initializing the member.SourceFileLocation.  We've fixed that for the next verison.

We also will add IParameterDefinition.SourceFileLocation and IVariableDefinition.SourceFileLocation properties in the next version.


Actipro Software Support

Posted 10 days ago by Seito Shirata
Avatar

Thank you.
I will consider introducing the next version.

Posted 10 days ago by Seito Shirata
Avatar

Excuse me for repeating question.
I checked in v21.1.3, but when member is field, member.SourceFileLocation is still null.

Hasn't it been fixed in this version?

This is a part of my source code.

switch (result)
{
  /* omit other cases */
  case ITypeMemberResolverResult typeMemberResolverResult:
    var sourceFileLocation = typeMemberResolverResult.Member.SourceFileLocation;
    /* when member is field sourceFileLocation is null */
    break;
}

Thanks

Posted 9 days ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

I'm sorry but v21.1.3 was out before this thread was created.  The updates we made to support all definition kinds will be in the v22.1 codebase.

Note that even after the v22.1 updates, SourceFileLocation will only ever be filled in when the type/member/parameter/variable definition is created from code that is parsed.  It won't be filled in from definitions that come from a reflected assembly .dll file.  


Actipro Software Support

Add Comment

Please log in to a validated account to post comments.