Fixed wrong node being used when resolving return type of a function

This commit is contained in:
Sergeeeek 2020-05-19 07:39:34 +03:00
parent 5043a10dd4
commit 4b3cb641c0
3 changed files with 7 additions and 9 deletions

View File

@ -262,16 +262,16 @@ pub fn resolveTypeOfNode(analysis_ctx: *AnalysisContext, node: *ast.Node) ?*ast.
const suffix_op = node.cast(ast.Node.SuffixOp).?; const suffix_op = node.cast(ast.Node.SuffixOp).?;
switch (suffix_op.op) { switch (suffix_op.op) {
.Call, .StructInitializer => { .Call, .StructInitializer => {
const func_decl = resolveTypeOfNode(analysis_ctx, suffix_op.lhs.node) orelse return null; const func_or_struct_decl = resolveTypeOfNode(analysis_ctx, suffix_op.lhs.node) orelse return null;
if (func_decl.id == .FnProto) { if (func_or_struct_decl.id == .FnProto) {
const func = node.cast(ast.Node.FnProto).?; const func = func_or_struct_decl.cast(ast.Node.FnProto).?;
switch (func.return_type) { switch (func.return_type) {
.Explicit, .InferErrorSet => |return_type| return resolveTypeOfNode(analysis_ctx, return_type), .Explicit, .InferErrorSet => |return_type| return resolveTypeOfNode(analysis_ctx, return_type),
.Invalid => {}, .Invalid => {},
} }
} }
return null; return func_or_struct_decl;
}, },
else => {}, else => {},
} }
@ -280,13 +280,9 @@ pub fn resolveTypeOfNode(analysis_ctx: *AnalysisContext, node: *ast.Node) ?*ast.
const infix_op = node.cast(ast.Node.InfixOp).?; const infix_op = node.cast(ast.Node.InfixOp).?;
switch (infix_op.op) { switch (infix_op.op) {
.Period => { .Period => {
std.debug.warn("\n\n\nPeriod\n\n\n", .{});
std.debug.warn("InfixOp file = {}\n{}\n", .{ analysis_ctx.handle.document.uri, analysis_ctx.tree.getNodeSource(&analysis_ctx.tree.root_node.base) });
std.debug.warn("InfixOp full = {}\n", .{analysis_ctx.tree.getNodeSource(node)});
// Save the child string from this tree since the tree may switch when processing // Save the child string from this tree since the tree may switch when processing
// an import lhs. // an import lhs.
var rhs_str = nodeToString(analysis_ctx.tree, infix_op.rhs) orelse return null; var rhs_str = nodeToString(analysis_ctx.tree, infix_op.rhs) orelse return null;
std.debug.warn("InfixOp rhs_str = {}\n", .{rhs_str});
// Use the analysis context temporary arena to store the rhs string. // Use the analysis context temporary arena to store the rhs string.
rhs_str = std.mem.dupe(&analysis_ctx.arena.allocator, u8, rhs_str) catch return null; rhs_str = std.mem.dupe(&analysis_ctx.arena.allocator, u8, rhs_str) catch return null;
const left = resolveTypeOfNode(analysis_ctx, infix_op.lhs) orelse return null; const left = resolveTypeOfNode(analysis_ctx, infix_op.lhs) orelse return null;

View File

@ -343,7 +343,7 @@ pub const AnalysisContext = struct {
} }
pub fn clone(self: *Self) !Self { pub fn clone(self: *Self) !Self {
// Copy the tree, so it can be destroyed by the cloned AnalysisContext without affecting the original // Create a new tree so it can be destroyed by the cloned AnalysisContext without affecting the original
const tree = try self.handle.tree(self.store.allocator); const tree = try self.handle.tree(self.store.allocator);
return Self{ return Self{
.store = self.store, .store = self.store,

View File

@ -223,6 +223,8 @@ fn nodeToCompletion(list: *std.ArrayList(types.CompletionItem), analysis_ctx: *D
const maybe_resolved_node = analysis.resolveTypeOfNode(&child_analysis_context, child_node); const maybe_resolved_node = analysis.resolveTypeOfNode(&child_analysis_context, child_node);
if (maybe_resolved_node) |resolved_node| { if (maybe_resolved_node) |resolved_node| {
// Special case for function aliases
// In the future it might be used to print types of values instead of their declarations
if (resolved_node.id == .FnProto) { if (resolved_node.id == .FnProto) {
try nodeToCompletion(list, &child_analysis_context, resolved_node, config); try nodeToCompletion(list, &child_analysis_context, resolved_node, config);
return; return;