A lot of fixes
This commit is contained in:
		
							parent
							
								
									0133f0d863
								
							
						
					
					
						commit
						72605c7549
					
				
							
								
								
									
										268
									
								
								src/analysis.zig
									
									
									
									
									
								
							
							
						
						
									
										268
									
								
								src/analysis.zig
									
									
									
									
									
								
							| @ -5,17 +5,33 @@ const types = @import("types.zig"); | |||||||
| const offsets = @import("offsets.zig"); | const offsets = @import("offsets.zig"); | ||||||
| const log = std.log.scoped(.analysis); | const log = std.log.scoped(.analysis); | ||||||
| 
 | 
 | ||||||
| /// Get a declaration's doc comment node | /// Get a declaration's doc comment token index | ||||||
| pub fn getDocCommentNode(tree: ast.Tree, node: *ast.Node) ?*ast.Node.DocComment { | pub fn getDocCommentTokenIndex(tree: ast.Tree, node: ast.Node.Index) ?ast.TokenIndex { | ||||||
|     if (node.castTag(.FnProto)) |func| { |     const tags = tree.nodes.items(.tag); | ||||||
|         return func.getDocComments(); |     const tokens = tree.tokens.items(.tag); | ||||||
|     } else if (node.castTag(.VarDecl)) |var_decl| { |     const current = tree.nodes.items(.main_token)[node]; | ||||||
|         return var_decl.getDocComments(); | 
 | ||||||
|     } else if (node.castTag(.ContainerField)) |field| { |     switch (tags[node]) { | ||||||
|         return field.doc_comments; |         .fn_proto, .fn_proto_one, .fn_proto_simple, .fn_proto_multi => { | ||||||
|     } else if (node.castTag(.ErrorTag)) |tag| { |             var idx = current - 1; | ||||||
|         return tag.doc_comments; |             idx -= @boolToInt(tokens[idx] == .keyword_extern); | ||||||
|  |             idx -= @boolToInt(tokens[idx] == .keyword_pub); | ||||||
|  |             return if (tokens[idx] == .doc_comment) idx else null; | ||||||
|  |         }, | ||||||
|  |         .local_var_decl, .global_var_decl, .aligned_var_decl, .simple_var_decl => { | ||||||
|  |             return if (tokens[current - 1] == .doc_comment) current - 1 else null; | ||||||
|  |         }, | ||||||
|  |         .container_field, .container_field_init, .container_field_align => { | ||||||
|  |             var idx = current - 2; // skip '.' | ||||||
|  |             return if (tokens[idx] == .doc_comment) idx else null; | ||||||
|  |         }, | ||||||
|  |         else => return null, | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     // @TODO: Implement doc comments for tags | ||||||
|  |     // } else if (node.castTag(.ErrorTag)) |tag| { | ||||||
|  |     //     return tag.doc_comments; | ||||||
|  |     // } | ||||||
|     return null; |     return null; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -28,11 +44,11 @@ pub fn getDocCommentNode(tree: ast.Tree, node: *ast.Node) ?*ast.Node.DocComment | |||||||
| pub fn getDocComments( | pub fn getDocComments( | ||||||
|     allocator: *std.mem.Allocator, |     allocator: *std.mem.Allocator, | ||||||
|     tree: ast.Tree, |     tree: ast.Tree, | ||||||
|     node: *ast.Node, |     node: ast.Node.Index, | ||||||
|     format: types.MarkupContent.Kind, |     format: types.MarkupContent.Kind, | ||||||
| ) !?[]const u8 { | ) !?[]const u8 { | ||||||
|     if (getDocCommentNode(tree, node)) |doc_comment_node| { |     if (getDocCommentTokenIndex(tree, node)) |doc_comment_index| { | ||||||
|         return try collectDocComments(allocator, tree, doc_comment_node, format); |         return try collectDocComments(allocator, tree, doc_comment_index, format); | ||||||
|     } |     } | ||||||
|     return null; |     return null; | ||||||
| } | } | ||||||
| @ -40,17 +56,19 @@ pub fn getDocComments( | |||||||
| pub fn collectDocComments( | pub fn collectDocComments( | ||||||
|     allocator: *std.mem.Allocator, |     allocator: *std.mem.Allocator, | ||||||
|     tree: ast.Tree, |     tree: ast.Tree, | ||||||
|     doc_comments: *ast.Node.DocComment, |     doc_comments: ast.TokenIndex, | ||||||
|     format: types.MarkupContent.Kind, |     format: types.MarkupContent.Kind, | ||||||
| ) ![]const u8 { | ) ![]const u8 { | ||||||
|     var lines = std.ArrayList([]const u8).init(allocator); |     var lines = std.ArrayList([]const u8).init(allocator); | ||||||
|     defer lines.deinit(); |     defer lines.deinit(); | ||||||
| 
 | 
 | ||||||
|     var curr_line_tok = doc_comments.first_line; |     const token_tags = tree.tokens.items(.tag); | ||||||
|  |     const loc = tree.tokenLocation(0, doc_comments); | ||||||
|  | 
 | ||||||
|  |     var curr_line_tok = doc_comments; | ||||||
|     while (true) : (curr_line_tok += 1) { |     while (true) : (curr_line_tok += 1) { | ||||||
|         switch (tree.token_ids[curr_line_tok]) { |         switch (token_tags[curr_line_tok]) { | ||||||
|             .LineComment => continue, |             .doc_comment, .container_doc_comment => { | ||||||
|             .DocComment, .ContainerDocComment => { |  | ||||||
|                 try lines.append(std.mem.trim(u8, tree.tokenSlice(curr_line_tok)[3..], &std.ascii.spaces)); |                 try lines.append(std.mem.trim(u8, tree.tokenSlice(curr_line_tok)[3..], &std.ascii.spaces)); | ||||||
|             }, |             }, | ||||||
|             else => break, |             else => break, | ||||||
| @ -61,20 +79,15 @@ pub fn collectDocComments( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets a function signature (keywords, name, return value) | /// Gets a function signature (keywords, name, return value) | ||||||
| pub fn getFunctionSignature(tree: ast.Tree, func: *ast.Node.FnProto) []const u8 { | pub fn getFunctionSignature(tree: ast.Tree, func: *ast.full.FnProto) []const u8 { | ||||||
|     const start = tree.token_locs[func.firstToken()].start; |     const start = tree.tokenLocation(func.ast.fn_token).line_start; | ||||||
|     const end = tree.token_locs[ |     const end = tree.tokenLocation(func.ast.return_type).line_end; | ||||||
|         switch (func.return_type) { |  | ||||||
|             .Explicit, .InferErrorSet => |node| node.lastToken(), |  | ||||||
|             .Invalid => |r_paren| r_paren, |  | ||||||
|         } |  | ||||||
|     ].end; |  | ||||||
|     return tree.source[start..end]; |     return tree.source[start..end]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets a function snippet insert text | /// Gets a function snippet insert text | ||||||
| pub fn getFunctionSnippet(allocator: *std.mem.Allocator, tree: ast.Tree, func: *ast.Node.FnProto, skip_self_param: bool) ![]const u8 { | pub fn getFunctionSnippet(allocator: *std.mem.Allocator, tree: ast.Tree, func: *ast.full.FnProto, skip_self_param: bool) ![]const u8 { | ||||||
|     const name_tok = func.getNameToken() orelse unreachable; |     const name_index = func.name_token orelse unreachable; | ||||||
| 
 | 
 | ||||||
|     var buffer = std.ArrayList(u8).init(allocator); |     var buffer = std.ArrayList(u8).init(allocator); | ||||||
|     try buffer.ensureCapacity(128); |     try buffer.ensureCapacity(128); | ||||||
| @ -84,18 +97,20 @@ pub fn getFunctionSnippet(allocator: *std.mem.Allocator, tree: ast.Tree, func: * | |||||||
| 
 | 
 | ||||||
|     var buf_stream = buffer.writer(); |     var buf_stream = buffer.writer(); | ||||||
| 
 | 
 | ||||||
|     for (func.paramsConst()) |param, param_num| { |     const token_tags = tree.tokens.items(.tag); | ||||||
|         if (skip_self_param and param_num == 0) continue; |  | ||||||
|         if (param_num != @boolToInt(skip_self_param)) try buffer.appendSlice(", ${") else try buffer.appendSlice("${"); |  | ||||||
| 
 | 
 | ||||||
|         try buf_stream.print("{}:", .{param_num + 1}); |     var it = func.iterate(tree); | ||||||
|  |     while (it.next()) |param| { | ||||||
|  |         if (skip_self_param and it.param_i == 0) continue; | ||||||
|  |         if (it.param_i != @boolToInt(skip_self_param)) try buffer.appendSlice(", ${") else try buffer.appendSlice("${"); | ||||||
| 
 | 
 | ||||||
|         if (param.comptime_token) |_| { |         try buf_stream.print("{d}", .{it.param_i + 1}); | ||||||
|             try buffer.appendSlice("comptime "); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         if (param.noalias_token) |_| { |         if (param.comptime_noalias) |token_index| { | ||||||
|             try buffer.appendSlice("noalias "); |             if (token_tags[token_index] == .keyword_comptime) | ||||||
|  |                 try buffer.appendSlice("comptime ") | ||||||
|  |             else | ||||||
|  |                 try buffer.appendSlice("noalias "); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (param.name_token) |name_token| { |         if (param.name_token) |name_token| { | ||||||
| @ -103,23 +118,23 @@ pub fn getFunctionSnippet(allocator: *std.mem.Allocator, tree: ast.Tree, func: * | |||||||
|             try buffer.appendSlice(": "); |             try buffer.appendSlice(": "); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         switch (param.param_type) { |         if (param.anytype_ellipsis3) |token_index| { | ||||||
|             .any_type => try buffer.appendSlice("anytype"), |             if (token_tags[token_index] == .keyword_anytype) | ||||||
|             .type_expr => |type_expr| { |                 try buffer.appendSlice("anytype") | ||||||
|                 var curr_tok = type_expr.firstToken(); |             else | ||||||
|                 var end_tok = type_expr.lastToken(); |                 try buffer.appendSlice("..."); | ||||||
|                 while (curr_tok <= end_tok) : (curr_tok += 1) { |         } else { | ||||||
|                     const id = tree.token_ids[curr_tok]; |             var curr_token = param.type_expr; | ||||||
|                     const is_comma = id == .Comma; |             var end_token = tree.lastToken(func.ast.params[it.param_i]); | ||||||
|  |             while (curr_token <= end_token) : (curr_token += 1) { | ||||||
|  |                 const tag = token_tags[curr_token]; | ||||||
|  |                 const is_comma = tag == .comma; | ||||||
| 
 | 
 | ||||||
|                     if (curr_tok == end_tok and is_comma) continue; |                 if (curr_token == end_token and is_comma) continue; | ||||||
| 
 |                 try buffer.appendSlice(tree.tokenSlice(curr_token)); | ||||||
|                     try buffer.appendSlice(tree.tokenSlice(curr_tok)); |                 if (is_comma or tag == .Keyword_const) try buffer.append(' '); | ||||||
|                     if (is_comma or id == .Keyword_const) try buffer.append(' '); |             } | ||||||
|                 } |  | ||||||
|             }, |  | ||||||
|         } |         } | ||||||
| 
 |  | ||||||
|         try buffer.append('}'); |         try buffer.append('}'); | ||||||
|     } |     } | ||||||
|     try buffer.append(')'); |     try buffer.append(')'); | ||||||
| @ -128,16 +143,16 @@ pub fn getFunctionSnippet(allocator: *std.mem.Allocator, tree: ast.Tree, func: * | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets a function signature (keywords, name, return value) | /// Gets a function signature (keywords, name, return value) | ||||||
| pub fn getVariableSignature(tree: ast.Tree, var_decl: *ast.Node.VarDecl) []const u8 { | pub fn getVariableSignature(tree: ast.Tree, var_decl: *ast.full.VarDecl) []const u8 { | ||||||
|     const start = tree.token_locs[var_decl.firstToken()].start; |     const start = tree.tokenLocation(0, var_decl.ast.mut_token).line_start; | ||||||
|     const end = tree.token_locs[var_decl.semicolon_token].start; |     const end = tree.tokenLocation(@truncate(u32, start), tree.lastToken(var_decl.ast.init_node)).line_end; | ||||||
|     return tree.source[start..end]; |     return tree.source[start..end]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // analysis.getContainerFieldSignature(handle.tree, field) | // analysis.getContainerFieldSignature(handle.tree, field) | ||||||
| pub fn getContainerFieldSignature(tree: ast.Tree, field: *ast.Node.ContainerField) []const u8 { | pub fn getContainerFieldSignature(tree: ast.Tree, field: *ast.full.ContainerField) []const u8 { | ||||||
|     const start = tree.token_locs[field.firstToken()].start; |     const start = tree.tokenLocation(0, field.ast.name_token).line_start; | ||||||
|     const end = tree.token_locs[field.lastToken()].end; |     const end = tree.tokenLocation(@truncate(u32, start), tree.lastToken(field.ast.value_expr)).line_start; | ||||||
|     return tree.source[start..end]; |     return tree.source[start..end]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -150,7 +165,7 @@ fn typeIsType(tree: ast.Tree, node: ast.Node.Index) bool { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn isTypeFunction(tree: ast.Tree, func: ast.full.FnProto) bool { | pub fn isTypeFunction(tree: ast.Tree, func: ast.full.FnProto) bool { | ||||||
|     return typeIsType(func.ast.return_type); |     return typeIsType(tree, func.ast.return_type); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn isGenericFunction(tree: ast.Tree, func: *ast.full.FnProto) bool { | pub fn isGenericFunction(tree: ast.Tree, func: *ast.full.FnProto) bool { | ||||||
| @ -1570,7 +1585,9 @@ pub fn getDocumentSymbols(allocator: *std.mem.Allocator, tree: ast.Tree, encodin | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub const Declaration = union(enum) { | pub const Declaration = union(enum) { | ||||||
|     ast_node: ast.Node, |     /// Index of the ast node | ||||||
|  |     ast_node: ast.Node.Index, | ||||||
|  |     /// Function parameter | ||||||
|     param_decl: ast.full.FnProto.Param, |     param_decl: ast.full.FnProto.Param, | ||||||
|     pointer_payload: struct { |     pointer_payload: struct { | ||||||
|         node: ast.full.PtrType, |         node: ast.full.PtrType, | ||||||
| @ -2062,15 +2079,15 @@ pub const DocumentScope = struct { | |||||||
| 
 | 
 | ||||||
| pub const Scope = struct { | pub const Scope = struct { | ||||||
|     pub const Data = union(enum) { |     pub const Data = union(enum) { | ||||||
|         container: *ast.Node, // .id is ContainerDecl or Root or ErrorSetDecl |         container: ast.Node.Index, // .tag is ContainerDecl or Root or ErrorSetDecl | ||||||
|         function: *ast.Node, // .id is FnProto |         function: ast.Node.Index, // .tag is FnProto | ||||||
|         block: *ast.Node, // .id is Block |         block: ast.Node.Index, // .tag is Block | ||||||
|         other, |         other, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     range: SourceRange, |     range: SourceRange, | ||||||
|     decls: std.StringHashMap(Declaration), |     decls: std.StringHashMap(Declaration), | ||||||
|     tests: []const *ast.Node, |     tests: []const ast.Node.Index, | ||||||
|     // uses: []const *ast.Node.Data, |     // uses: []const *ast.Node.Data, | ||||||
| 
 | 
 | ||||||
|     data: Data, |     data: Data, | ||||||
| @ -2088,8 +2105,8 @@ pub fn makeDocumentScope(allocator: *std.mem.Allocator, tree: ast.Tree) !Documen | |||||||
|         for (enum_completions.items) |item| if (item.documentation) |doc| allocator.free(doc.value); |         for (enum_completions.items) |item| if (item.documentation) |doc| allocator.free(doc.value); | ||||||
|         enum_completions.deinit(allocator); |         enum_completions.deinit(allocator); | ||||||
|     } |     } | ||||||
| 
 |     // pass root node index ('0') | ||||||
|     try makeScopeInternal(allocator, &scopes, &error_completions, &enum_completions, tree); |     try makeScopeInternal(allocator, &scopes, &error_completions, &enum_completions, tree, 0); | ||||||
|     return DocumentScope{ |     return DocumentScope{ | ||||||
|         .scopes = scopes.toOwnedSlice(allocator), |         .scopes = scopes.toOwnedSlice(allocator), | ||||||
|         .error_completions = error_completions.toOwnedSlice(allocator), |         .error_completions = error_completions.toOwnedSlice(allocator), | ||||||
| @ -2105,6 +2122,51 @@ fn nodeSourceRange(tree: ast.Tree, node: ast.Node.Index) SourceRange { | |||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | fn isContainer(tag: ast.Node.Tag) bool { | ||||||
|  |     return switch (tag) { | ||||||
|  |         .container_decl, | ||||||
|  |         .container_decl_trailing, | ||||||
|  |         .container_decl_arg, | ||||||
|  |         .container_decl_arg_trailing, | ||||||
|  |         .container_decl_two, | ||||||
|  |         .container_decl_two_trailing, | ||||||
|  |         .tagged_union, | ||||||
|  |         .tagged_union_trailing, | ||||||
|  |         .tagged_union_two, | ||||||
|  |         .tagged_union_two_trailing, | ||||||
|  |         .tagged_union_enum_tag, | ||||||
|  |         .tagged_union_enum_tag_trailing, | ||||||
|  |         .root, | ||||||
|  |         .error_set_decl, | ||||||
|  |         => true, | ||||||
|  |         else => false, | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Returns the member indices of a given declaration container. | ||||||
|  | /// Asserts given `tag` is a container node | ||||||
|  | fn declMembers(tree: ast.Tree, tag: ast.Node.Tag) []ast.Node.index { | ||||||
|  |     std.debug.assert(isContainer(tag)); | ||||||
|  |     return switch (tag) { | ||||||
|  |         .container_decl, .container_decl_trailing => tree.containerDecl(node_idx).ast.members, | ||||||
|  |         .container_decl_arg, .container_decl_arg_trailing => tree.containerDeclArg(node_idx).ast.members, | ||||||
|  |         .container_decl_two, .container_decl_two_trailing => blk: { | ||||||
|  |             var buffer: [2]ast.Node.Index = undefined; | ||||||
|  |             break :blk tree.containerDeclTwo(&buffer, node_idx).ast.members; | ||||||
|  |         }, | ||||||
|  |         .tagged_union, .tagged_union_trailing => tree.taggedUnion(node_idx).ast.members, | ||||||
|  |         .tagged_union_enum_tag, .tagged_union_enum_tag_trailing => tree.taggedUnionEnumTag(node_idx).ast.members, | ||||||
|  |         .tagged_union_two, .tagged_union_two_trailing => blk: { | ||||||
|  |             var buffer: [2]ast.Node.Index = undefined; | ||||||
|  |             break :blk tree.taggedUnionTwo(&buffer, node_idx).ast.members; | ||||||
|  |         }, | ||||||
|  |         .root => tree.rootDecls(), | ||||||
|  |         // @TODO: Fix error set declarations | ||||||
|  |         .error_set_decl => &[_]ast.Node.Index{}, | ||||||
|  |         else => unreachable, | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // TODO Possibly collect all imports to diff them on changes | // TODO Possibly collect all imports to diff them on changes | ||||||
| //      as well | //      as well | ||||||
| fn makeScopeInternal( | fn makeScopeInternal( | ||||||
| @ -2115,27 +2177,23 @@ fn makeScopeInternal( | |||||||
|     tree: ast.Tree, |     tree: ast.Tree, | ||||||
|     node_idx: ast.Node.Index, |     node_idx: ast.Node.Index, | ||||||
| ) error{OutOfMemory}!void { | ) error{OutOfMemory}!void { | ||||||
|     const nodes = tree.nodes.items(.tag); |     const tags = tree.nodes.items(.tag); | ||||||
|     const node = nodes[node_idx]; |     const token_tags = tree.tokens.items(.tag); | ||||||
|     if (node == .root or node == .container_decl or node == .error_set_decl) { |     const node = tags[node_idx]; | ||||||
|         const ast_decls = switch (node) { | 
 | ||||||
|             .container_decl => tree.containerDecl(node_idx).ast.members, |     if (isContainer(node)) { | ||||||
|             .root => tree.rootDecls(), |         const ast_decls = declMembers(tree, node); | ||||||
|             // @TODO: Fix error set declarations |  | ||||||
|             // .error_set_decl => node.castTag(.ErrorSetDecl).?.declsConst(), |  | ||||||
|             else => unreachable, |  | ||||||
|         }; |  | ||||||
| 
 | 
 | ||||||
|         (try scopes.addOne(allocator)).* = .{ |         (try scopes.addOne(allocator)).* = .{ | ||||||
|             .range = nodeSourceRange(tree, node), |             .range = nodeSourceRange(tree, node_idx), | ||||||
|             .decls = std.StringHashMap(Declaration).init(allocator), |             .decls = std.StringHashMap(Declaration).init(allocator), | ||||||
|             // .uses = &[0]*ast.Node.Use{}, |             // .uses = &[0]*ast.Node.Use{}, | ||||||
|             .tests = &[0]*ast.Node{}, |             .tests = &[0]*ast.Node{}, | ||||||
|             .data = .{ .container = node }, |             .data = .{ .container = node_idx }, | ||||||
|         }; |         }; | ||||||
|         const scope_idx = scopes.items.len - 1; |         const scope_idx = scopes.items.len - 1; | ||||||
|         // var uses = std.ArrayList(*ast.Node.Use).init(allocator); |         // var uses = std.ArrayList(*ast.Node.Use).init(allocator); | ||||||
|         var tests = std.ArrayList(*ast.Node).init(allocator); |         var tests = std.ArrayList(ast.Node.Index).init(allocator); | ||||||
| 
 | 
 | ||||||
|         errdefer { |         errdefer { | ||||||
|             scopes.items[scope_idx].decls.deinit(); |             scopes.items[scope_idx].decls.deinit(); | ||||||
| @ -2144,6 +2202,7 @@ fn makeScopeInternal( | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         for (ast_decls) |decl| { |         for (ast_decls) |decl| { | ||||||
|  |             // @TODO: Implement using namespace | ||||||
|             // if (decl.castTag(.Use)) |use| { |             // if (decl.castTag(.Use)) |use| { | ||||||
|             //     try uses.append(use); |             //     try uses.append(use); | ||||||
|             //     continue; |             //     continue; | ||||||
| @ -2151,12 +2210,13 @@ fn makeScopeInternal( | |||||||
| 
 | 
 | ||||||
|             try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, decl); |             try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, decl); | ||||||
|             const name = getDeclName(tree, decl) orelse continue; |             const name = getDeclName(tree, decl) orelse continue; | ||||||
|             if (decl.tag == .TestDecl) { |             // @TODO: implement tests | ||||||
|                 try tests.append(decl); |             // if (decl.tag == .TestDecl) { | ||||||
|                 continue; |             //     try tests.append(decl); | ||||||
|             } |             //     continue; | ||||||
|  |             // } | ||||||
| 
 | 
 | ||||||
|             if (node.tag == .ErrorSetDecl) { |             if (tags[decl] == .error_set_decl) { | ||||||
|                 (try error_completions.addOne(allocator)).* = .{ |                 (try error_completions.addOne(allocator)).* = .{ | ||||||
|                     .label = name, |                     .label = name, | ||||||
|                     .kind = .Constant, |                     .kind = .Constant, | ||||||
| @ -2167,15 +2227,39 @@ fn makeScopeInternal( | |||||||
|                 }; |                 }; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (decl.castTag(.ContainerField)) |field| { |             const container_field: ?ast.full.ContainerField = switch (decl) { | ||||||
|                 const empty_field = field.type_expr == null and field.value_expr == null; |                 .container_field => tree.containerField(decl), | ||||||
|                 if (empty_field and node.tag == .Root) { |                 .container_field_align => tree.containerFieldAlign(decl), | ||||||
|  |                 .container_field_init => tree.containerFieldInit(decl), | ||||||
|  |                 else => null, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             if (container_field) |field| { | ||||||
|  |                 const empty_field = field.type_expr == 0 and field.value_expr == 0; | ||||||
|  |                 if (empty_field and node == .root) { | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 if (node.castTag(.ContainerDecl)) |container| { |                 // @TODO: We can probably just use node_idx directly instead of first transforming to container | ||||||
|                     const kind = tree.token_ids[container.kind_token]; |                 const container_decl: ?ast.full.ContainerDecl = switch (node) { | ||||||
|                     if (empty_field and (kind == .Keyword_struct or (kind == .Keyword_union and container.init_arg_expr == .None))) { |                     .container_decl, .container_decl_trailing => tree.containerDecl(node_idx), | ||||||
|  |                     .container_decl_arg, .container_decl_arg_trailing => tree.containerDeclArg(node_idx), | ||||||
|  |                     .container_decl_two, .container_decl_two_trailing => blk: { | ||||||
|  |                         var buffer: [2]ast.Node.Index = undefined; | ||||||
|  |                         break :blk tree.containerDeclTwo(&buffer, node_idx); | ||||||
|  |                     }, | ||||||
|  |                     .tagged_union, .tagged_union_trailing => tree.taggedUnion(node_idx), | ||||||
|  |                     .tagged_union_enum_tag, .tagged_union_enum_tag_trailing => tree.taggedUnionEnumTag(node_idx), | ||||||
|  |                     .tagged_union_enum_tag, .tagged_union_enum_tag_trailing => blk: { | ||||||
|  |                         var buffer: [2]ast.Node.Index = undefined; | ||||||
|  |                         break :blk tree.taggedUnionTwo(&buffer, node_idx); | ||||||
|  |                     }, | ||||||
|  |                     else => null, | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |                 if (container_decl) |container| { | ||||||
|  |                     const kind = token_tags[container.ast.main_token]; | ||||||
|  |                     if (empty_field and (kind == .keyword_struct or (kind == .keyword_union and container.ast.arg == 0))) { | ||||||
|                         continue; |                         continue; | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
| @ -2183,7 +2267,7 @@ fn makeScopeInternal( | |||||||
|                         (try enum_completions.addOne(allocator)).* = .{ |                         (try enum_completions.addOne(allocator)).* = .{ | ||||||
|                             .label = name, |                             .label = name, | ||||||
|                             .kind = .Constant, |                             .kind = .Constant, | ||||||
|                             .documentation = if (try getDocComments(allocator, tree, decl, .Markdown)) |docs| |                             .documentation = if (try getDocComments(allocator, tree, node_idx, .Markdown)) |docs| | ||||||
|                                 .{ .kind = .Markdown, .value = docs } |                                 .{ .kind = .Markdown, .value = docs } | ||||||
|                             else |                             else | ||||||
|                                 null, |                                 null, | ||||||
| @ -2202,7 +2286,7 @@ fn makeScopeInternal( | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch (node.tag) { |     switch (node) { | ||||||
|         .FnProto => { |         .FnProto => { | ||||||
|             const func = node.castTag(.FnProto).?; |             const func = node.castTag(.FnProto).?; | ||||||
| 
 | 
 | ||||||
|  | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user