Skip to content

Commit 659a278

Browse files
committed
Improved vscode extension
1 parent cf7c040 commit 659a278

23 files changed

+963
-3776
lines changed

src/Yabal.Compiler/Yabal/Ast/LanguageType.cs

+9-2
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,24 @@ public override string ToString()
9999
StaticType.Integer => "int",
100100
StaticType.Boolean => "bool",
101101
StaticType.Void => "void",
102-
StaticType.Pointer => $"*{ElementType}",
102+
StaticType.Pointer => $"{ElementType}[]",
103103
StaticType.Struct => StructReference?.Name ?? "struct",
104104
StaticType.Assembly => "assembly",
105105
StaticType.Reference => $"ref {ElementType}",
106106
StaticType.Unknown => "unknown",
107107
StaticType.Char => "char",
108-
StaticType.Function => $"({string.Join(", ", FunctionType?.Parameters ?? new List<LanguageType>())}) => {FunctionType?.ReturnType}",
108+
StaticType.Function => GetFunctionName(),
109109
_ => throw new ArgumentOutOfRangeException()
110110
};
111111
}
112112

113+
private string GetFunctionName()
114+
{
115+
return FunctionType?.Parameters is null or { Count: 0 }
116+
? $"func<{FunctionType?.ReturnType ?? Void}>"
117+
: $"func<{string.Join(", ", FunctionType.Parameters)}, {FunctionType?.ReturnType ?? Void}>";
118+
}
119+
113120
public virtual bool Equals(LanguageType? other)
114121
{
115122
if (ReferenceEquals(null, other)) return false;

src/Yabal.Compiler/Yabal/Ast/Statement/FunctionDeclarationStatement.cs

+12-2
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ public record FunctionParameter(Identifier Name, LanguageType Type, bool HasDefa
1111

1212
public record FunctionName(SourceRange Range);
1313

14-
public record FunctionIdentifier(SourceRange Range, string Name) : FunctionName(Range)
14+
public record FunctionIdentifier(Identifier Identifier) : FunctionName(Identifier.Range)
1515
{
1616
public override string ToString()
1717
{
18-
return Name;
18+
return Identifier.Name;
1919
}
2020
}
2121

@@ -69,6 +69,14 @@ public override string ToString()
6969

7070
public bool IsDirectReference => true;
7171

72+
Identifier IVariable.Identifier => Name switch
73+
{
74+
FunctionIdentifier { Identifier: { } identifier } => identifier,
75+
FunctionOperator { Range: var range, Operator: var op } => new Identifier(range, $"operator:{op}"),
76+
FunctionCast { Range: var range } => new Identifier(range, $"cast:{ReturnType}"),
77+
_ => throw new NotSupportedException()
78+
};
79+
7280
Pointer IVariable.Pointer => Label;
7381

7482
LanguageType IVariable.Type => new(StaticType.Function, FunctionType: new LanguageFunction(ReturnType, Parameters.Select(i => i.Type).ToList()));
@@ -77,6 +85,8 @@ public override string ToString()
7785

7886
bool IVariable.Constant { get; set; } = true;
7987

88+
IEnumerable<Identifier> IVariable.References => References;
89+
8090
void IVariable.AddReference(Identifier identifierExpression)
8191
{
8292
References.Add(identifierExpression);

src/Yabal.Compiler/Yabal/Visitor/Variable.cs

+6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ public interface IVariable
99

1010
bool IsDirectReference { get; }
1111

12+
Identifier Identifier { get; }
13+
1214
Pointer Pointer { get; }
1315

1416
LanguageType Type { get; }
@@ -19,6 +21,8 @@ public interface IVariable
1921

2022
public bool Constant { get; set; }
2123

24+
IEnumerable<Identifier> References { get; }
25+
2226
void AddReference(Identifier identifierExpression);
2327

2428
void AddUsage();
@@ -49,6 +53,8 @@ public record Variable(
4953

5054
public List<Identifier> References { get; } = new();
5155

56+
IEnumerable<Identifier> IVariable.References => References;
57+
5258
void IVariable.AddReference(Identifier identifierExpression)
5359
{
5460
References.Add(identifierExpression);

src/Yabal.Compiler/Yabal/Visitor/YabalVisitor.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ public override Node VisitFunctionDeclaration(YabalParser.FunctionDeclarationCon
307307

308308
if (context.identifierName() is { } identifierName)
309309
{
310-
name = new FunctionIdentifier(SourceRange.From(identifierName, _file), identifierName.GetText());
310+
name = new FunctionIdentifier(new Identifier(SourceRange.From(identifierName, _file), identifierName.GetText()));
311311
}
312312
else if (context.operatorName() is { } operatorName)
313313
{

src/Yabal.Compiler/Yabal/YabalBuilder.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -973,20 +973,20 @@ private void AddStrings(InstructionBuilder builder)
973973

974974
public void DeclareFunction(Function function)
975975
{
976-
if (function.Name is FunctionIdentifier identifier)
976+
if (function.Name is FunctionIdentifier name)
977977
{
978-
if (!_functions.TryGetValue(identifier.Name, out var functions))
978+
if (!_functions.TryGetValue(name.Identifier.Name, out var functions))
979979
{
980980
functions = new List<Function>();
981-
_functions.Add(identifier.Name, functions);
981+
_functions.Add(name.Identifier.Name, functions);
982982
}
983983

984984
if (functions.Any(i =>
985985
i.Namespace.Equals(function.Namespace) &&
986986
i.Parameters.Count == function.Parameters.Count &&
987987
i.Parameters.Zip(function.Parameters).All(j => j.First.Type == j.Second.Type)))
988988
{
989-
throw new InvalidCodeException($"Function '{identifier.Name}' with the same parameters already exists.", identifier.Range);
989+
throw new InvalidCodeException($"Function '{name.Identifier.Name}' with the same parameters already exists.", name.Range);
990990
}
991991

992992
functions.Add(function);
@@ -1000,7 +1000,7 @@ public void DeclareFunction(Function function)
10001000

10011001
BinaryOperators.Add((op.Operator, function.Parameters[0].Type, function.Parameters[1].Type), function);
10021002
}
1003-
else if (function.Name is FunctionCast cast)
1003+
else if (function.Name is FunctionCast)
10041004
{
10051005
if (function.Parameters.Count != 1)
10061006
{

src/Yabal.LanguageServer/Document.cs

+5-14
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,14 @@
1212

1313
namespace Yabal.LanguageServer;
1414

15-
public class Document
15+
public class Document(DocumentUri uri, ILanguageServerFacade languageServer, TextDocumentContainer documentContainer)
1616
{
17-
private readonly TextDocumentContainer _documentContainer;
18-
private readonly ILanguageServerFacade _languageServer;
19-
private readonly string _uriString;
20-
21-
public Document(DocumentUri uri, ILanguageServerFacade languageServer, TextDocumentContainer documentContainer)
22-
{
23-
_languageServer = languageServer;
24-
_documentContainer = documentContainer;
25-
Uri = uri;
26-
_uriString = uri.ToString();
27-
}
17+
private readonly TextDocumentContainer _documentContainer = documentContainer;
18+
private readonly string _uriString = uri.ToString();
2819

2920
public YabalBuilder Builder { get; set; }
3021

31-
public DocumentUri Uri { get; }
22+
public DocumentUri Uri { get; } = uri;
3223

3324
public int? Version { get; set; }
3425

@@ -69,7 +60,7 @@ public async Task UpdateAsync(int? version, string text)
6960

7061
builder.Build();
7162

72-
_languageServer.TextDocument.PublishDiagnostics(new PublishDiagnosticsParams
63+
languageServer.TextDocument.PublishDiagnostics(new PublishDiagnosticsParams
7364
{
7465
Uri = Uri,
7566
Diagnostics = diagnostics

src/Yabal.LanguageServer/Extensions/RangeExtensions.cs

+40
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,44 @@ public static (Identifier?, Variable?) Find(this IEnumerable<Variable> variables
4343

4444
return default;
4545
}
46+
47+
public static (Identifier?, Function?) Find(this IEnumerable<Function> functions, Position position)
48+
{
49+
foreach (var function in functions)
50+
{
51+
if (function.Name is not FunctionIdentifier { Identifier: {} name })
52+
{
53+
continue;
54+
}
55+
56+
if (name.Range.IsInRange(position))
57+
{
58+
return (name, function);
59+
}
60+
61+
foreach (var identifier in function.References)
62+
{
63+
if (identifier.Range.IsInRange(position))
64+
{
65+
return (identifier, function);
66+
}
67+
}
68+
}
69+
70+
return default;
71+
}
72+
73+
public static (Identifier?, IVariable?) Find(this YabalBuilder builder, Position position)
74+
{
75+
(var identifier, IVariable? variable) = builder.Variables.Find(position);
76+
77+
if (identifier != null && variable != null)
78+
{
79+
return (identifier, variable);
80+
}
81+
82+
(identifier, variable) = builder.Functions.Find(position);
83+
84+
return (identifier, variable);
85+
}
4686
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System.Collections.Generic;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
5+
using OmniSharp.Extensions.LanguageServer.Protocol.Document;
6+
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
7+
8+
namespace Yabal.LanguageServer.Handlers;
9+
10+
public class DefinitionHandler(TextDocumentContainer documentContainer) : IDefinitionHandler
11+
{
12+
public Task<LocationOrLocationLinks?> Handle(DefinitionParams request, CancellationToken cancellationToken)
13+
{
14+
if (!documentContainer.Documents.TryGetValue(request.TextDocument.Uri, out var document))
15+
{
16+
return Task.FromResult<LocationOrLocationLinks?>(null);
17+
}
18+
19+
var (_, variable) = document.Builder.Find(request.Position);
20+
21+
if (variable == null)
22+
{
23+
return Task.FromResult<LocationOrLocationLinks?>(null);
24+
}
25+
26+
return Task.FromResult<LocationOrLocationLinks?>(new LocationOrLocationLinks(new LocationOrLocationLink(new Location
27+
{
28+
Uri = request.TextDocument.Uri,
29+
Range = variable.Identifier.Range.ToRange()
30+
})));
31+
}
32+
33+
public DefinitionRegistrationOptions GetRegistrationOptions(DefinitionCapability capability,
34+
ClientCapabilities clientCapabilities)
35+
{
36+
return new DefinitionRegistrationOptions
37+
{
38+
DocumentSelector = TextDocumentSelector.ForLanguage("yabal")
39+
};
40+
}
41+
}

src/Yabal.LanguageServer/Handlers/HighlightHandler.cs

+3-10
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,13 @@
88

99
namespace Yabal.LanguageServer.Handlers;
1010

11-
public class HighlightHandler : IDocumentHighlightHandler
11+
public class HighlightHandler(TextDocumentContainer documentContainer) : IDocumentHighlightHandler
1212
{
13-
private readonly TextDocumentContainer _documentContainer;
14-
15-
public HighlightHandler(TextDocumentContainer documentContainer)
16-
{
17-
_documentContainer = documentContainer;
18-
}
19-
2013
public Task<DocumentHighlightContainer?> Handle(DocumentHighlightParams request, CancellationToken cancellationToken)
2114
{
2215
var items = new List<DocumentHighlight>();
2316

24-
if (_documentContainer.Documents.TryGetValue(request.TextDocument.Uri, out var document))
17+
if (documentContainer.Documents.TryGetValue(request.TextDocument.Uri, out var document))
2518
{
2619
AddHighlights(request, document, items);
2720
}
@@ -31,7 +24,7 @@ public HighlightHandler(TextDocumentContainer documentContainer)
3124

3225
private static void AddHighlights(TextDocumentPositionParams request, Document document, List<DocumentHighlight> items)
3326
{
34-
var (_, variable) = document.Builder.Variables.Find(request.Position);
27+
var (_, variable) = document.Builder.Find(request.Position);
3528

3629
if (variable == null) return;
3730

src/Yabal.LanguageServer/Handlers/HoverHandler.cs

+9-11
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,20 @@
55
using OmniSharp.Extensions.LanguageServer.Protocol.Document;
66
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
77
using Yabal.Ast;
8+
using Yabal.Instructions;
89

910
namespace Yabal.LanguageServer.Handlers;
1011

11-
public class HoverHandler : IHoverHandler
12+
public class HoverHandler(TextDocumentContainer documentContainer) : IHoverHandler
1213
{
13-
private readonly TextDocumentContainer _documentContainer;
14-
15-
public HoverHandler(TextDocumentContainer documentContainer)
16-
{
17-
_documentContainer = documentContainer;
18-
}
19-
2014
public Task<Hover?> Handle(HoverParams request, CancellationToken cancellationToken)
2115
{
22-
if (!_documentContainer.Documents.TryGetValue(request.TextDocument.Uri, out var document))
16+
if (!documentContainer.Documents.TryGetValue(request.TextDocument.Uri, out var document))
2317
{
2418
return Task.FromResult<Hover?>(null);
2519
}
2620

27-
var (identifier, variable) = document.Builder.Variables.Find(request.Position);
21+
var (identifier, variable) = document.Builder.Find(request.Position);
2822

2923
if (identifier == null || variable == null)
3024
{
@@ -36,7 +30,11 @@ public HoverHandler(TextDocumentContainer documentContainer)
3630

3731
sb.AppendLine($"Type: {variable.Type} ");
3832
sb.AppendLine($"Size: {size} ");
39-
sb.AppendLine($"Variable address: {variable.Pointer.Address} ");
33+
34+
if (variable.Pointer is not InstructionLabel)
35+
{
36+
sb.AppendLine($"Variable address: {variable.Pointer.Address} ");
37+
}
4038

4139
if (variable.Initializer is IPointerSource { Pointer: {} pointer })
4240
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using OmniSharp.Extensions.LanguageServer.Protocol;
7+
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
8+
using OmniSharp.Extensions.LanguageServer.Protocol.Document;
9+
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
10+
11+
namespace Yabal.LanguageServer.Handlers;
12+
13+
public class RenameHandler(TextDocumentContainer documentContainer) : IRenameHandler
14+
{
15+
public Task<WorkspaceEdit?> Handle(RenameParams request, CancellationToken cancellationToken)
16+
{
17+
if (!documentContainer.Documents.TryGetValue(request.TextDocument.Uri, out var document))
18+
{
19+
return Task.FromResult<WorkspaceEdit?>(null);
20+
}
21+
22+
var (_, variable) = document.Builder.Find(request.Position);
23+
24+
if (variable == null)
25+
{
26+
return Task.FromResult<WorkspaceEdit?>(null);
27+
}
28+
29+
return Task.FromResult<WorkspaceEdit?>(new WorkspaceEdit
30+
{
31+
Changes = new Dictionary<DocumentUri, IEnumerable<TextEdit>>
32+
{
33+
[request.TextDocument.Uri] =
34+
[
35+
..variable.References
36+
.OrderByDescending(i => i.Range)
37+
.DistinctBy(i => i.Range.Index)
38+
.Select(i => new TextEdit
39+
{
40+
Range = i.Range.ToRange(),
41+
NewText = request.NewName
42+
}),
43+
new TextEdit
44+
{
45+
Range = variable.Identifier.Range.ToRange(),
46+
NewText = request.NewName
47+
}
48+
]
49+
}
50+
});
51+
}
52+
53+
public RenameRegistrationOptions GetRegistrationOptions(RenameCapability capability, ClientCapabilities clientCapabilities)
54+
{
55+
return new RenameRegistrationOptions
56+
{
57+
DocumentSelector = TextDocumentSelector.ForLanguage("yabal")
58+
};
59+
}
60+
}

0 commit comments

Comments
 (0)