Semantic highlighting improvements

This commit is contained in:
Alexandros Naskos 2020-06-27 20:45:58 +03:00
parent 6a830de271
commit 108a2dbd64
3 changed files with 53 additions and 4 deletions

View File

@ -153,6 +153,15 @@ pub fn isTypeFunction(tree: *ast.Tree, func: *ast.Node.FnProto) bool {
} }
} }
// @TODO
pub fn isGenericFunction(tree: *ast.Tree, func: *ast.Node.FnProto) bool {
for (func.paramsConst()) |param| {
if (param.param_type == .var_type or param.comptime_token != null) {
return true;
}
}
return false;
}
// STYLE // STYLE
pub fn isCamelCase(name: []const u8) bool { pub fn isCamelCase(name: []const u8) bool {
@ -899,6 +908,16 @@ pub const TypeWithHandle = struct {
return self.isContainer(.Keyword_struct) or self.isRoot(); return self.isContainer(.Keyword_struct) or self.isRoot();
} }
pub fn isNamespace(self: TypeWithHandle) bool {
if (!self.isStructType()) return false;
var idx: usize = 0;
while (self.type.data.other.iterate(idx)) |child| : (idx += 1) {
if (child.id == .ContainerField)
return false;
}
return true;
}
pub fn isEnumType(self: TypeWithHandle) bool { pub fn isEnumType(self: TypeWithHandle) bool {
return self.isContainer(.Keyword_enum); return self.isContainer(.Keyword_enum);
} }
@ -919,6 +938,18 @@ pub const TypeWithHandle = struct {
} }
} }
pub fn isGenericFunc(self: TypeWithHandle) bool {
switch (self.type.data) {
.other => |n| {
if (n.cast(ast.Node.FnProto)) |fn_proto| {
return isGenericFunction(self.handle.tree, fn_proto);
}
return false;
},
else => return false,
}
}
pub fn isFunc(self: TypeWithHandle) bool { pub fn isFunc(self: TypeWithHandle) bool {
switch (self.type.data) { switch (self.type.data) {
.other => |n| { .other => |n| {

View File

@ -86,7 +86,7 @@ const ClientCapabilities = struct {
var client_capabilities = ClientCapabilities{}; var client_capabilities = ClientCapabilities{};
const initialize_response = const initialize_response =
\\,"result": {"capabilities": {"signatureHelpProvider": {"triggerCharacters": ["(",","]},"textDocumentSync": 1,"renameProvider":true,"completionProvider": {"resolveProvider": false,"triggerCharacters": [".",":","@"]},"documentHighlightProvider": false,"hoverProvider": true,"codeActionProvider": false,"declarationProvider": true,"definitionProvider": true,"typeDefinitionProvider": true,"implementationProvider": false,"referencesProvider": false,"documentSymbolProvider": true,"colorProvider": false,"documentFormattingProvider": true,"documentRangeFormattingProvider": false,"foldingRangeProvider": false,"selectionRangeProvider": false,"workspaceSymbolProvider": false,"rangeProvider": false,"documentProvider": true,"workspace": {"workspaceFolders": {"supported": true,"changeNotifications": true}},"semanticTokensProvider": {"documentProvider": true,"legend": {"tokenTypes": ["type","struct","enum","union","parameter","variable","tagField","field","errorTag","function","keyword","comment","string","number","operator","builtin","label"],"tokenModifiers": ["definition","async","documentation", "generic"]}}}}} \\,"result": {"capabilities": {"signatureHelpProvider": {"triggerCharacters": ["(",","]},"textDocumentSync": 1,"renameProvider":true,"completionProvider": {"resolveProvider": false,"triggerCharacters": [".",":","@"]},"documentHighlightProvider": false,"hoverProvider": true,"codeActionProvider": false,"declarationProvider": true,"definitionProvider": true,"typeDefinitionProvider": true,"implementationProvider": false,"referencesProvider": false,"documentSymbolProvider": true,"colorProvider": false,"documentFormattingProvider": true,"documentRangeFormattingProvider": false,"foldingRangeProvider": false,"selectionRangeProvider": false,"workspaceSymbolProvider": false,"rangeProvider": false,"documentProvider": true,"workspace": {"workspaceFolders": {"supported": true,"changeNotifications": true}},"semanticTokensProvider": {"documentProvider": true,"legend": {"tokenTypes": ["namespace","type","struct","enum","union","parameter","variable","tagField","field","errorTag","function","keyword","comment","string","number","operator","builtin","label"],"tokenModifiers": ["definition","async","documentation", "generic"]}}}}}
; ;
const not_implemented_response = const not_implemented_response =

View File

@ -4,6 +4,7 @@ const analysis = @import("analysis.zig");
const ast = std.zig.ast; const ast = std.zig.ast;
const TokenType = enum(u32) { const TokenType = enum(u32) {
namespace,
type, type,
@"struct", @"struct",
@"enum", @"enum",
@ -165,7 +166,9 @@ const GapHighlighter = struct {
fn colorIdentifierBasedOnType(builder: *Builder, type_node: analysis.TypeWithHandle, target_tok: ast.TokenIndex, tok_mod: TokenModifiers) !void { fn colorIdentifierBasedOnType(builder: *Builder, type_node: analysis.TypeWithHandle, target_tok: ast.TokenIndex, tok_mod: TokenModifiers) !void {
if (type_node.type.is_type_val) { if (type_node.type.is_type_val) {
const tok_type = if (type_node.isStructType()) const tok_type = if (type_node.isNamespace())
.namespace
else if (type_node.isStructType())
.@"struct" .@"struct"
else if (type_node.isEnumType()) else if (type_node.isEnumType())
.@"enum" .@"enum"
@ -178,7 +181,11 @@ fn colorIdentifierBasedOnType(builder: *Builder, type_node: analysis.TypeWithHan
} else if (type_node.isTypeFunc()) { } else if (type_node.isTypeFunc()) {
try writeTokenMod(builder, target_tok, .type, tok_mod); try writeTokenMod(builder, target_tok, .type, tok_mod);
} else if (type_node.isFunc()) { } else if (type_node.isFunc()) {
try writeTokenMod(builder, target_tok, .function, tok_mod); var new_tok_mod = tok_mod;
if (type_node.isGenericFunc()) {
new_tok_mod.set("generic");
}
try writeTokenMod(builder, target_tok, .function, new_tok_mod);
} else { } else {
try writeTokenMod(builder, target_tok, .variable, tok_mod); try writeTokenMod(builder, target_tok, .variable, tok_mod);
} }
@ -334,7 +341,13 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D
.type .type
else else
.function; .function;
try writeToken(builder, fn_proto.name_token, func_name_tok_type);
const tok_mod = if (analysis.isGenericFunction(handle.tree, fn_proto))
TokenModifiers{ .generic = true }
else
TokenModifiers{};
try writeTokenMod(builder, fn_proto.name_token, func_name_tok_type, tok_mod);
for (fn_proto.paramsConst()) |param_decl| { for (fn_proto.paramsConst()) |param_decl| {
if (param_decl.doc_comments) |docs| try writeDocComments(builder, handle.tree, docs); if (param_decl.doc_comments) |docs| try writeDocComments(builder, handle.tree, docs);
@ -618,6 +631,11 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D
const call = node.cast(ast.Node.Call).?; const call = node.cast(ast.Node.Call).?;
try writeToken(builder, call.async_token, .keyword); try writeToken(builder, call.async_token, .keyword);
try await @asyncCall(child_frame, {}, writeNodeTokens, builder, arena, store, call.lhs); try await @asyncCall(child_frame, {}, writeNodeTokens, builder, arena, store, call.lhs);
if (builder.current_token) |curr_tok| {
if (curr_tok != call.lhs.lastToken() and handle.tree.token_ids[call.lhs.lastToken()] == .Identifier) {
try writeToken(builder, call.lhs.lastToken(), .function);
}
}
for (call.paramsConst()) |param| try await @asyncCall(child_frame, {}, writeNodeTokens, builder, arena, store, param); for (call.paramsConst()) |param| try await @asyncCall(child_frame, {}, writeNodeTokens, builder, arena, store, param);
}, },
.SuffixOp => { .SuffixOp => {