| ... | @@ -2960,7 +2960,6 @@ const Fmt = struct { | ... | @@ -2960,7 +2960,6 @@ const Fmt = struct { |
| 2960 | }; | 2960 | }; |
| 2961 | | 2961 | |
| 2962 | pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { | 2962 | pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { |
| 2963 | const stderr_file = io.getStdErr(); | | |
| 2964 | var color: Color = .auto; | 2963 | var color: Color = .auto; |
| 2965 | var stdin_flag: bool = false; | 2964 | var stdin_flag: bool = false; |
| 2966 | var check_flag: bool = false; | 2965 | var check_flag: bool = false; |
| ... | @@ -3018,7 +3017,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { | ... | @@ -3018,7 +3017,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { |
| 3018 | defer tree.deinit(gpa); | 3017 | defer tree.deinit(gpa); |
| 3019 | | 3018 | |
| 3020 | for (tree.errors) |parse_error| { | 3019 | for (tree.errors) |parse_error| { |
| 3021 | try printErrMsgToFile(gpa, parse_error, tree, "<stdin>", stderr_file, color); | 3020 | try printErrMsgToStdErr(gpa, parse_error, tree, "<stdin>", color); |
| 3022 | } | 3021 | } |
| 3023 | if (tree.errors.len != 0) { | 3022 | if (tree.errors.len != 0) { |
| 3024 | process.exit(1); | 3023 | process.exit(1); |
| ... | @@ -3163,7 +3162,7 @@ fn fmtPathFile( | ... | @@ -3163,7 +3162,7 @@ fn fmtPathFile( |
| 3163 | defer tree.deinit(fmt.gpa); | 3162 | defer tree.deinit(fmt.gpa); |
| 3164 | | 3163 | |
| 3165 | for (tree.errors) |parse_error| { | 3164 | for (tree.errors) |parse_error| { |
| 3166 | try printErrMsgToFile(fmt.gpa, parse_error, tree, file_path, std.io.getStdErr(), fmt.color); | 3165 | try printErrMsgToStdErr(fmt.gpa, parse_error, tree, file_path, fmt.color); |
| 3167 | } | 3166 | } |
| 3168 | if (tree.errors.len != 0) { | 3167 | if (tree.errors.len != 0) { |
| 3169 | fmt.any_error = true; | 3168 | fmt.any_error = true; |
| ... | @@ -3239,25 +3238,16 @@ fn fmtPathFile( | ... | @@ -3239,25 +3238,16 @@ fn fmtPathFile( |
| 3239 | } | 3238 | } |
| 3240 | } | 3239 | } |
| 3241 | | 3240 | |
| 3242 | fn printErrMsgToFile( | 3241 | fn printErrMsgToStdErr( |
| 3243 | gpa: *mem.Allocator, | 3242 | gpa: *mem.Allocator, |
| 3244 | parse_error: ast.Error, | 3243 | parse_error: ast.Error, |
| 3245 | tree: ast.Tree, | 3244 | tree: ast.Tree, |
| 3246 | path: []const u8, | 3245 | path: []const u8, |
| 3247 | file: fs.File, | | |
| 3248 | color: Color, | 3246 | color: Color, |
| 3249 | ) !void { | 3247 | ) !void { |
| 3250 | const color_on = switch (color) { | | |
| 3251 | .auto => file.isTty(), | | |
| 3252 | .on => true, | | |
| 3253 | .off => false, | | |
| 3254 | }; | | |
| 3255 | const lok_token = parse_error.token; | 3248 | const lok_token = parse_error.token; |
| 3256 | | | |
| 3257 | const token_starts = tree.tokens.items(.start); | | |
| 3258 | const token_tags = tree.tokens.items(.tag); | | |
| 3259 | const first_token_start = token_starts[lok_token]; | | |
| 3260 | const start_loc = tree.tokenLocation(0, lok_token); | 3249 | const start_loc = tree.tokenLocation(0, lok_token); |
| | 3250 | const source_line = tree.source[start_loc.line_start..start_loc.line_end]; |
| 3261 | | 3251 | |
| 3262 | var text_buf = std.ArrayList(u8).init(gpa); | 3252 | var text_buf = std.ArrayList(u8).init(gpa); |
| 3263 | defer text_buf.deinit(); | 3253 | defer text_buf.deinit(); |
| ... | @@ -3265,26 +3255,24 @@ fn printErrMsgToFile( | ... | @@ -3265,26 +3255,24 @@ fn printErrMsgToFile( |
| 3265 | try tree.renderError(parse_error, writer); | 3255 | try tree.renderError(parse_error, writer); |
| 3266 | const text = text_buf.items; | 3256 | const text = text_buf.items; |
| 3267 | | 3257 | |
| 3268 | const stream = file.writer(); | 3258 | const message: Compilation.AllErrors.Message = .{ |
| 3269 | try stream.print("{s}:{d}:{d}: error: {s}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text }); | 3259 | .src = .{ |
| | 3260 | .src_path = path, |
| | 3261 | .msg = text, |
| | 3262 | .byte_offset = @intCast(u32, start_loc.line_start), |
| | 3263 | .line = @intCast(u32, start_loc.line), |
| | 3264 | .column = @intCast(u32, start_loc.column), |
| | 3265 | .source_line = source_line, |
| | 3266 | }, |
| | 3267 | }; |
| 3270 | | 3268 | |
| 3271 | if (!color_on) return; | 3269 | const ttyconf: std.debug.TTY.Config = switch (color) { |
| | 3270 | .auto => std.debug.detectTTYConfig(), |
| | 3271 | .on => .escape_codes, |
| | 3272 | .off => .no_color, |
| | 3273 | }; |
| 3272 | | 3274 | |
| 3273 | // Print \r and \t as one space each so that column counts line up | 3275 | message.renderToStdErr(ttyconf); |
| 3274 | for (tree.source[start_loc.line_start..start_loc.line_end]) |byte| { | | |
| 3275 | try stream.writeByte(switch (byte) { | | |
| 3276 | '\r', '\t' => ' ', | | |
| 3277 | else => byte, | | |
| 3278 | }); | | |
| 3279 | } | | |
| 3280 | try stream.writeByte('\n'); | | |
| 3281 | try stream.writeByteNTimes(' ', start_loc.column); | | |
| 3282 | if (token_tags[lok_token].lexeme()) |lexeme| { | | |
| 3283 | try stream.writeByteNTimes('~', lexeme.len); | | |
| 3284 | try stream.writeByte('\n'); | | |
| 3285 | } else { | | |
| 3286 | try stream.writeAll("^\n"); | | |
| 3287 | } | | |
| 3288 | } | 3276 | } |
| 3289 | | 3277 | |
| 3290 | pub const info_zen = | 3278 | pub const info_zen = |
| ... | @@ -3800,7 +3788,7 @@ pub fn cmdAstCheck( | ... | @@ -3800,7 +3788,7 @@ pub fn cmdAstCheck( |
| 3800 | defer file.tree.deinit(gpa); | 3788 | defer file.tree.deinit(gpa); |
| 3801 | | 3789 | |
| 3802 | for (file.tree.errors) |parse_error| { | 3790 | for (file.tree.errors) |parse_error| { |
| 3803 | try printErrMsgToFile(gpa, parse_error, file.tree, file.sub_file_path, io.getStdErr(), color); | 3791 | try printErrMsgToStdErr(gpa, parse_error, file.tree, file.sub_file_path, color); |
| 3804 | } | 3792 | } |
| 3805 | if (file.tree.errors.len != 0) { | 3793 | if (file.tree.errors.len != 0) { |
| 3806 | process.exit(1); | 3794 | process.exit(1); |
| ... | @@ -3921,7 +3909,7 @@ pub fn cmdChangelist( | ... | @@ -3921,7 +3909,7 @@ pub fn cmdChangelist( |
| 3921 | defer file.tree.deinit(gpa); | 3909 | defer file.tree.deinit(gpa); |
| 3922 | | 3910 | |
| 3923 | for (file.tree.errors) |parse_error| { | 3911 | for (file.tree.errors) |parse_error| { |
| 3924 | try printErrMsgToFile(gpa, parse_error, file.tree, old_source_file, io.getStdErr(), .auto); | 3912 | try printErrMsgToStdErr(gpa, parse_error, file.tree, old_source_file, .auto); |
| 3925 | } | 3913 | } |
| 3926 | if (file.tree.errors.len != 0) { | 3914 | if (file.tree.errors.len != 0) { |
| 3927 | process.exit(1); | 3915 | process.exit(1); |
| ... | @@ -3958,7 +3946,7 @@ pub fn cmdChangelist( | ... | @@ -3958,7 +3946,7 @@ pub fn cmdChangelist( |
| 3958 | defer new_tree.deinit(gpa); | 3946 | defer new_tree.deinit(gpa); |
| 3959 | | 3947 | |
| 3960 | for (new_tree.errors) |parse_error| { | 3948 | for (new_tree.errors) |parse_error| { |
| 3961 | try printErrMsgToFile(gpa, parse_error, new_tree, new_source_file, io.getStdErr(), .auto); | 3949 | try printErrMsgToStdErr(gpa, parse_error, new_tree, new_source_file, .auto); |
| 3962 | } | 3950 | } |
| 3963 | if (new_tree.errors.len != 0) { | 3951 | if (new_tree.errors.len != 0) { |
| 3964 | process.exit(1); | 3952 | process.exit(1); |