| ... | @@ -120,7 +120,20 @@ pub fn main() !void { | ... | @@ -120,7 +120,20 @@ pub fn main() !void { |
| 120 | defer aro_arena_state.deinit(); | 120 | defer aro_arena_state.deinit(); |
| 121 | const aro_arena = aro_arena_state.allocator(); | 121 | const aro_arena = aro_arena_state.allocator(); |
| 122 | | 122 | |
| 123 | var comp = aro.Compilation.init(aro_arena, std.fs.cwd()); | 123 | var stderr_buf: [512]u8 = undefined; |
| | 124 | var stderr_writer = stderr.writer(&stderr_buf); |
| | 125 | var diagnostics: aro.Diagnostics = switch (zig_integration) { |
| | 126 | false => .{ .output = .{ .to_writer = .{ |
| | 127 | .writer = &stderr_writer.interface, |
| | 128 | .color = stderr_config, |
| | 129 | } } }, |
| | 130 | true => .{ .output = .{ .to_list = .{ |
| | 131 | .arena = .init(allocator), |
| | 132 | } } }, |
| | 133 | }; |
| | 134 | defer diagnostics.deinit(); |
| | 135 | |
| | 136 | var comp = aro.Compilation.init(aro_arena, aro_arena, &diagnostics, std.fs.cwd()); |
| 124 | defer comp.deinit(); | 137 | defer comp.deinit(); |
| 125 | | 138 | |
| 126 | var argv: std.ArrayList([]const u8) = .empty; | 139 | var argv: std.ArrayList([]const u8) = .empty; |
| ... | @@ -143,20 +156,24 @@ pub fn main() !void { | ... | @@ -143,20 +156,24 @@ pub fn main() !void { |
| 143 | try stdout.flush(); | 156 | try stdout.flush(); |
| 144 | } | 157 | } |
| 145 | | 158 | |
| 146 | preprocess.preprocess(&comp, &preprocessed_buf.writer, argv.items, maybe_dependencies) catch |err| switch (err) { | 159 | preprocess.preprocess(&comp, &preprocessed_buf.writer, argv.items, maybe_dependencies_list) catch |err| switch (err) { |
| 147 | error.GeneratedSourceError => { | 160 | error.GeneratedSourceError => { |
| 148 | try error_handler.emitAroDiagnostics(allocator, "failed during preprocessor setup (this is always a bug):", &comp); | 161 | try error_handler.emitAroDiagnostics(allocator, "failed during preprocessor setup (this is always a bug)", &comp); |
| 149 | std.process.exit(1); | 162 | std.process.exit(1); |
| 150 | }, | 163 | }, |
| 151 | // ArgError can occur if e.g. the .rc file is not found | 164 | // ArgError can occur if e.g. the .rc file is not found |
| 152 | error.ArgError, error.PreprocessError => { | 165 | error.ArgError, error.PreprocessError => { |
| 153 | try error_handler.emitAroDiagnostics(allocator, "failed during preprocessing:", &comp); | 166 | try error_handler.emitAroDiagnostics(allocator, "failed during preprocessing", &comp); |
| 154 | std.process.exit(1); | 167 | std.process.exit(1); |
| 155 | }, | 168 | }, |
| 156 | error.StreamTooLong => { | 169 | error.FileTooBig => { |
| 157 | try error_handler.emitMessage(allocator, .err, "failed during preprocessing: maximum file size exceeded", .{}); | 170 | try error_handler.emitMessage(allocator, .err, "failed during preprocessing: maximum file size exceeded", .{}); |
| 158 | std.process.exit(1); | 171 | std.process.exit(1); |
| 159 | }, | 172 | }, |
| | 173 | error.WriteFailed => { |
| | 174 | try error_handler.emitMessage(allocator, .err, "failed during preprocessing: error writing the preprocessed output", .{}); |
| | 175 | std.process.exit(1); |
| | 176 | }, |
| 160 | error.OutOfMemory => |e| return e, | 177 | error.OutOfMemory => |e| return e, |
| 161 | }; | 178 | }; |
| 162 | | 179 | |
| ... | @@ -660,11 +677,10 @@ const ErrorHandler = union(enum) { | ... | @@ -660,11 +677,10 @@ const ErrorHandler = union(enum) { |
| 660 | try server.serveErrorBundle(error_bundle); | 677 | try server.serveErrorBundle(error_bundle); |
| 661 | }, | 678 | }, |
| 662 | .tty => { | 679 | .tty => { |
| 663 | // extra newline to separate this line from the aro errors | 680 | // aro errors have already been emitted |
| 664 | const stderr = std.debug.lockStderrWriter(&.{}); | 681 | const stderr = std.debug.lockStderrWriter(&.{}); |
| 665 | defer std.debug.unlockStderrWriter(); | 682 | defer std.debug.unlockStderrWriter(); |
| 666 | try renderErrorMessage(stderr, self.tty, .err, "{s}\n", .{fail_msg}); | 683 | try renderErrorMessage(stderr, self.tty, .err, "{s}", .{fail_msg}); |
| 667 | aro.Diagnostics.render(comp, self.tty); | | |
| 668 | }, | 684 | }, |
| 669 | } | 685 | } |
| 670 | } | 686 | } |
| ... | @@ -883,12 +899,10 @@ fn aroDiagnosticsToErrorBundle( | ... | @@ -883,12 +899,10 @@ fn aroDiagnosticsToErrorBundle( |
| 883 | .msg = try bundle.addString(fail_msg), | 899 | .msg = try bundle.addString(fail_msg), |
| 884 | }); | 900 | }); |
| 885 | | 901 | |
| 886 | var msg_writer = MsgWriter.init(gpa); | | |
| 887 | defer msg_writer.deinit(); | | |
| 888 | var cur_err: ?ErrorBundle.ErrorMessage = null; | 902 | var cur_err: ?ErrorBundle.ErrorMessage = null; |
| 889 | var cur_notes: std.ArrayList(ErrorBundle.ErrorMessage) = .empty; | 903 | var cur_notes: std.ArrayList(ErrorBundle.ErrorMessage) = .empty; |
| 890 | defer cur_notes.deinit(gpa); | 904 | defer cur_notes.deinit(gpa); |
| 891 | for (comp.diagnostics.list.items) |msg| { | 905 | for (comp.diagnostics.output.to_list.messages.items) |msg| { |
| 892 | switch (msg.kind) { | 906 | switch (msg.kind) { |
| 893 | // Clear the current error so that notes don't bleed into unassociated errors | 907 | // Clear the current error so that notes don't bleed into unassociated errors |
| 894 | .off, .warning => { | 908 | .off, .warning => { |
| ... | @@ -897,28 +911,19 @@ fn aroDiagnosticsToErrorBundle( | ... | @@ -897,28 +911,19 @@ fn aroDiagnosticsToErrorBundle( |
| 897 | }, | 911 | }, |
| 898 | .note => if (cur_err == null) continue, | 912 | .note => if (cur_err == null) continue, |
| 899 | .@"fatal error", .@"error" => {}, | 913 | .@"fatal error", .@"error" => {}, |
| 900 | .default => unreachable, | | |
| 901 | } | 914 | } |
| 902 | msg_writer.resetRetainingCapacity(); | | |
| 903 | aro.Diagnostics.renderMessage(comp, &msg_writer, msg); | | |
| 904 | | 915 | |
| 905 | const src_loc = src_loc: { | 916 | const src_loc = src_loc: { |
| 906 | if (msg_writer.path) |src_path| { | 917 | if (msg.location) |location| { |
| 907 | var src_loc: ErrorBundle.SourceLocation = .{ | 918 | break :src_loc try bundle.addSourceLocation(.{ |
| 908 | .src_path = try bundle.addString(src_path), | 919 | .src_path = try bundle.addString(location.path), |
| 909 | .line = msg_writer.line - 1, // 1-based -> 0-based | 920 | .line = location.line_no - 1, // 1-based -> 0-based |
| 910 | .column = msg_writer.col - 1, // 1-based -> 0-based | 921 | .column = location.col - 1, // 1-based -> 0-based |
| 911 | .span_start = 0, | 922 | .span_start = location.width, |
| 912 | .span_main = 0, | 923 | .span_main = location.width, |
| 913 | .span_end = 0, | 924 | .span_end = location.width, |
| 914 | }; | 925 | .source_line = try bundle.addString(location.line), |
| 915 | if (msg_writer.source_line) |source_line| { | 926 | }); |
| 916 | src_loc.span_start = msg_writer.span_main; | | |
| 917 | src_loc.span_main = msg_writer.span_main; | | |
| 918 | src_loc.span_end = msg_writer.span_main; | | |
| 919 | src_loc.source_line = try bundle.addString(source_line); | | |
| 920 | } | | |
| 921 | break :src_loc try bundle.addSourceLocation(src_loc); | | |
| 922 | } | 927 | } |
| 923 | break :src_loc ErrorBundle.SourceLocationIndex.none; | 928 | break :src_loc ErrorBundle.SourceLocationIndex.none; |
| 924 | }; | 929 | }; |
| ... | @@ -929,7 +934,7 @@ fn aroDiagnosticsToErrorBundle( | ... | @@ -929,7 +934,7 @@ fn aroDiagnosticsToErrorBundle( |
| 929 | try flushErrorMessageIntoBundle(&bundle, err, cur_notes.items); | 934 | try flushErrorMessageIntoBundle(&bundle, err, cur_notes.items); |
| 930 | } | 935 | } |
| 931 | cur_err = .{ | 936 | cur_err = .{ |
| 932 | .msg = try bundle.addString(msg_writer.buf.items), | 937 | .msg = try bundle.addString(msg.text), |
| 933 | .src_loc = src_loc, | 938 | .src_loc = src_loc, |
| 934 | }; | 939 | }; |
| 935 | cur_notes.clearRetainingCapacity(); | 940 | cur_notes.clearRetainingCapacity(); |
| ... | @@ -937,11 +942,11 @@ fn aroDiagnosticsToErrorBundle( | ... | @@ -937,11 +942,11 @@ fn aroDiagnosticsToErrorBundle( |
| 937 | .note => { | 942 | .note => { |
| 938 | cur_err.?.notes_len += 1; | 943 | cur_err.?.notes_len += 1; |
| 939 | try cur_notes.append(gpa, .{ | 944 | try cur_notes.append(gpa, .{ |
| 940 | .msg = try bundle.addString(msg_writer.buf.items), | 945 | .msg = try bundle.addString(msg.text), |
| 941 | .src_loc = src_loc, | 946 | .src_loc = src_loc, |
| 942 | }); | 947 | }); |
| 943 | }, | 948 | }, |
| 944 | .off, .warning, .default => unreachable, | 949 | .off, .warning => unreachable, |
| 945 | } | 950 | } |
| 946 | } | 951 | } |
| 947 | if (cur_err) |err| { | 952 | if (cur_err) |err| { |
| ... | @@ -950,63 +955,3 @@ fn aroDiagnosticsToErrorBundle( | ... | @@ -950,63 +955,3 @@ fn aroDiagnosticsToErrorBundle( |
| 950 | | 955 | |
| 951 | return try bundle.toOwnedBundle(""); | 956 | return try bundle.toOwnedBundle(""); |
| 952 | } | 957 | } |
| 953 | | | |
| 954 | // Similar to aro.Diagnostics.MsgWriter but: | | |
| 955 | // - Writers to an ArrayList | | |
| 956 | // - Only prints the message itself (no location, source line, error: prefix, etc) | | |
| 957 | // - Keeps track of source path/line/col instead | | |
| 958 | const MsgWriter = struct { | | |
| 959 | buf: std.array_list.Managed(u8), | | |
| 960 | path: ?[]const u8 = null, | | |
| 961 | // 1-indexed | | |
| 962 | line: u32 = undefined, | | |
| 963 | col: u32 = undefined, | | |
| 964 | source_line: ?[]const u8 = null, | | |
| 965 | span_main: u32 = undefined, | | |
| 966 | | | |
| 967 | fn init(allocator: std.mem.Allocator) MsgWriter { | | |
| 968 | return .{ | | |
| 969 | .buf = std.array_list.Managed(u8).init(allocator), | | |
| 970 | }; | | |
| 971 | } | | |
| 972 | | | |
| 973 | fn deinit(m: *MsgWriter) void { | | |
| 974 | m.buf.deinit(); | | |
| 975 | } | | |
| 976 | | | |
| 977 | fn resetRetainingCapacity(m: *MsgWriter) void { | | |
| 978 | m.buf.clearRetainingCapacity(); | | |
| 979 | m.path = null; | | |
| 980 | m.source_line = null; | | |
| 981 | } | | |
| 982 | | | |
| 983 | pub fn print(m: *MsgWriter, comptime fmt: []const u8, args: anytype) void { | | |
| 984 | m.buf.print(fmt, args) catch {}; | | |
| 985 | } | | |
| 986 | | | |
| 987 | pub fn write(m: *MsgWriter, msg: []const u8) void { | | |
| 988 | m.buf.appendSlice(msg) catch {}; | | |
| 989 | } | | |
| 990 | | | |
| 991 | pub fn setColor(m: *MsgWriter, color: std.Io.tty.Color) void { | | |
| 992 | _ = m; | | |
| 993 | _ = color; | | |
| 994 | } | | |
| 995 | | | |
| 996 | pub fn location(m: *MsgWriter, path: []const u8, line: u32, col: u32) void { | | |
| 997 | m.path = path; | | |
| 998 | m.line = line; | | |
| 999 | m.col = col; | | |
| 1000 | } | | |
| 1001 | | | |
| 1002 | pub fn start(m: *MsgWriter, kind: aro.Diagnostics.Kind) void { | | |
| 1003 | _ = m; | | |
| 1004 | _ = kind; | | |
| 1005 | } | | |
| 1006 | | | |
| 1007 | pub fn end(m: *MsgWriter, maybe_line: ?[]const u8, col: u32, end_with_splice: bool) void { | | |
| 1008 | _ = end_with_splice; | | |
| 1009 | m.source_line = maybe_line; | | |
| 1010 | m.span_main = col; | | |
| 1011 | } | | |
| 1012 | }; | | |