Complete resolveTypeOfNodeInternal

This commit is contained in:
Luuk de Gram 2021-02-28 20:37:21 +01:00
parent b175a01fce
commit 96fcac89a4
No known key found for this signature in database
GPG Key ID: A002B174963DBB7D

View File

@ -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,
},