This repository has been archived on 2025-10-24. You can view files and clone it, but cannot push or open issues or pull requests.
Files
nub-lang-archive-2/compiler/NubLang.LSP/DefinitionHandler.cs
2025-10-23 19:17:51 +02:00

74 lines
2.6 KiB
C#

using NubLang.Ast;
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
using OmniSharp.Extensions.LanguageServer.Protocol.Document;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
namespace NubLang.LSP;
internal class DefinitionHandler(WorkspaceManager workspaceManager) : DefinitionHandlerBase
{
protected override DefinitionRegistrationOptions CreateRegistrationOptions(DefinitionCapability capability, ClientCapabilities clientCapabilities)
{
return new DefinitionRegistrationOptions();
}
public override Task<LocationOrLocationLinks?> Handle(DefinitionParams request, CancellationToken cancellationToken)
{
return Task.FromResult(HandleSync(request, cancellationToken));
}
private LocationOrLocationLinks? HandleSync(DefinitionParams request, CancellationToken cancellationToken)
{
var uri = request.TextDocument.Uri;
var compilationUnit = workspaceManager.GetCompilationUnit(uri);
if (compilationUnit == null)
{
return null;
}
var line = request.Position.Line;
var character = request.Position.Character;
var node = compilationUnit.DeepestNodeAtPosition(line, character);
switch (node)
{
case VariableIdentifierNode variableIdentifierNode:
{
var function = compilationUnit.FunctionAtPosition(line, character);
var parameter = function?.Prototype.Parameters.FirstOrDefault(x => x.Name == variableIdentifierNode.Name);
if (parameter != null)
{
return new LocationOrLocationLinks(parameter.ToLocation());
}
var variable = function?.Body?
.Descendants()
.OfType<VariableDeclarationNode>()
.FirstOrDefault(x => x.Name == variableIdentifierNode.Name);
if (variable != null)
{
return new LocationOrLocationLinks(variable.ToLocation());
}
return null;
}
case FuncIdentifierNode funcIdentifierNode:
{
var prototype = compilationUnit.ImportedFunctions.FirstOrDefault(x => x.Module == funcIdentifierNode.Module && x.Name == funcIdentifierNode.Name);
if (prototype != null)
{
return new LocationOrLocationLinks(prototype.ToLocation());
}
return null;
}
default:
{
return null;
}
}
}
}