...
This commit is contained in:
@@ -1,9 +1,26 @@
|
|||||||
using NubLang.Ast;
|
using NubLang.Ast;
|
||||||
|
using NubLang.Syntax;
|
||||||
|
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
||||||
|
using Range = OmniSharp.Extensions.LanguageServer.Protocol.Models.Range;
|
||||||
|
|
||||||
namespace NubLang.LSP;
|
namespace NubLang.LSP;
|
||||||
|
|
||||||
public static class AstExtensions
|
public static class AstExtensions
|
||||||
{
|
{
|
||||||
|
public static Location ToLocation(this Node node)
|
||||||
|
{
|
||||||
|
if (node.Tokens.Count == 0)
|
||||||
|
{
|
||||||
|
return new Location();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Location
|
||||||
|
{
|
||||||
|
Uri = node.Tokens.First().Span.FilePath,
|
||||||
|
Range = new Range(node.Tokens.First().Span.Start.Line - 1, node.Tokens.First().Span.Start.Column - 1, node.Tokens.Last().Span.End.Line - 1, node.Tokens.Last().Span.End.Column - 1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static bool ContainsPosition(this Node node, int line, int character)
|
public static bool ContainsPosition(this Node node, int line, int character)
|
||||||
{
|
{
|
||||||
if (node.Tokens.Count == 0)
|
if (node.Tokens.Count == 0)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using NubLang.Ast;
|
|||||||
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
|
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
|
||||||
using OmniSharp.Extensions.LanguageServer.Protocol.Document;
|
using OmniSharp.Extensions.LanguageServer.Protocol.Document;
|
||||||
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
|
||||||
using Range = OmniSharp.Extensions.LanguageServer.Protocol.Models.Range;
|
|
||||||
|
|
||||||
namespace NubLang.LSP;
|
namespace NubLang.LSP;
|
||||||
|
|
||||||
@@ -41,16 +40,7 @@ internal class DefinitionHandler(WorkspaceManager workspaceManager) : Definition
|
|||||||
var parameter = function?.Prototype.Parameters.FirstOrDefault(x => x.Name == variableIdentifierNode.Name);
|
var parameter = function?.Prototype.Parameters.FirstOrDefault(x => x.Name == variableIdentifierNode.Name);
|
||||||
if (parameter != null)
|
if (parameter != null)
|
||||||
{
|
{
|
||||||
if (parameter.Tokens.Count == 0)
|
return new LocationOrLocationLinks(parameter.ToLocation());
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new LocationOrLocationLinks(new Location
|
|
||||||
{
|
|
||||||
Uri = parameter.Tokens.First().Span.FilePath,
|
|
||||||
Range = new Range(parameter.Tokens.First().Span.Start.Line - 1, parameter.Tokens.First().Span.Start.Column - 1, parameter.Tokens.Last().Span.End.Line - 1, parameter.Tokens.Last().Span.End.Column - 1)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var variable = function?.Body?
|
var variable = function?.Body?
|
||||||
@@ -60,33 +50,20 @@ internal class DefinitionHandler(WorkspaceManager workspaceManager) : Definition
|
|||||||
|
|
||||||
if (variable != null)
|
if (variable != null)
|
||||||
{
|
{
|
||||||
if (variable.Tokens.Count == 0)
|
return new LocationOrLocationLinks(variable.ToLocation());
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new LocationOrLocationLinks(new Location
|
|
||||||
{
|
|
||||||
Uri = variable.Tokens.First().Span.FilePath,
|
|
||||||
Range = new Range(variable.Tokens.First().Span.Start.Line - 1, variable.Tokens.First().Span.Start.Column - 1, variable.Tokens.Last().Span.End.Line - 1, variable.Tokens.Last().Span.End.Column - 1)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
case FuncIdentifierNode funcIdentifierNode:
|
case FuncIdentifierNode funcIdentifierNode:
|
||||||
{
|
{
|
||||||
var functionBody = compilationUnit.ImportedFunctions.FirstOrDefault(x => x.Module == funcIdentifierNode.Module && x.Name == funcIdentifierNode.Name);
|
var prototype = compilationUnit.ImportedFunctions.FirstOrDefault(x => x.Module == funcIdentifierNode.Module && x.Name == funcIdentifierNode.Name);
|
||||||
if (functionBody == null || functionBody.Tokens.Count == 0)
|
if (prototype != null)
|
||||||
{
|
{
|
||||||
return null;
|
return new LocationOrLocationLinks(prototype.ToLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LocationOrLocationLinks(new Location
|
return null;
|
||||||
{
|
|
||||||
Uri = functionBody.Tokens.First().Span.FilePath,
|
|
||||||
Range = new Range(functionBody.Tokens.First().Span.Start.Line - 1, functionBody.Tokens.First().Span.Start.Column - 1, functionBody.Tokens.Last().Span.End.Line - 1, functionBody.Tokens.Last().Span.End.Column - 1)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -59,35 +59,39 @@ internal class HoverHandler(WorkspaceManager workspaceManager) : HoverHandlerBas
|
|||||||
{
|
{
|
||||||
return hoveredNode switch
|
return hoveredNode switch
|
||||||
{
|
{
|
||||||
FuncNode funcNode => CreateFuncPrototypeNodeMessage(funcNode.Prototype),
|
FuncNode funcNode => CreateFuncPrototypeMessage(funcNode.Prototype),
|
||||||
FuncPrototypeNode funcPrototypeNode => CreateFuncPrototypeNodeMessage(funcPrototypeNode),
|
FuncPrototypeNode funcPrototypeNode => CreateFuncPrototypeMessage(funcPrototypeNode),
|
||||||
FuncIdentifierNode funcIdentifierNode => CreateFuncIdentifierNodeMessage(funcIdentifierNode, compilationUnit),
|
FuncIdentifierNode funcIdentifierNode => CreateFuncIdentifierMessage(funcIdentifierNode, compilationUnit),
|
||||||
FuncParameterNode funcParameterNode => CreateVariableIdentifierNodeMessage(funcParameterNode.Name, funcParameterNode.Type),
|
FuncParameterNode funcParameterNode => CreateTypeNameMessage("Function parameter", funcParameterNode.Name, funcParameterNode.Type),
|
||||||
VariableIdentifierNode variableIdentifierNode => CreateVariableIdentifierNodeMessage(variableIdentifierNode.Name, variableIdentifierNode.Type),
|
VariableIdentifierNode variableIdentifierNode => CreateTypeNameMessage("Variable", variableIdentifierNode.Name, variableIdentifierNode.Type),
|
||||||
VariableDeclarationNode variableDeclarationNode => CreateVariableIdentifierNodeMessage(variableDeclarationNode.Name, variableDeclarationNode.Type),
|
VariableDeclarationNode variableDeclarationNode => CreateTypeNameMessage("Variable declaration", variableDeclarationNode.Name, variableDeclarationNode.Type),
|
||||||
CStringLiteralNode cStringLiteralNode => CreateLiteralNodeMessage(cStringLiteralNode.Type, '"' + cStringLiteralNode.Value + '"'),
|
StructFieldAccessNode structFieldAccessNode => CreateTypeNameMessage("Struct field", $"{structFieldAccessNode.Target.Type}.{structFieldAccessNode.Field}", structFieldAccessNode.Type),
|
||||||
StringLiteralNode stringLiteralNode => CreateLiteralNodeMessage(stringLiteralNode.Type, '"' + stringLiteralNode.Value + '"'),
|
CStringLiteralNode cStringLiteralNode => CreateLiteralMessage(cStringLiteralNode.Type, '"' + cStringLiteralNode.Value + '"'),
|
||||||
BoolLiteralNode boolLiteralNode => CreateLiteralNodeMessage(boolLiteralNode.Type, boolLiteralNode.Value.ToString()),
|
StringLiteralNode stringLiteralNode => CreateLiteralMessage(stringLiteralNode.Type, '"' + stringLiteralNode.Value + '"'),
|
||||||
Float32LiteralNode float32LiteralNode => CreateLiteralNodeMessage(float32LiteralNode.Type, float32LiteralNode.Value.ToString(CultureInfo.InvariantCulture)),
|
BoolLiteralNode boolLiteralNode => CreateLiteralMessage(boolLiteralNode.Type, boolLiteralNode.Value.ToString()),
|
||||||
Float64LiteralNode float64LiteralNode => CreateLiteralNodeMessage(float64LiteralNode.Type, float64LiteralNode.Value.ToString(CultureInfo.InvariantCulture)),
|
Float32LiteralNode float32LiteralNode => CreateLiteralMessage(float32LiteralNode.Type, float32LiteralNode.Value.ToString(CultureInfo.InvariantCulture)),
|
||||||
I8LiteralNode i8LiteralNode => CreateLiteralNodeMessage(i8LiteralNode.Type, i8LiteralNode.Value.ToString()),
|
Float64LiteralNode float64LiteralNode => CreateLiteralMessage(float64LiteralNode.Type, float64LiteralNode.Value.ToString(CultureInfo.InvariantCulture)),
|
||||||
I16LiteralNode i16LiteralNode => CreateLiteralNodeMessage(i16LiteralNode.Type, i16LiteralNode.Value.ToString()),
|
I8LiteralNode i8LiteralNode => CreateLiteralMessage(i8LiteralNode.Type, i8LiteralNode.Value.ToString()),
|
||||||
I32LiteralNode i32LiteralNode => CreateLiteralNodeMessage(i32LiteralNode.Type, i32LiteralNode.Value.ToString()),
|
I16LiteralNode i16LiteralNode => CreateLiteralMessage(i16LiteralNode.Type, i16LiteralNode.Value.ToString()),
|
||||||
I64LiteralNode i64LiteralNode => CreateLiteralNodeMessage(i64LiteralNode.Type, i64LiteralNode.Value.ToString()),
|
I32LiteralNode i32LiteralNode => CreateLiteralMessage(i32LiteralNode.Type, i32LiteralNode.Value.ToString()),
|
||||||
U8LiteralNode u8LiteralNode => CreateLiteralNodeMessage(u8LiteralNode.Type, u8LiteralNode.Value.ToString()),
|
I64LiteralNode i64LiteralNode => CreateLiteralMessage(i64LiteralNode.Type, i64LiteralNode.Value.ToString()),
|
||||||
U16LiteralNode u16LiteralNode => CreateLiteralNodeMessage(u16LiteralNode.Type, u16LiteralNode.Value.ToString()),
|
U8LiteralNode u8LiteralNode => CreateLiteralMessage(u8LiteralNode.Type, u8LiteralNode.Value.ToString()),
|
||||||
U32LiteralNode u32LiteralNode => CreateLiteralNodeMessage(u32LiteralNode.Type, u32LiteralNode.Value.ToString()),
|
U16LiteralNode u16LiteralNode => CreateLiteralMessage(u16LiteralNode.Type, u16LiteralNode.Value.ToString()),
|
||||||
U64LiteralNode u64LiteralNode => CreateLiteralNodeMessage(u64LiteralNode.Type, u64LiteralNode.Value.ToString()),
|
U32LiteralNode u32LiteralNode => CreateLiteralMessage(u32LiteralNode.Type, u32LiteralNode.Value.ToString()),
|
||||||
|
U64LiteralNode u64LiteralNode => CreateLiteralMessage(u64LiteralNode.Type, u64LiteralNode.Value.ToString()),
|
||||||
// Expressions can have a generic fallback showing the resulting type
|
// Expressions can have a generic fallback showing the resulting type
|
||||||
ExpressionNode expressionNode => CreateGenericExpressionNodeMessage(expressionNode),
|
ExpressionNode expressionNode => $"""
|
||||||
// Explicit null returns, can be removed when the default is null instead of the debug type
|
**Expression** `{expressionNode.GetType().Name}`
|
||||||
|
```nub
|
||||||
|
{expressionNode.Type}
|
||||||
|
```
|
||||||
|
""",
|
||||||
BlockNode => null,
|
BlockNode => null,
|
||||||
StatementNode statementNode => CreateGenericStatementNodeMessage(statementNode),
|
|
||||||
_ => hoveredNode.GetType().Name
|
_ => hoveredNode.GetType().Name
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CreateLiteralNodeMessage(NubType type, string value)
|
private static string CreateLiteralMessage(NubType type, string value)
|
||||||
{
|
{
|
||||||
return $"""
|
return $"""
|
||||||
**Literal** `{type}`
|
**Literal** `{type}`
|
||||||
@@ -97,17 +101,17 @@ internal class HoverHandler(WorkspaceManager workspaceManager) : HoverHandlerBas
|
|||||||
""";
|
""";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CreateVariableIdentifierNodeMessage(string name, NubType type)
|
private static string CreateTypeNameMessage(string description, string name, NubType type)
|
||||||
{
|
{
|
||||||
return $"""
|
return $"""
|
||||||
**Variable** `{name}`
|
**{description}** `{name}`
|
||||||
```nub
|
```nub
|
||||||
{name}: {type}
|
{name}: {type}
|
||||||
```
|
```
|
||||||
""";
|
""";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CreateFuncIdentifierNodeMessage(FuncIdentifierNode funcIdentifierNode, CompilationUnit compilationUnit)
|
private static string CreateFuncIdentifierMessage(FuncIdentifierNode funcIdentifierNode, CompilationUnit compilationUnit)
|
||||||
{
|
{
|
||||||
var func = compilationUnit.ImportedFunctions.FirstOrDefault(x => x.Module == funcIdentifierNode.Module && x.Name == funcIdentifierNode.Name);
|
var func = compilationUnit.ImportedFunctions.FirstOrDefault(x => x.Module == funcIdentifierNode.Module && x.Name == funcIdentifierNode.Name);
|
||||||
if (func == null)
|
if (func == null)
|
||||||
@@ -120,33 +124,18 @@ internal class HoverHandler(WorkspaceManager workspaceManager) : HoverHandlerBas
|
|||||||
""";
|
""";
|
||||||
}
|
}
|
||||||
|
|
||||||
return CreateFuncPrototypeNodeMessage(func);
|
return CreateFuncPrototypeMessage(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CreateFuncPrototypeNodeMessage(FuncPrototypeNode funcPrototypeNode)
|
private static string CreateFuncPrototypeMessage(FuncPrototypeNode funcPrototypeNode)
|
||||||
{
|
{
|
||||||
var parameterText = string.Join(", ", funcPrototypeNode.Parameters.Select(x => $"{x.Name}: {x.Type}"));
|
var parameterText = string.Join(", ", funcPrototypeNode.Parameters.Select(x => $"{x.Name}: {x.Type}"));
|
||||||
var externText = funcPrototypeNode.ExternSymbol != null ? $"extern \"{funcPrototypeNode.ExternSymbol}\" " : "";
|
var externText = funcPrototypeNode.ExternSymbol != null ? $"extern \"{funcPrototypeNode.ExternSymbol}\" " : "";
|
||||||
|
|
||||||
return $"""
|
return $"""
|
||||||
**Function** `{funcPrototypeNode.Name}`
|
**Function** `{funcPrototypeNode.Module}::{funcPrototypeNode.Name}`
|
||||||
```nub
|
```nub
|
||||||
{externText}func {funcPrototypeNode.Name}({parameterText}): {funcPrototypeNode.ReturnType}
|
{externText}func {funcPrototypeNode.Module}::{funcPrototypeNode.Name}({parameterText}): {funcPrototypeNode.ReturnType}
|
||||||
```
|
|
||||||
""";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string CreateGenericStatementNodeMessage(StatementNode statementNode)
|
|
||||||
{
|
|
||||||
return $"**Statement** `{statementNode.GetType().Name}`";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string CreateGenericExpressionNodeMessage(ExpressionNode expressionNode)
|
|
||||||
{
|
|
||||||
return $"""
|
|
||||||
**Expression** `{expressionNode.GetType().Name}`
|
|
||||||
```nub
|
|
||||||
{expressionNode.Type}
|
|
||||||
```
|
```
|
||||||
""";
|
""";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user