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