Skip to content

Commit 93dea2c

Browse files
committed
[lsp] Go to implementation.
#126
1 parent e3ad2f9 commit 93dea2c

1 file changed

Lines changed: 42 additions & 1 deletion

File tree

‎editors/lsp/lsp.fu‎

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,23 @@ public abstract class FusionLanguageServer : FuSemaHost
143143
return $"{{ \"uri\": \"{file.Filename}\", \"range\": {{ \"start\": {{ \"line\": {line}, \"character\" : {character} }}, \"end\": {{ \"line\": {line}, \"character\" : {character} }} }} }}";
144144
}
145145

146+
bool PushLocation(int loc, StringWriter! writer, bool haveLocation)
147+
{
148+
if (loc <= 0)
149+
return haveLocation;
150+
if (haveLocation)
151+
writer.Write(", ");
152+
writer.Write(GetLocation(loc));
153+
return true;
154+
}
155+
146156
bool Handle!(Dictionary<string(), JsonElement#> request)
147157
{
148158
Dictionary<string(), JsonElement#> params = request["params"].GetObject();
149159
string method = request["method"].GetString();
150160
switch (method) {
151161
case "initialize":
152-
Respond(request, $"\"result\": {{ \"capabilities\": {{ \"textDocumentSync\": 1, \"hoverProvider\": true, \"definitionProvider\": true }}, \"serverInfo\": {{ \"name\": \"Fusion\", \"version\": \"3.3.7\" }} }}"); // TODO: version
162+
Respond(request, $"\"result\": {{ \"capabilities\": {{ \"textDocumentSync\": 1, \"hoverProvider\": true, \"definitionProvider\": true, \"implementationProvider\": true }}, \"serverInfo\": {{ \"name\": \"Fusion\", \"version\": \"3.3.7\" }} }}"); // TODO: version
153163
JsonElement pid = params["processId"];
154164
if (pid.IsNumber())
155165
WatchClientProcess(GetInt(pid));
@@ -191,6 +201,37 @@ public abstract class FusionLanguageServer : FuSemaHost
191201
else
192202
Respond(request, "\"result\": " + GetLocation(symbol.Loc));
193203
break;
204+
case "textDocument/implementation":
205+
FuProgram() program;
206+
this.Program = program;
207+
FuSymbol? symbol = FindDefinition(params);
208+
StringWriter() writer;
209+
bool haveLocation = false;
210+
switch (symbol) {
211+
case null:
212+
break;
213+
case FuClass klass:
214+
foreach (FuClass subclass in program.Classes) {
215+
if (klass.IsSameOrBaseOf(subclass))
216+
haveLocation = PushLocation(subclass.Loc, writer, haveLocation);
217+
}
218+
break;
219+
case FuMethod:
220+
assert symbol.Parent is FuClass klass;
221+
foreach (FuClass subclass in program.Classes) {
222+
if (klass.IsSameOrBaseOf(subclass) && subclass.Contains(symbol))
223+
haveLocation = PushLocation(subclass.TryLookup(symbol.Name, false).Loc, writer, haveLocation);
224+
}
225+
break;
226+
default:
227+
haveLocation = PushLocation(symbol.Loc, writer, false);
228+
break;
229+
}
230+
if (haveLocation)
231+
Respond(request, $"\"result\": [ {writer.ToString()} ]");
232+
else
233+
Respond(request, "\"result\": null");
234+
break;
194235
default:
195236
if (request.ContainsKey("id"))
196237
RespondError(request, -32601, "Method not found");

0 commit comments

Comments
 (0)