| ... | @@ -2937,7 +2937,6 @@ const Fmt = struct { | ... | @@ -2937,7 +2937,6 @@ const Fmt = struct { |
| 2937 | }; | 2937 | }; |
| 2938 | | 2938 | |
| 2939 | pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { | 2939 | pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { |
| 2940 | const stderr_file = io.getStdErr(); | | |
| 2941 | var color: Color = .auto; | 2940 | var color: Color = .auto; |
| 2942 | var stdin_flag: bool = false; | 2941 | var stdin_flag: bool = false; |
| 2943 | var check_flag: bool = false; | 2942 | var check_flag: bool = false; |
| ... | @@ -2992,7 +2991,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { | ... | @@ -2992,7 +2991,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { |
| 2992 | defer tree.deinit(gpa); | 2991 | defer tree.deinit(gpa); |
| 2993 | | 2992 | |
| 2994 | for (tree.errors) |parse_error| { | 2993 | for (tree.errors) |parse_error| { |
| 2995 | try printErrMsgToFile(gpa, parse_error, tree, "<stdin>", stderr_file, color); | 2994 | try printErrMsgToStdErr(gpa, parse_error, tree, "<stdin>", color); |
| 2996 | } | 2995 | } |
| 2997 | if (tree.errors.len != 0) { | 2996 | if (tree.errors.len != 0) { |
| 2998 | process.exit(1); | 2997 | process.exit(1); |
| ... | @@ -3136,7 +3135,7 @@ fn fmtPathFile( | ... | @@ -3136,7 +3135,7 @@ fn fmtPathFile( |
| 3136 | defer tree.deinit(fmt.gpa); | 3135 | defer tree.deinit(fmt.gpa); |
| 3137 | | 3136 | |
| 3138 | for (tree.errors) |parse_error| { | 3137 | for (tree.errors) |parse_error| { |
| 3139 | try printErrMsgToFile(fmt.gpa, parse_error, tree, file_path, std.io.getStdErr(), fmt.color); | 3138 | try printErrMsgToStdErr(fmt.gpa, parse_error, tree, file_path, fmt.color); |
| 3140 | } | 3139 | } |
| 3141 | if (tree.errors.len != 0) { | 3140 | if (tree.errors.len != 0) { |
| 3142 | fmt.any_error = true; | 3141 | fmt.any_error = true; |
| ... | @@ -3166,25 +3165,16 @@ fn fmtPathFile( | ... | @@ -3166,25 +3165,16 @@ fn fmtPathFile( |
| 3166 | } | 3165 | } |
| 3167 | } | 3166 | } |
| 3168 | | 3167 | |
| 3169 | fn printErrMsgToFile( | 3168 | fn printErrMsgToStdErr( |
| 3170 | gpa: *mem.Allocator, | 3169 | gpa: *mem.Allocator, |
| 3171 | parse_error: ast.Error, | 3170 | parse_error: ast.Error, |
| 3172 | tree: ast.Tree, | 3171 | tree: ast.Tree, |
| 3173 | path: []const u8, | 3172 | path: []const u8, |
| 3174 | file: fs.File, | | |
| 3175 | color: Color, | 3173 | color: Color, |
| 3176 | ) !void { | 3174 | ) !void { |
| 3177 | const color_on = switch (color) { | | |
| 3178 | .auto => file.isTty(), | | |
| 3179 | .on => true, | | |
| 3180 | .off => false, | | |
| 3181 | }; | | |
| 3182 | const lok_token = parse_error.token; | 3175 | const lok_token = parse_error.token; |
| 3183 | | | |
| 3184 | const token_starts = tree.tokens.items(.start); | | |
| 3185 | const token_tags = tree.tokens.items(.tag); | | |
| 3186 | const first_token_start = token_starts[lok_token]; | | |
| 3187 | const start_loc = tree.tokenLocation(0, lok_token); | 3176 | const start_loc = tree.tokenLocation(0, lok_token); |
| | 3177 | const source_line = tree.source[start_loc.line_start..start_loc.line_end]; |
| 3188 | | 3178 | |
| 3189 | var text_buf = std.ArrayList(u8).init(gpa); | 3179 | var text_buf = std.ArrayList(u8).init(gpa); |
| 3190 | defer text_buf.deinit(); | 3180 | defer text_buf.deinit(); |
| ... | @@ -3192,26 +3182,24 @@ fn printErrMsgToFile( | ... | @@ -3192,26 +3182,24 @@ fn printErrMsgToFile( |
| 3192 | try tree.renderError(parse_error, writer); | 3182 | try tree.renderError(parse_error, writer); |
| 3193 | const text = text_buf.items; | 3183 | const text = text_buf.items; |
| 3194 | | 3184 | |
| 3195 | const stream = file.writer(); | 3185 | const message: Compilation.AllErrors.Message = .{ |
| 3196 | try stream.print("{s}:{d}:{d}: error: {s}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text }); | 3186 | .src = .{ |
| | 3187 | .src_path = path, |
| | 3188 | .msg = text, |
| | 3189 | .byte_offset = @intCast(u32, start_loc.line_start), |
| | 3190 | .line = @intCast(u32, start_loc.line), |
| | 3191 | .column = @intCast(u32, start_loc.column), |
| | 3192 | .source_line = source_line, |
| | 3193 | }, |
| | 3194 | }; |
| 3197 | | 3195 | |
| 3198 | if (!color_on) return; | 3196 | const ttyconf: std.debug.TTY.Config = switch (color) { |
| | 3197 | .auto => std.debug.detectTTYConfig(), |
| | 3198 | .on => .escape_codes, |
| | 3199 | .off => .no_color, |
| | 3200 | }; |
| 3199 | | 3201 | |
| 3200 | // Print \r and \t as one space each so that column counts line up | 3202 | message.renderToStdErr(ttyconf); |
| 3201 | for (tree.source[start_loc.line_start..start_loc.line_end]) |byte| { | | |
| 3202 | try stream.writeByte(switch (byte) { | | |
| 3203 | '\r', '\t' => ' ', | | |
| 3204 | else => byte, | | |
| 3205 | }); | | |
| 3206 | } | | |
| 3207 | try stream.writeByte('\n'); | | |
| 3208 | try stream.writeByteNTimes(' ', start_loc.column); | | |
| 3209 | if (token_tags[lok_token].lexeme()) |lexeme| { | | |
| 3210 | try stream.writeByteNTimes('~', lexeme.len); | | |
| 3211 | try stream.writeByte('\n'); | | |
| 3212 | } else { | | |
| 3213 | try stream.writeAll("^\n"); | | |
| 3214 | } | | |
| 3215 | } | 3203 | } |
| 3216 | | 3204 | |
| 3217 | pub const info_zen = | 3205 | pub const info_zen = |
| ... | @@ -3726,7 +3714,7 @@ pub fn cmdAstCheck( | ... | @@ -3726,7 +3714,7 @@ pub fn cmdAstCheck( |
| 3726 | defer file.tree.deinit(gpa); | 3714 | defer file.tree.deinit(gpa); |
| 3727 | | 3715 | |
| 3728 | for (file.tree.errors) |parse_error| { | 3716 | for (file.tree.errors) |parse_error| { |
| 3729 | try printErrMsgToFile(gpa, parse_error, file.tree, file.sub_file_path, io.getStdErr(), color); | 3717 | try printErrMsgToStdErr(gpa, parse_error, file.tree, file.sub_file_path, color); |
| 3730 | } | 3718 | } |
| 3731 | if (file.tree.errors.len != 0) { | 3719 | if (file.tree.errors.len != 0) { |
| 3732 | process.exit(1); | 3720 | process.exit(1); |
| ... | @@ -3847,7 +3835,7 @@ pub fn cmdChangelist( | ... | @@ -3847,7 +3835,7 @@ pub fn cmdChangelist( |
| 3847 | defer file.tree.deinit(gpa); | 3835 | defer file.tree.deinit(gpa); |
| 3848 | | 3836 | |
| 3849 | for (file.tree.errors) |parse_error| { | 3837 | for (file.tree.errors) |parse_error| { |
| 3850 | try printErrMsgToFile(gpa, parse_error, file.tree, old_source_file, io.getStdErr(), .auto); | 3838 | try printErrMsgToStdErr(gpa, parse_error, file.tree, old_source_file, .auto); |
| 3851 | } | 3839 | } |
| 3852 | if (file.tree.errors.len != 0) { | 3840 | if (file.tree.errors.len != 0) { |
| 3853 | process.exit(1); | 3841 | process.exit(1); |
| ... | @@ -3884,7 +3872,7 @@ pub fn cmdChangelist( | ... | @@ -3884,7 +3872,7 @@ pub fn cmdChangelist( |
| 3884 | defer new_tree.deinit(gpa); | 3872 | defer new_tree.deinit(gpa); |
| 3885 | | 3873 | |
| 3886 | for (new_tree.errors) |parse_error| { | 3874 | for (new_tree.errors) |parse_error| { |
| 3887 | try printErrMsgToFile(gpa, parse_error, new_tree, new_source_file, io.getStdErr(), .auto); | 3875 | try printErrMsgToStdErr(gpa, parse_error, new_tree, new_source_file, .auto); |
| 3888 | } | 3876 | } |
| 3889 | if (new_tree.errors.len != 0) { | 3877 | if (new_tree.errors.len != 0) { |
| 3890 | process.exit(1); | 3878 | process.exit(1); |