From db46dbba03d062217ca69633451506c35590e09c Mon Sep 17 00:00:00 2001 From: nub31 Date: Thu, 23 Oct 2025 14:31:14 +0200 Subject: [PATCH] ... --- compiler/NubLang.LSP/AstExtensions.cs | 17 +++++ compiler/NubLang.LSP/DefinitionHandler.cs | 35 ++-------- compiler/NubLang.LSP/HoverHandler.cs | 79 ++++++++++------------- 3 files changed, 57 insertions(+), 74 deletions(-) diff --git a/compiler/NubLang.LSP/AstExtensions.cs b/compiler/NubLang.LSP/AstExtensions.cs index ed1ea80..82ceb0f 100644 --- a/compiler/NubLang.LSP/AstExtensions.cs +++ b/compiler/NubLang.LSP/AstExtensions.cs @@ -1,9 +1,26 @@ using NubLang.Ast; +using NubLang.Syntax; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using Range = OmniSharp.Extensions.LanguageServer.Protocol.Models.Range; namespace NubLang.LSP; 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) { if (node.Tokens.Count == 0) diff --git a/compiler/NubLang.LSP/DefinitionHandler.cs b/compiler/NubLang.LSP/DefinitionHandler.cs index f363cd4..6329111 100644 --- a/compiler/NubLang.LSP/DefinitionHandler.cs +++ b/compiler/NubLang.LSP/DefinitionHandler.cs @@ -2,7 +2,6 @@ using NubLang.Ast; using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; using OmniSharp.Extensions.LanguageServer.Protocol.Document; using OmniSharp.Extensions.LanguageServer.Protocol.Models; -using Range = OmniSharp.Extensions.LanguageServer.Protocol.Models.Range; namespace NubLang.LSP; @@ -41,16 +40,7 @@ internal class DefinitionHandler(WorkspaceManager workspaceManager) : Definition var parameter = function?.Prototype.Parameters.FirstOrDefault(x => x.Name == variableIdentifierNode.Name); if (parameter != null) { - if (parameter.Tokens.Count == 0) - { - 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) - }); + return new LocationOrLocationLinks(parameter.ToLocation()); } var variable = function?.Body? @@ -60,33 +50,20 @@ internal class DefinitionHandler(WorkspaceManager workspaceManager) : Definition if (variable != null) { - if (variable.Tokens.Count == 0) - { - 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 new LocationOrLocationLinks(variable.ToLocation()); } return null; } case FuncIdentifierNode funcIdentifierNode: { - var functionBody = compilationUnit.ImportedFunctions.FirstOrDefault(x => x.Module == funcIdentifierNode.Module && x.Name == funcIdentifierNode.Name); - if (functionBody == null || functionBody.Tokens.Count == 0) + var prototype = compilationUnit.ImportedFunctions.FirstOrDefault(x => x.Module == funcIdentifierNode.Module && x.Name == funcIdentifierNode.Name); + if (prototype != null) { - return null; + return new LocationOrLocationLinks(prototype.ToLocation()); } - return new LocationOrLocationLinks(new Location - { - 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) - }); + return null; } default: { diff --git a/compiler/NubLang.LSP/HoverHandler.cs b/compiler/NubLang.LSP/HoverHandler.cs index 19e94e2..f90e6c0 100644 --- a/compiler/NubLang.LSP/HoverHandler.cs +++ b/compiler/NubLang.LSP/HoverHandler.cs @@ -59,35 +59,39 @@ internal class HoverHandler(WorkspaceManager workspaceManager) : HoverHandlerBas { return hoveredNode switch { - FuncNode funcNode => CreateFuncPrototypeNodeMessage(funcNode.Prototype), - FuncPrototypeNode funcPrototypeNode => CreateFuncPrototypeNodeMessage(funcPrototypeNode), - FuncIdentifierNode funcIdentifierNode => CreateFuncIdentifierNodeMessage(funcIdentifierNode, compilationUnit), - FuncParameterNode funcParameterNode => CreateVariableIdentifierNodeMessage(funcParameterNode.Name, funcParameterNode.Type), - VariableIdentifierNode variableIdentifierNode => CreateVariableIdentifierNodeMessage(variableIdentifierNode.Name, variableIdentifierNode.Type), - VariableDeclarationNode variableDeclarationNode => CreateVariableIdentifierNodeMessage(variableDeclarationNode.Name, variableDeclarationNode.Type), - CStringLiteralNode cStringLiteralNode => CreateLiteralNodeMessage(cStringLiteralNode.Type, '"' + cStringLiteralNode.Value + '"'), - StringLiteralNode stringLiteralNode => CreateLiteralNodeMessage(stringLiteralNode.Type, '"' + stringLiteralNode.Value + '"'), - BoolLiteralNode boolLiteralNode => CreateLiteralNodeMessage(boolLiteralNode.Type, boolLiteralNode.Value.ToString()), - Float32LiteralNode float32LiteralNode => CreateLiteralNodeMessage(float32LiteralNode.Type, float32LiteralNode.Value.ToString(CultureInfo.InvariantCulture)), - Float64LiteralNode float64LiteralNode => CreateLiteralNodeMessage(float64LiteralNode.Type, float64LiteralNode.Value.ToString(CultureInfo.InvariantCulture)), - I8LiteralNode i8LiteralNode => CreateLiteralNodeMessage(i8LiteralNode.Type, i8LiteralNode.Value.ToString()), - I16LiteralNode i16LiteralNode => CreateLiteralNodeMessage(i16LiteralNode.Type, i16LiteralNode.Value.ToString()), - I32LiteralNode i32LiteralNode => CreateLiteralNodeMessage(i32LiteralNode.Type, i32LiteralNode.Value.ToString()), - I64LiteralNode i64LiteralNode => CreateLiteralNodeMessage(i64LiteralNode.Type, i64LiteralNode.Value.ToString()), - U8LiteralNode u8LiteralNode => CreateLiteralNodeMessage(u8LiteralNode.Type, u8LiteralNode.Value.ToString()), - U16LiteralNode u16LiteralNode => CreateLiteralNodeMessage(u16LiteralNode.Type, u16LiteralNode.Value.ToString()), - U32LiteralNode u32LiteralNode => CreateLiteralNodeMessage(u32LiteralNode.Type, u32LiteralNode.Value.ToString()), - U64LiteralNode u64LiteralNode => CreateLiteralNodeMessage(u64LiteralNode.Type, u64LiteralNode.Value.ToString()), + FuncNode funcNode => CreateFuncPrototypeMessage(funcNode.Prototype), + FuncPrototypeNode funcPrototypeNode => CreateFuncPrototypeMessage(funcPrototypeNode), + FuncIdentifierNode funcIdentifierNode => CreateFuncIdentifierMessage(funcIdentifierNode, compilationUnit), + FuncParameterNode funcParameterNode => CreateTypeNameMessage("Function parameter", funcParameterNode.Name, funcParameterNode.Type), + VariableIdentifierNode variableIdentifierNode => CreateTypeNameMessage("Variable", variableIdentifierNode.Name, variableIdentifierNode.Type), + VariableDeclarationNode variableDeclarationNode => CreateTypeNameMessage("Variable declaration", variableDeclarationNode.Name, variableDeclarationNode.Type), + StructFieldAccessNode structFieldAccessNode => CreateTypeNameMessage("Struct field", $"{structFieldAccessNode.Target.Type}.{structFieldAccessNode.Field}", structFieldAccessNode.Type), + CStringLiteralNode cStringLiteralNode => CreateLiteralMessage(cStringLiteralNode.Type, '"' + cStringLiteralNode.Value + '"'), + StringLiteralNode stringLiteralNode => CreateLiteralMessage(stringLiteralNode.Type, '"' + stringLiteralNode.Value + '"'), + BoolLiteralNode boolLiteralNode => CreateLiteralMessage(boolLiteralNode.Type, boolLiteralNode.Value.ToString()), + Float32LiteralNode float32LiteralNode => CreateLiteralMessage(float32LiteralNode.Type, float32LiteralNode.Value.ToString(CultureInfo.InvariantCulture)), + Float64LiteralNode float64LiteralNode => CreateLiteralMessage(float64LiteralNode.Type, float64LiteralNode.Value.ToString(CultureInfo.InvariantCulture)), + I8LiteralNode i8LiteralNode => CreateLiteralMessage(i8LiteralNode.Type, i8LiteralNode.Value.ToString()), + I16LiteralNode i16LiteralNode => CreateLiteralMessage(i16LiteralNode.Type, i16LiteralNode.Value.ToString()), + I32LiteralNode i32LiteralNode => CreateLiteralMessage(i32LiteralNode.Type, i32LiteralNode.Value.ToString()), + I64LiteralNode i64LiteralNode => CreateLiteralMessage(i64LiteralNode.Type, i64LiteralNode.Value.ToString()), + U8LiteralNode u8LiteralNode => CreateLiteralMessage(u8LiteralNode.Type, u8LiteralNode.Value.ToString()), + U16LiteralNode u16LiteralNode => CreateLiteralMessage(u16LiteralNode.Type, u16LiteralNode.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 - ExpressionNode expressionNode => CreateGenericExpressionNodeMessage(expressionNode), - // Explicit null returns, can be removed when the default is null instead of the debug type + ExpressionNode expressionNode => $""" + **Expression** `{expressionNode.GetType().Name}` + ```nub + {expressionNode.Type} + ``` + """, BlockNode => null, - StatementNode statementNode => CreateGenericStatementNodeMessage(statementNode), _ => hoveredNode.GetType().Name }; } - private static string CreateLiteralNodeMessage(NubType type, string value) + private static string CreateLiteralMessage(NubType type, string value) { return $""" **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 $""" - **Variable** `{name}` + **{description}** `{name}` ```nub {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); 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 externText = funcPrototypeNode.ExternSymbol != null ? $"extern \"{funcPrototypeNode.ExternSymbol}\" " : ""; return $""" - **Function** `{funcPrototypeNode.Name}` + **Function** `{funcPrototypeNode.Module}::{funcPrototypeNode.Name}` ```nub - {externText}func {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} + {externText}func {funcPrototypeNode.Module}::{funcPrototypeNode.Name}({parameterText}): {funcPrototypeNode.ReturnType} ``` """; }