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