Complete resolveTypeOfNodeInternal
This commit is contained in:
parent
b175a01fce
commit
96fcac89a4
135
src/analysis.zig
135
src/analysis.zig
@ -442,7 +442,7 @@ fn resolveDerefType(
|
|||||||
const main_token = tree.nodes.items(.main_token)[deref_node];
|
const main_token = tree.nodes.items(.main_token)[deref_node];
|
||||||
const token_tag = tree.tokens.items(.tag)[main_token];
|
const token_tag = tree.tokens.items(.tag)[main_token];
|
||||||
|
|
||||||
if (isPtrType(deref_node)) {
|
if (isPtrType(tree, deref_node)) {
|
||||||
switch (token_tag) {
|
switch (token_tag) {
|
||||||
.asterisk => {
|
.asterisk => {
|
||||||
return ((try resolveTypeOfNodeInternal(store, arena, .{
|
return ((try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
@ -679,63 +679,57 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
.Comptime => {
|
.@"comptime", .@"nosuspend" => {
|
||||||
const ct = node.castTag(.Comptime).?;
|
return try resolveTypeOfNodeInternal(store, arena, .{ .node = datas[node].lhs, .handle = handle }, bound_type_params);
|
||||||
return try resolveTypeOfNodeInternal(store, arena, .{ .node = ct.expr, .handle = handle }, bound_type_params);
|
|
||||||
},
|
},
|
||||||
.GroupedExpression => {
|
.grouped_expression => {
|
||||||
const grouped = node.castTag(.GroupedExpression).?;
|
return try resolveTypeOfNodeInternal(store, arena, .{ .node = datas[node].lhs, .handle = handle }, bound_type_params);
|
||||||
return try resolveTypeOfNodeInternal(store, arena, .{ .node = grouped.expr, .handle = handle }, bound_type_params);
|
|
||||||
},
|
},
|
||||||
.StructInitializer => {
|
.struct_init, .struct_init_comma, .struct_init_one, .struct_init_one_comma => {
|
||||||
const struct_init = node.castTag(.StructInitializer).?;
|
const struct_init = node.castTag(.StructInitializer).?;
|
||||||
return ((try resolveTypeOfNodeInternal(
|
return ((try resolveTypeOfNodeInternal(
|
||||||
store,
|
store,
|
||||||
arena,
|
arena,
|
||||||
.{ .node = struct_init.lhs, .handle = handle },
|
.{ .node = datas[node].lhs, .handle = handle },
|
||||||
bound_type_params,
|
bound_type_params,
|
||||||
)) orelse return null).instanceTypeVal();
|
)) orelse return null).instanceTypeVal();
|
||||||
},
|
},
|
||||||
.ErrorSetDecl => {
|
.error_set_decl => {
|
||||||
return TypeWithHandle.typeVal(node_handle);
|
return TypeWithHandle.typeVal(node_handle);
|
||||||
},
|
},
|
||||||
.Slice => {
|
.slice, .slice_sentinel, .slice_open => {
|
||||||
const slice = node.castTag(.Slice).?;
|
|
||||||
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = slice.lhs,
|
.node = dates[node].lhs,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
}, bound_type_params)) orelse return null;
|
}, bound_type_params)) orelse return null;
|
||||||
return try resolveBracketAccessType(store, arena, left_type, .Range, bound_type_params);
|
return try resolveBracketAccessType(store, arena, left_type, .Range, bound_type_params);
|
||||||
},
|
},
|
||||||
.Deref, .UnwrapOptional => {
|
.deref, .unwrap_optional => {
|
||||||
const suffix = node.cast(ast.Node.SimpleSuffixOp).?;
|
|
||||||
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = suffix.lhs,
|
.node = dates[node].lhs,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
}, bound_type_params)) orelse return null;
|
}, bound_type_params)) orelse return null;
|
||||||
return switch (node.tag) {
|
return switch (node_tags[node]) {
|
||||||
.UnwrapOptional => try resolveUnwrapOptionalType(store, arena, left_type, bound_type_params),
|
.unwrap_optional => try resolveUnwrapOptionalType(store, arena, left_type, bound_type_params),
|
||||||
.Deref => try resolveDerefType(store, arena, left_type, bound_type_params),
|
.deref => try resolveDerefType(store, arena, left_type, bound_type_params),
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
.ArrayAccess => {
|
.array_access => {
|
||||||
const arr_acc = node.castTag(.ArrayAccess).?;
|
|
||||||
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = arr_acc.lhs,
|
.node = datas[node].lhs,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
}, bound_type_params)) orelse return null;
|
}, bound_type_params)) orelse return null;
|
||||||
return try resolveBracketAccessType(store, arena, left_type, .Single, bound_type_params);
|
return try resolveBracketAccessType(store, arena, left_type, .Single, bound_type_params);
|
||||||
},
|
},
|
||||||
.Period => {
|
.field_access => {
|
||||||
const infix_op = node.cast(ast.Node.SimpleInfixOp).?;
|
const rhs_str = nodeToString(handle.tree, datas[node].rhs) orelse return null;
|
||||||
const rhs_str = nodeToString(handle.tree, infix_op.rhs) orelse return null;
|
|
||||||
// If we are accessing a pointer type, remove one pointerness level :)
|
// If we are accessing a pointer type, remove one pointerness level :)
|
||||||
const left_type = try resolveFieldAccessLhsType(
|
const left_type = try resolveFieldAccessLhsType(
|
||||||
store,
|
store,
|
||||||
arena,
|
arena,
|
||||||
(try resolveTypeOfNodeInternal(store, arena, .{
|
(try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = infix_op.lhs,
|
.node = datas[node].lhs,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
}, bound_type_params)) orelse return null,
|
}, bound_type_params)) orelse return null,
|
||||||
bound_type_params,
|
bound_type_params,
|
||||||
@ -756,40 +750,39 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
return try child.resolveType(store, arena, bound_type_params);
|
return try child.resolveType(store, arena, bound_type_params);
|
||||||
} else return null;
|
} else return null;
|
||||||
},
|
},
|
||||||
.OrElse => {
|
.@"orelse" => {
|
||||||
const infix_op = node.cast(ast.Node.SimpleInfixOp).?;
|
|
||||||
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = infix_op.lhs,
|
.node = datas[node].lhs,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
}, bound_type_params)) orelse return null;
|
}, bound_type_params)) orelse return null;
|
||||||
return try resolveUnwrapOptionalType(store, arena, left_type, bound_type_params);
|
return try resolveUnwrapOptionalType(store, arena, left_type, bound_type_params);
|
||||||
},
|
},
|
||||||
.Catch => {
|
.@"catch" => {
|
||||||
const infix_op = node.cast(ast.Node.Catch).?;
|
|
||||||
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = infix_op.lhs,
|
.node = datas[node].lhs,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
}, bound_type_params)) orelse return null;
|
}, bound_type_params)) orelse return null;
|
||||||
return try resolveUnwrapErrorType(store, arena, left_type, bound_type_params);
|
return try resolveUnwrapErrorType(store, arena, left_type, bound_type_params);
|
||||||
},
|
},
|
||||||
.ErrorUnion => return TypeWithHandle.typeVal(node_handle),
|
.error_union => return TypeWithHandle.typeVal(node_handle),
|
||||||
.SliceType,
|
.array_type,
|
||||||
.ArrayType,
|
.array_type_sentinel,
|
||||||
.OptionalType,
|
.optional_type,
|
||||||
.PtrType,
|
.ptr_type_aligned,
|
||||||
|
.ptr_type.aligned,
|
||||||
|
.ptr_type,
|
||||||
|
.ptr_type_bit_range,
|
||||||
=> return TypeWithHandle.typeVal(node_handle),
|
=> return TypeWithHandle.typeVal(node_handle),
|
||||||
.Try => {
|
.@"try" => {
|
||||||
const prefix_op = node.cast(ast.Node.SimplePrefixOp).?;
|
|
||||||
const rhs_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
const rhs_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = prefix_op.rhs,
|
.node = datas[node].lhs,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
}, bound_type_params)) orelse return null;
|
}, bound_type_params)) orelse return null;
|
||||||
return try resolveUnwrapErrorType(store, arena, rhs_type, bound_type_params);
|
return try resolveUnwrapErrorType(store, arena, rhs_type, bound_type_params);
|
||||||
},
|
},
|
||||||
.AddressOf => {
|
.address_of => {
|
||||||
const prefix_op = node.cast(ast.Node.SimplePrefixOp).?;
|
|
||||||
const rhs_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
const rhs_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = prefix_op.rhs,
|
.node = datas[node].lhs,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
}, bound_type_params)) orelse return null;
|
}, bound_type_params)) orelse return null;
|
||||||
|
|
||||||
@ -803,12 +796,13 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
.handle = rhs_type.handle,
|
.handle = rhs_type.handle,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
.BuiltinCall => {
|
.builtin_call, .builtin_call_comma, .builtin_call_two, .builtin_call_two_comma => {
|
||||||
const builtin_call = node.castTag(.BuiltinCall).?;
|
const params = builtinCallParams(tree, node);
|
||||||
const call_name = handle.tree.tokenSlice(builtin_call.builtin_token);
|
|
||||||
|
const call_name = tree.tokenSlice(main_tokens[node]);
|
||||||
if (std.mem.eql(u8, call_name, "@This")) {
|
if (std.mem.eql(u8, call_name, "@This")) {
|
||||||
if (builtin_call.params_len != 0) return null;
|
if (params.len != 0) return null;
|
||||||
return innermostContainer(handle, handle.tree.token_locs[builtin_call.firstToken()].start);
|
return innermostContainer(handle, starts[tree.firstToken(node)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const cast_map = std.ComptimeStringMap(void, .{
|
const cast_map = std.ComptimeStringMap(void, .{
|
||||||
@ -825,9 +819,9 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
.{"@ptrCast"},
|
.{"@ptrCast"},
|
||||||
});
|
});
|
||||||
if (cast_map.has(call_name)) {
|
if (cast_map.has(call_name)) {
|
||||||
if (builtin_call.params_len < 1) return null;
|
if (params.len < 1) return null;
|
||||||
return ((try resolveTypeOfNodeInternal(store, arena, .{
|
return ((try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = builtin_call.paramsConst()[0],
|
.node = params[0],
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
}, bound_type_params)) orelse return null).instanceTypeVal();
|
}, bound_type_params)) orelse return null).instanceTypeVal();
|
||||||
}
|
}
|
||||||
@ -835,9 +829,9 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
// Almost the same as the above, return a type value though.
|
// Almost the same as the above, return a type value though.
|
||||||
// TODO Do peer type resolution, we just keep the first for now.
|
// TODO Do peer type resolution, we just keep the first for now.
|
||||||
if (std.mem.eql(u8, call_name, "@TypeOf")) {
|
if (std.mem.eql(u8, call_name, "@TypeOf")) {
|
||||||
if (builtin_call.params_len < 1) return null;
|
if (params.len < 1) return null;
|
||||||
var resolved_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
var resolved_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = builtin_call.paramsConst()[0],
|
.node = params[0],
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
}, bound_type_params)) orelse return null;
|
}, bound_type_params)) orelse return null;
|
||||||
|
|
||||||
@ -847,35 +841,50 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!std.mem.eql(u8, call_name, "@import")) return null;
|
if (!std.mem.eql(u8, call_name, "@import")) return null;
|
||||||
if (builtin_call.params_len < 1) return null;
|
if (params.len < 1) return null;
|
||||||
|
|
||||||
const import_param = builtin_call.paramsConst()[0];
|
const import_param = params[0];
|
||||||
if (import_param.tag != .StringLiteral) return null;
|
if (node_tags[import_param] != .string_literal) return null;
|
||||||
|
|
||||||
const import_str = handle.tree.tokenSlice(import_param.castTag(.StringLiteral).?.token);
|
const import_str = tree.tokenSlice(main_tokens[import_param]);
|
||||||
const new_handle = (store.resolveImport(handle, import_str[1 .. import_str.len - 1]) catch |err| {
|
const new_handle = (store.resolveImport(handle, import_str[1 .. import_str.len - 1]) catch |err| {
|
||||||
log.debug("Error {} while processing import {s}", .{ err, import_str });
|
log.debug("Error {} while processing import {s}", .{ err, import_str });
|
||||||
return null;
|
return null;
|
||||||
}) orelse return null;
|
}) orelse return null;
|
||||||
|
|
||||||
return TypeWithHandle.typeVal(.{ .node = &new_handle.tree.root_node.base, .handle = new_handle });
|
// reference to node '0' which is root
|
||||||
|
return TypeWithHandle.typeVal(.{ .node = 0, .handle = new_handle });
|
||||||
},
|
},
|
||||||
.ContainerDecl => {
|
.container_decl,
|
||||||
const container = node.castTag(.ContainerDecl).?;
|
.container_decl_arg,
|
||||||
const kind = handle.tree.token_ids[container.kind_token];
|
.container_decl_arg_trailing,
|
||||||
|
.container_decl_trailing,
|
||||||
|
.container_decl_two,
|
||||||
|
.container_decl_two_trailing,
|
||||||
|
=> {
|
||||||
return TypeWithHandle.typeVal(node_handle);
|
return TypeWithHandle.typeVal(node_handle);
|
||||||
},
|
},
|
||||||
.FnProto => {
|
.fn_proto, .fn_proto_multi, .fn_proto_one, .fn_proto_simple => {
|
||||||
|
var buf: [1]ast.Node.Index = undefined;
|
||||||
|
const fn_proto: ast.full.FnProto = switch (node_tags[node]) {
|
||||||
|
.fn_proto => tree.fnProto(node),
|
||||||
|
.fn_proto_multi => tree.fnProtoMulti(node),
|
||||||
|
.fn_proto_one => tree.fnProtoOne(&buf, node),
|
||||||
|
.fn_proto_simple => tree.fnProtoSimple(&buf, node),
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
|
||||||
// This is a function type
|
// This is a function type
|
||||||
if (node.castTag(.FnProto).?.getNameToken() == null) {
|
if (fn_proto.name_token == null) {
|
||||||
return TypeWithHandle.typeVal(node_handle);
|
return TypeWithHandle.typeVal(node_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TypeWithHandle{
|
return TypeWithHandle{
|
||||||
.type = .{ .data = .{ .other = node }, .is_type_val = false },
|
.type = .{ .data = .{ .other = node }, .is_type_val = false },
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
.MultilineStringLiteral, .StringLiteral => return TypeWithHandle{
|
.multiline_string_literal, .string_literal => return TypeWithHandle{
|
||||||
.type = .{ .data = .{ .other = node }, .is_type_val = false },
|
.type = .{ .data = .{ .other = node }, .is_type_val = false },
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user