114 lines
3.2 KiB
C#
114 lines
3.2 KiB
C#
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.SourcePath,
|
|
Range = new Range(node.Tokens.First().Span.StartLine - 1, node.Tokens.First().Span.StartColumn - 1, node.Tokens.Last().Span.EndLine - 1, node.Tokens.Last().Span.EndColumn - 1)
|
|
};
|
|
}
|
|
|
|
public static Location ToLocation(this Token token)
|
|
{
|
|
return new Location
|
|
{
|
|
Uri = token.Span.SourcePath,
|
|
Range = new Range(token.Span.StartLine - 1, token.Span.StartColumn - 1, token.Span.EndLine - 1, token.Span.EndColumn - 1)
|
|
};
|
|
}
|
|
|
|
public static bool ContainsPosition(this Token token, int line, int character)
|
|
{
|
|
var startLine = token.Span.StartLine - 1;
|
|
var startChar = token.Span.StartColumn - 1;
|
|
var endLine = token.Span.EndLine - 1;
|
|
var endChar = token.Span.EndColumn - 1;
|
|
|
|
if (line < startLine || line > endLine) return false;
|
|
|
|
if (line > startLine && line < endLine) return true;
|
|
|
|
if (startLine == endLine)
|
|
{
|
|
return character >= startChar && character <= endChar;
|
|
}
|
|
|
|
if (line == startLine)
|
|
{
|
|
return character >= startChar;
|
|
}
|
|
|
|
if (line == endLine)
|
|
{
|
|
return character <= endChar;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static bool ContainsPosition(this Node node, int line, int character)
|
|
{
|
|
if (node.Tokens.Count == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var span = node.Tokens.First().Span;
|
|
|
|
var startLine = span.StartLine - 1;
|
|
var startChar = span.StartColumn - 1;
|
|
var endLine = span.EndLine - 1;
|
|
var endChar = span.EndColumn - 1;
|
|
|
|
if (line < startLine || line > endLine) return false;
|
|
|
|
if (line > startLine && line < endLine) return true;
|
|
|
|
if (startLine == endLine)
|
|
{
|
|
return character >= startChar && character <= endChar;
|
|
}
|
|
|
|
if (line == startLine)
|
|
{
|
|
return character >= startChar;
|
|
}
|
|
|
|
if (line == endLine)
|
|
{
|
|
return character <= endChar;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static FuncNode? FunctionAtPosition(this List<TopLevelNode> compilationUnit, int line, int character)
|
|
{
|
|
return compilationUnit
|
|
.OfType<FuncNode>()
|
|
.FirstOrDefault(x => x.ContainsPosition(line, character));
|
|
}
|
|
|
|
public static Node? DeepestNodeAtPosition(this List<TopLevelNode> compilationUnit, int line, int character)
|
|
{
|
|
return compilationUnit
|
|
.SelectMany(x => x.DescendantsAndSelf())
|
|
.Where(n => n.ContainsPosition(line, character))
|
|
.OrderBy(n => n.Tokens.First().Span.StartLine)
|
|
.ThenBy(n => n.Tokens.First().Span.StartColumn)
|
|
.LastOrDefault();
|
|
}
|
|
} |