Skip to content

Commit

Permalink
Merge branch 'master' into fix-build-zig-lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
PanSashko committed Sep 15, 2024
2 parents 1617fc8 + 68667a7 commit 930ef8b
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 35 deletions.
12 changes: 6 additions & 6 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions src/DocumentScope.zig
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub const DeclarationLookupContext = struct {
};

/// Assumes that the `node` is not a container_field of a struct tuple field.
/// Returns a `.identifier` or `.builtin` token.
fn getDeclNameToken(tree: Ast, node: Ast.Node.Index) ?Ast.TokenIndex {
const tags = tree.nodes.items(.tag);
const token_tags = tree.tokens.items(.tag);
Expand Down Expand Up @@ -130,8 +131,10 @@ fn getDeclNameToken(tree: Ast, node: Ast.Node.Index) ?Ast.TokenIndex {
};

if (token_index >= tree.tokens.len) return null;
if (token_tags[token_index] != .identifier) return null;
return token_index;
return switch (token_tags[token_index]) {
.identifier, .builtin => token_index,
else => null,
};
}

pub const Declaration = union(enum) {
Expand Down Expand Up @@ -254,6 +257,7 @@ pub const Declaration = union(enum) {
return std.meta.eql(a, b);
}

/// Returns a `.identifier` or `.builtin` token.
pub fn nameToken(decl: Declaration, tree: Ast) Ast.TokenIndex {
return switch (decl) {
.ast_node => |n| getDeclNameToken(tree, n).?,
Expand Down Expand Up @@ -863,6 +867,7 @@ noinline fn walkContainerDecl(
container_field.convertToNonTupleLike(tree.nodes);
if (container_field.ast.tuple_like) continue;
const main_token = container_field.ast.main_token;
if (token_tags[main_token] != .identifier) continue;
try scope.pushDeclaration(main_token, .{ .ast_node = decl }, .field);

if (is_enum_or_tagged_union) {
Expand Down
12 changes: 6 additions & 6 deletions src/ZigCompileServer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -119,21 +119,21 @@ fn bswap(x: anytype) @TypeOf(x) {

const T = @TypeOf(x);
switch (@typeInfo(T)) {
.Enum => return @as(T, @enumFromInt(@byteSwap(@intFromEnum(x)))),
.Int => return @byteSwap(x),
.Struct => |info| switch (info.layout) {
.Extern => {
.@"enum" => return @as(T, @enumFromInt(@byteSwap(@intFromEnum(x)))),
.int => return @byteSwap(x),
.@"struct" => |info| switch (info.layout) {
.@"extern" => {
var result: T = undefined;
inline for (info.fields) |field| {
@field(result, field.name) = bswap(@field(x, field.name));
}
return result;
},
.Packed => {
.@"packed" => {
const I = info.backing_integer.?;
return @as(T, @bitCast(@byteSwap(@as(I, @bitCast(x)))));
},
.Auto => @compileError("auto layout struct"),
.auto => @compileError("auto layout struct"),
},
else => @compileError("bswap on type " ++ @typeName(T)),
}
Expand Down
23 changes: 15 additions & 8 deletions src/analysis.zig
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ pub fn isSnakeCase(name: []const u8) bool {
/// if the `source_index` points to `@name`, the source ___location of `name` without the `@` is returned.
/// if the `source_index` points to `@"name"`, the source ___location of `name` is returned.
pub fn identifierLocFromIndex(tree: Ast, source_index: usize) ?offsets.Loc {
std.debug.assert(source_index < tree.source.len);
std.debug.assert(source_index <= tree.source.len);

var start = source_index;
while (start > 0 and isSymbolChar(tree.source[start - 1])) {
Expand All @@ -617,17 +617,17 @@ pub fn identifierLocFromIndex(tree: Ast, source_index: usize) ?offsets.Loc {

test identifierLocFromIndex {
var tree = try Ast.parse(std.testing.allocator,
\\;name; ;@builtin; ;@"escaped";
\\;name; ;@builtin; ;@"escaped";end
, .zig);
defer tree.deinit(std.testing.allocator);

try std.testing.expectEqualSlices(
std.zig.Token.Tag,
&.{
.semicolon, .identifier, .semicolon,
.semicolon, .builtin, .semicolon,
.semicolon, .identifier, .semicolon,
.eof,
.semicolon, .identifier, .semicolon,
.semicolon, .builtin, .semicolon,
.semicolon, .identifier, .semicolon,
.identifier, .eof,
},
tree.tokens.items(.tag),
);
Expand All @@ -649,6 +649,13 @@ test identifierLocFromIndex {
try std.testing.expectEqual(@as(?offsets.Loc, .{ .start = 22, .end = 29 }), identifierLocFromIndex(tree, 22));
try std.testing.expectEqual(@as(?offsets.Loc, .{ .start = 22, .end = 29 }), identifierLocFromIndex(tree, 25));
try std.testing.expectEqual(@as(?offsets.Loc, .{ .start = 22, .end = 29 }), identifierLocFromIndex(tree, 29));

std.debug.assert(std.mem.eql(u8, "end", offsets.locToSlice(tree.source, .{ .start = 31, .end = 34 })));
try std.testing.expectEqual(@as(?offsets.Loc, null), identifierLocFromIndex(tree, 30));
try std.testing.expectEqual(@as(?offsets.Loc, .{ .start = 31, .end = 34 }), identifierLocFromIndex(tree, 31));
try std.testing.expectEqual(@as(?offsets.Loc, .{ .start = 31, .end = 34 }), identifierLocFromIndex(tree, 32));
try std.testing.expectEqual(@as(?offsets.Loc, .{ .start = 31, .end = 34 }), identifierLocFromIndex(tree, 33));
try std.testing.expectEqual(@as(?offsets.Loc, .{ .start = 31, .end = 34 }), identifierLocFromIndex(tree, 34));
}

/// Resolves variable declarations consisting of chains of imports and field accesses of containers
Expand Down Expand Up @@ -2066,8 +2073,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e

for (start..end + 1, 0..) |token_index, i| {
const slice = tree.tokenSlice(@intCast(token_index));
const carriage_return_ending: usize = if (slice[slice.len - 2] == '\r') 2 else 1;
length += slice.len - carriage_return_ending - 2 + @intFromBool(i != 0);
length += slice.len - 2 + @intFromBool(i != 0);
}

const string_literal_type = try analyser.ip.get(analyser.gpa, .{ .pointer_type = .{
Expand Down Expand Up @@ -3598,6 +3604,7 @@ pub const DeclWithHandle = struct {
return a.decl.eql(b.decl) and std.mem.eql(u8, a.handle.uri, b.handle.uri);
}

/// Returns a `.identifier` or `.builtin` token.
pub fn nameToken(self: DeclWithHandle) Ast.TokenIndex {
return self.decl.nameToken(self.handle.tree);
}
Expand Down
21 changes: 16 additions & 5 deletions src/offsets.zig
Original file line number Diff line number Diff line change
Expand Up @@ -233,19 +233,24 @@ fn identifierIndexToLoc(tree: Ast, source_index: usize) Loc {
return .{ .start = source_index, .end = index };
}

/// Support formats:
/// - `foo`
/// - `@"foo"`
/// - `@foo`
pub fn identifierIndexToNameLoc(text: [:0]const u8, source_index: usize) Loc {
if (text[source_index] == '@') {
std.debug.assert(text[source_index + 1] == '\"');
if (text[source_index] == '@' and text[source_index + 1] == '\"') {
const start_index = source_index + 2;
var index: usize = start_index;
while (true) : (index += 1) {
if (text[index] == '\"') {
break;
switch (text[index]) {
'\n', '\"' => break,
else => {},
}
}
return .{ .start = start_index, .end = index };
} else {
var index: usize = source_index;
if (text[index] == '@') index += 1;
while (true) : (index += 1) {
switch (text[index]) {
'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
Expand All @@ -268,14 +273,20 @@ test identifierIndexToNameLoc {
try std.testing.expectEqualStrings("hello", identifierIndexToNameSlice("@\"hello\"", 0));
try std.testing.expectEqualStrings("hello", identifierIndexToNameSlice("@\"hello\" world", 0));
try std.testing.expectEqualStrings("world", identifierIndexToNameSlice("@\"hello\" @\"world\"", 9));

try std.testing.expectEqualStrings("@hello", identifierIndexToNameSlice("@hello", 0));
}

pub fn identifierIndexToNameSlice(text: [:0]const u8, source_index: usize) []const u8 {
return locToSlice(text, identifierIndexToNameLoc(text, source_index));
}

pub fn identifierTokenToNameLoc(tree: Ast, identifier_token: Ast.TokenIndex) Loc {
std.debug.assert(tree.tokens.items(.tag)[identifier_token] == .identifier);
std.debug.assert(switch (tree.tokens.items(.tag)[identifier_token]) {
.builtin => true, // The Zig parser likes to emit .builtin where a identifier would be expected
.identifier => true,
else => false,
});
return identifierIndexToNameLoc(tree.source, tree.tokens.items(.start)[identifier_token]);
}

Expand Down
17 changes: 16 additions & 1 deletion src/snippets.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ pub const top_level_decl_data = [_]Snipped{
.{ .label = "union tagged", .kind = .Snippet, .text = "const $1 = union(${2:enum}) {$0};" },
.{ .label = "test", .kind = .Snippet, .text = "test \"$1\" {$0}" },
.{ .label = "main", .kind = .Snippet, .text = "pub fn main() !void {$0}" },
.{ .label = "std_options", .kind = .Snippet, .text = "pub const std_options: std.Options = .{${0}};" },
.{ .label = "std_options", .kind = .Snippet, .text = "pub const std_options: std.Options = .{$0};" },
.{ .label = "panic", .kind = .Snippet, .text =
\\pub fn panic(
\\ msg: []const u8,
\\ trace: ?*std.builtin.StackTrace,
\\ ret_addr: ?usize,
\\) noreturn {$0}
},
};

pub const generic = [_]Snipped{
Expand Down Expand Up @@ -85,6 +92,14 @@ pub const generic = [_]Snipped{
.{ .label = "log warn", .kind = .Snippet, .text = "std.log.warn(\"$1\", .{$0});" },
.{ .label = "log info", .kind = .Snippet, .text = "std.log.info(\"$1\", .{$0});" },
.{ .label = "log debug", .kind = .Snippet, .text = "std.log.debug(\"$1\", .{$0});" },
.{ .label = "format", .kind = .Snippet, .text =
\\pub fn format(
\\ ${1:self}: ${2:@This()},
\\ comptime fmt: []const u8,
\\ options: std.fmt.FormatOptions,
\\ writer: anytype,
\\) !void {$0}
},

// types
.{ .label = "anyerror", .kind = .Keyword },
Expand Down
2 changes: 1 addition & 1 deletion tests/lsp_features/folding_range.zig
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ test "multi-line string literal" {
\\ \\world
\\;
, &.{
.{ .startLine = 1, .startCharacter = 4, .endLine = 3, .endCharacter = 0 },
.{ .startLine = 1, .startCharacter = 4, .endLine = 2, .endCharacter = 11 },
});
}

Expand Down
2 changes: 0 additions & 2 deletions tests/lsp_features/hover.zig
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@ test "string literal" {
\\```zig
\\const foo =
\\ \\ipsum lorem
\\
\\```
\\```zig
\\(*const [11:0]u8)
Expand All @@ -240,7 +239,6 @@ test "string literal" {
\\const foo =
\\ \\ipsum lorem
\\ \\dolor sit amet
\\
\\```
\\```zig
\\(*const [26:0]u8)
Expand Down
20 changes: 16 additions & 4 deletions tests/lsp_features/semantic_tokens.zig
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,9 @@ test "string literals" {
.{ "const", .keyword, .{} },
.{ "gamma", .variable, .{ .declaration = true } },
.{ "=", .operator, .{} },
// TODO remove the newline
.{ "\\\\hello\n", .string, .{} },
.{ "\\\\world\n", .string, .{} },
.{ "\\\\\n", .string, .{} },
.{ "\\\\hello", .string, .{} },
.{ "\\\\world", .string, .{} },
.{ "\\\\", .string, .{} },
});
}

Expand Down Expand Up @@ -1789,6 +1788,19 @@ test "weird code" {
.{ "=", .operator, .{} },
.{ "5", .number, .{} },
});
try testSemanticTokens(
\\const foo = enum {
\\ @"a",
\\ @b,
\\};
, &.{
.{ "const", .keyword, .{} },
.{ "foo", .@"enum", .{ .declaration = true } },
.{ "=", .operator, .{} },
.{ "enum", .keyword, .{} },
.{ "@\"a\"", .enumMember, .{ .declaration = true } },
.{ "@b", .enumMember, .{ .declaration = true } },
});
}

const TokenData = struct {
Expand Down

0 comments on commit 930ef8b

Please sign in to comment.