Skip to content

Commit 3663cd3

Browse files
Fix Go to Type Definition (#1352)
1 parent d1d4e60 commit 3663cd3

File tree

3 files changed

+51
-31
lines changed

3 files changed

+51
-31
lines changed

src/Server.zig

+8-8
Original file line numberDiff line numberDiff line change
@@ -883,13 +883,13 @@ fn gotoDefinitionHandler(
883883
arena: std.mem.Allocator,
884884
request: types.DefinitionParams,
885885
) Error!ResultType("textDocument/definition") {
886-
return server.gotoHandler(arena, true, request);
886+
return server.gotoHandler(arena, .definition, request);
887887
}
888888

889889
fn gotoHandler(
890890
server: *Server,
891891
arena: std.mem.Allocator,
892-
comptime resolve_alias: bool,
892+
comptime kind: goto.GotoKind,
893893
request: types.DefinitionParams,
894894
) Error!ResultType("textDocument/definition") {
895895
if (request.position.character == 0) return null;
@@ -901,12 +901,12 @@ fn gotoHandler(
901901
defer analyser.deinit();
902902

903903
return .{
904-
.array_of_DefinitionLink = try goto.goto(&analyser, &server.document_store, arena, handle, source_index, resolve_alias, server.offset_encoding) orelse return null,
904+
.array_of_DefinitionLink = try goto.goto(&analyser, &server.document_store, arena, handle, source_index, kind, server.offset_encoding) orelse return null,
905905
};
906906
}
907907

908-
fn gotoTypeDeclarationHandler(server: *Server, arena: std.mem.Allocator, request: types.TypeDefinitionParams) Error!ResultType("textDocument/typeDefinition") {
909-
const response = (try server.gotoHandler(arena, false, .{
908+
fn gotoTypeDefinitionHandler(server: *Server, arena: std.mem.Allocator, request: types.TypeDefinitionParams) Error!ResultType("textDocument/typeDefinition") {
909+
const response = (try server.gotoHandler(arena, .type_definition, .{
910910
.textDocument = request.textDocument,
911911
.position = request.position,
912912
.workDoneToken = request.workDoneToken,
@@ -916,7 +916,7 @@ fn gotoTypeDeclarationHandler(server: *Server, arena: std.mem.Allocator, request
916916
}
917917

918918
fn gotoImplementationHandler(server: *Server, arena: std.mem.Allocator, request: types.ImplementationParams) Error!ResultType("textDocument/implementation") {
919-
const response = (try server.gotoHandler(arena, true, .{
919+
const response = (try server.gotoHandler(arena, .definition, .{
920920
.textDocument = request.textDocument,
921921
.position = request.position,
922922
.workDoneToken = request.workDoneToken,
@@ -926,7 +926,7 @@ fn gotoImplementationHandler(server: *Server, arena: std.mem.Allocator, request:
926926
}
927927

928928
fn gotoDeclarationHandler(server: *Server, arena: std.mem.Allocator, request: types.DeclarationParams) Error!ResultType("textDocument/declaration") {
929-
const response = (try server.gotoHandler(arena, false, .{
929+
const response = (try server.gotoHandler(arena, .declaration, .{
930930
.textDocument = request.textDocument,
931931
.position = request.position,
932932
.workDoneToken = request.workDoneToken,
@@ -1614,7 +1614,7 @@ pub fn sendRequestSync(server: *Server, arena: std.mem.Allocator, comptime metho
16141614
.@"textDocument/completion" => try server.completionHandler(arena, params),
16151615
.@"textDocument/signatureHelp" => try server.signatureHelpHandler(arena, params),
16161616
.@"textDocument/definition" => try server.gotoDefinitionHandler(arena, params),
1617-
.@"textDocument/typeDefinition" => try server.gotoTypeDeclarationHandler(arena, params),
1617+
.@"textDocument/typeDefinition" => try server.gotoTypeDefinitionHandler(arena, params),
16181618
.@"textDocument/implementation" => try server.gotoImplementationHandler(arena, params),
16191619
.@"textDocument/declaration" => try server.gotoDeclarationHandler(arena, params),
16201620
.@"textDocument/hover" => try server.hoverHandler(arena, params),

src/analysis.zig

+12-10
Original file line numberDiff line numberDiff line change
@@ -1842,14 +1842,14 @@ pub const TypeWithHandle = struct {
18421842
};
18431843
}
18441844

1845-
pub fn definitionToken(self: TypeWithHandle) ?Ast.TokenIndex {
1846-
if (self.type.is_type_val) {
1847-
switch (self.type.data) {
1848-
.other => |n| return self.handle.tree.firstToken(n),
1849-
else => {},
1850-
}
1851-
}
1852-
return null;
1845+
pub fn typeDefinitionToken(self: TypeWithHandle) ?TokenWithHandle {
1846+
return switch (self.type.data) {
1847+
.other => |n| .{
1848+
.token = self.handle.tree.firstToken(n),
1849+
.handle = self.handle,
1850+
},
1851+
else => null,
1852+
};
18531853
}
18541854

18551855
pub fn docComments(self: TypeWithHandle, allocator: std.mem.Allocator) !?[]const u8 {
@@ -2574,8 +2574,10 @@ pub const DeclWithHandle = struct {
25742574
else => {},
25752575
}
25762576
if (try self.resolveType(analyser)) |resolved_type| {
2577-
if (resolved_type.definitionToken()) |token| {
2578-
return .{ .token = token, .handle = resolved_type.handle };
2577+
if (resolved_type.type.is_type_val) {
2578+
if (resolved_type.typeDefinitionToken()) |token| {
2579+
return token;
2580+
}
25792581
}
25802582
}
25812583
}

src/features/goto.zig

+31-13
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,33 @@ const tracy = @import("../tracy.zig");
1111
const Analyser = @import("../analysis.zig");
1212
const DocumentStore = @import("../DocumentStore.zig");
1313

14+
pub const GotoKind = enum {
15+
declaration,
16+
definition,
17+
type_definition,
18+
};
19+
1420
pub fn gotoDefinitionSymbol(
1521
analyser: *Analyser,
1622
name_range: types.Range,
1723
decl_handle: Analyser.DeclWithHandle,
18-
resolve_alias: bool,
24+
kind: GotoKind,
1925
offset_encoding: offsets.Encoding,
2026
) error{OutOfMemory}!?types.DefinitionLink {
2127
const tracy_zone = tracy.trace(@src());
2228
defer tracy_zone.end();
2329

24-
const token_handle = try decl_handle.definitionToken(analyser, resolve_alias);
30+
const token_handle = switch (kind) {
31+
.declaration => try decl_handle.definitionToken(analyser, false),
32+
.definition => try decl_handle.definitionToken(analyser, true),
33+
.type_definition => blk: {
34+
const resolved_type = try decl_handle.resolveType(analyser) orelse
35+
return null;
36+
37+
break :blk resolved_type.typeDefinitionToken() orelse
38+
return null;
39+
},
40+
};
2541
const target_range = offsets.tokenToRange(token_handle.handle.tree, token_handle.token, offset_encoding);
2642

2743
return types.DefinitionLink{
@@ -37,6 +53,7 @@ pub fn gotoDefinitionLabel(
3753
arena: std.mem.Allocator,
3854
handle: *const DocumentStore.Handle,
3955
pos_index: usize,
56+
kind: GotoKind,
4057
offset_encoding: offsets.Encoding,
4158
) error{OutOfMemory}!?types.DefinitionLink {
4259
const tracy_zone = tracy.trace(@src());
@@ -46,15 +63,15 @@ pub fn gotoDefinitionLabel(
4663
const name_loc = Analyser.identifierLocFromPosition(pos_index, handle) orelse return null;
4764
const name = offsets.locToSlice(handle.text, name_loc);
4865
const decl = (try Analyser.getLabelGlobal(pos_index, handle, name)) orelse return null;
49-
return try gotoDefinitionSymbol(analyser, offsets.locToRange(handle.text, name_loc, offset_encoding), decl, false, offset_encoding);
66+
return try gotoDefinitionSymbol(analyser, offsets.locToRange(handle.text, name_loc, offset_encoding), decl, kind, offset_encoding);
5067
}
5168

5269
pub fn gotoDefinitionGlobal(
5370
analyser: *Analyser,
5471
arena: std.mem.Allocator,
5572
handle: *const DocumentStore.Handle,
5673
pos_index: usize,
57-
resolve_alias: bool,
74+
kind: GotoKind,
5875
offset_encoding: offsets.Encoding,
5976
) error{OutOfMemory}!?types.DefinitionLink {
6077
const tracy_zone = tracy.trace(@src());
@@ -64,14 +81,15 @@ pub fn gotoDefinitionGlobal(
6481
const name_loc = Analyser.identifierLocFromPosition(pos_index, handle) orelse return null;
6582
const name = offsets.locToSlice(handle.text, name_loc);
6683
const decl = (try analyser.getSymbolGlobal(pos_index, handle, name)) orelse return null;
67-
return try gotoDefinitionSymbol(analyser, offsets.locToRange(handle.text, name_loc, offset_encoding), decl, resolve_alias, offset_encoding);
84+
return try gotoDefinitionSymbol(analyser, offsets.locToRange(handle.text, name_loc, offset_encoding), decl, kind, offset_encoding);
6885
}
6986

7087
pub fn gotoDefinitionEnumLiteral(
7188
analyser: *Analyser,
7289
arena: std.mem.Allocator,
7390
handle: *const DocumentStore.Handle,
7491
source_index: usize,
92+
kind: GotoKind,
7593
offset_encoding: offsets.Encoding,
7694
) error{OutOfMemory}!?types.DefinitionLink {
7795
const tracy_zone = tracy.trace(@src());
@@ -80,7 +98,7 @@ pub fn gotoDefinitionEnumLiteral(
8098
const name_loc = Analyser.identifierLocFromPosition(source_index, handle) orelse return null;
8199
const name = offsets.locToSlice(handle.text, name_loc);
82100
const decl = (try analyser.getSymbolEnumLiteral(arena, handle, source_index, name)) orelse return null;
83-
return try gotoDefinitionSymbol(analyser, offsets.locToRange(handle.text, name_loc, offset_encoding), decl, false, offset_encoding);
101+
return try gotoDefinitionSymbol(analyser, offsets.locToRange(handle.text, name_loc, offset_encoding), decl, kind, offset_encoding);
84102
}
85103

86104
pub fn gotoDefinitionBuiltin(
@@ -126,7 +144,7 @@ pub fn gotoDefinitionFieldAccess(
126144
handle: *const DocumentStore.Handle,
127145
source_index: usize,
128146
loc: offsets.Loc,
129-
resolve_alias: bool,
147+
kind: GotoKind,
130148
offset_encoding: offsets.Encoding,
131149
) error{OutOfMemory}!?[]const types.DefinitionLink {
132150
const tracy_zone = tracy.trace(@src());
@@ -139,7 +157,7 @@ pub fn gotoDefinitionFieldAccess(
139157
var locs = std.ArrayListUnmanaged(types.DefinitionLink){};
140158

141159
for (accesses) |access| {
142-
if (try gotoDefinitionSymbol(analyser, offsets.locToRange(handle.text, name_loc, offset_encoding), access, resolve_alias, offset_encoding)) |l|
160+
if (try gotoDefinitionSymbol(analyser, offsets.locToRange(handle.text, name_loc, offset_encoding), access, kind, offset_encoding)) |l|
143161
try locs.append(arena, l);
144162
}
145163

@@ -208,22 +226,22 @@ pub fn goto(
208226
arena: std.mem.Allocator,
209227
handle: *const DocumentStore.Handle,
210228
source_index: usize,
211-
resolve_alias: bool,
229+
kind: GotoKind,
212230
offset_encoding: offsets.Encoding,
213231
) !?[]const types.DefinitionLink {
214232
const pos_context = try Analyser.getPositionContext(arena, handle.text, source_index, true);
215233
var links = std.ArrayListUnmanaged(types.DefinitionLink){};
216234

217235
try links.append(arena, switch (pos_context) {
218236
.builtin => |loc| try gotoDefinitionBuiltin(document_store, handle, loc, offset_encoding),
219-
.var_access => try gotoDefinitionGlobal(analyser, arena, handle, source_index, resolve_alias, offset_encoding),
220-
.field_access => |loc| return try gotoDefinitionFieldAccess(analyser, arena, handle, source_index, loc, resolve_alias, offset_encoding),
237+
.var_access => try gotoDefinitionGlobal(analyser, arena, handle, source_index, kind, offset_encoding),
238+
.field_access => |loc| return try gotoDefinitionFieldAccess(analyser, arena, handle, source_index, loc, kind, offset_encoding),
221239
.import_string_literal,
222240
.cinclude_string_literal,
223241
.embedfile_string_literal,
224242
=> try gotoDefinitionString(document_store, arena, pos_context, handle, offset_encoding),
225-
.label => try gotoDefinitionLabel(analyser, arena, handle, source_index, offset_encoding),
226-
.enum_literal => try gotoDefinitionEnumLiteral(analyser, arena, handle, source_index, offset_encoding),
243+
.label => try gotoDefinitionLabel(analyser, arena, handle, source_index, kind, offset_encoding),
244+
.enum_literal => try gotoDefinitionEnumLiteral(analyser, arena, handle, source_index, kind, offset_encoding),
227245
else => null,
228246
} orelse return null);
229247

0 commit comments

Comments
 (0)