| ... | @@ -24,8 +24,6 @@ const ErrorMsg = struct { | ... | @@ -24,8 +24,6 @@ const ErrorMsg = struct { |
| 24 | pub const TestContext = struct { | 24 | pub const TestContext = struct { |
| 25 | // TODO: remove these. They are deprecated. | 25 | // TODO: remove these. They are deprecated. |
| 26 | zir_cmp_output_cases: std.ArrayList(ZIRCompareOutputCase), | 26 | zir_cmp_output_cases: std.ArrayList(ZIRCompareOutputCase), |
| 27 | // TODO: remove | | |
| 28 | zir_error_cases: std.ArrayList(ZIRErrorCase), | | |
| 29 | | 27 | |
| 30 | /// TODO: find a way to treat cases as individual tests (shouldn't show "1 test passed" if there are 200 cases) | 28 | /// TODO: find a way to treat cases as individual tests (shouldn't show "1 test passed" if there are 200 cases) |
| 31 | zir_cases: std.ArrayList(ZIRCase), | 29 | zir_cases: std.ArrayList(ZIRCase), |
| ... | @@ -37,14 +35,6 @@ pub const TestContext = struct { | ... | @@ -37,14 +35,6 @@ pub const TestContext = struct { |
| 37 | expected_stdout_list: []const []const u8, | 35 | expected_stdout_list: []const []const u8, |
| 38 | }; | 36 | }; |
| 39 | | 37 | |
| 40 | // TODO: remove | | |
| 41 | pub const ZIRErrorCase = struct { | | |
| 42 | name: []const u8, | | |
| 43 | src: [:0]const u8, | | |
| 44 | expected_errors: []const ErrorMsg, | | |
| 45 | cross_target: std.zig.CrossTarget, | | |
| 46 | }; | | |
| 47 | | | |
| 48 | pub const ZIRUpdateType = enum { | 38 | pub const ZIRUpdateType = enum { |
| 49 | /// A transformation update transforms the input ZIR and tests against | 39 | /// A transformation update transforms the input ZIR and tests against |
| 50 | /// the expected output | 40 | /// the expected output |
| ... | @@ -114,6 +104,9 @@ pub const TestContext = struct { | ... | @@ -114,6 +104,9 @@ pub const TestContext = struct { |
| 114 | }) catch unreachable; | 104 | }) catch unreachable; |
| 115 | } | 105 | } |
| 116 | | 106 | |
| | 107 | /// TODO: document |
| | 108 | /// |
| | 109 | /// Errors must be specified in sequential order |
| 117 | pub fn addError(self: *ZIRCase, src: [:0]const u8, errors: []const []const u8) void { | 110 | pub fn addError(self: *ZIRCase, src: [:0]const u8, errors: []const []const u8) void { |
| 118 | var array = self.updates.allocator.alloc(ErrorMsg, errors.len) catch unreachable; | 111 | var array = self.updates.allocator.alloc(ErrorMsg, errors.len) catch unreachable; |
| 119 | for (errors) |e, i| { | 112 | for (errors) |e, i| { |
| ... | @@ -188,26 +181,24 @@ pub const TestContext = struct { | ... | @@ -188,26 +181,24 @@ pub const TestContext = struct { |
| 188 | pub fn addZIRError( | 181 | pub fn addZIRError( |
| 189 | ctx: *TestContext, | 182 | ctx: *TestContext, |
| 190 | name: []const u8, | 183 | name: []const u8, |
| 191 | cross_target: std.zig.CrossTarget, | 184 | target: std.zig.CrossTarget, |
| 192 | src: [:0]const u8, | 185 | src: [:0]const u8, |
| 193 | expected_errors: []const []const u8, | 186 | expected_errors: []const []const u8, |
| 194 | ) void {} | 187 | ) void { |
| | 188 | var c = ctx.addZIRMulti(name, target); |
| | 189 | c.addError(src, expected_errors); |
| | 190 | } |
| 195 | | 191 | |
| 196 | fn init(self: *TestContext) !void { | 192 | fn init(self: *TestContext) !void { |
| 197 | const allocator = std.heap.page_allocator; | 193 | const allocator = std.heap.page_allocator; |
| 198 | self.* = .{ | 194 | self.* = .{ |
| 199 | .zir_cmp_output_cases = std.ArrayList(ZIRCompareOutputCase).init(allocator), | 195 | .zir_cmp_output_cases = std.ArrayList(ZIRCompareOutputCase).init(allocator), |
| 200 | .zir_error_cases = std.ArrayList(ZIRErrorCase).init(allocator), | | |
| 201 | .zir_cases = std.ArrayList(ZIRCase).init(allocator), | 196 | .zir_cases = std.ArrayList(ZIRCase).init(allocator), |
| 202 | }; | 197 | }; |
| 203 | } | 198 | } |
| 204 | | 199 | |
| 205 | fn deinit(self: *TestContext) void { | 200 | fn deinit(self: *TestContext) void { |
| 206 | self.zir_cmp_output_cases.deinit(); | 201 | self.zir_cmp_output_cases.deinit(); |
| 207 | for (self.zir_error_cases.items) |e| { | | |
| 208 | self.zir_error_cases.allocator.free(e.expected_errors); | | |
| 209 | } | | |
| 210 | self.zir_error_cases.deinit(); | | |
| 211 | for (self.zir_cases.items) |c| { | 202 | for (self.zir_cases.items) |c| { |
| 212 | for (c.updates.items) |u| { | 203 | for (c.updates.items) |u| { |
| 213 | if (u.case == .Error) { | 204 | if (u.case == .Error) { |
| ... | @@ -240,12 +231,6 @@ pub const TestContext = struct { | ... | @@ -240,12 +231,6 @@ pub const TestContext = struct { |
| 240 | try self.runOneZIRCmpOutputCase(std.testing.allocator, root_node, case, native_info.target); | 231 | try self.runOneZIRCmpOutputCase(std.testing.allocator, root_node, case, native_info.target); |
| 241 | try std.testing.allocator_instance.validate(); | 232 | try std.testing.allocator_instance.validate(); |
| 242 | } | 233 | } |
| 243 | for (self.zir_error_cases.items) |case| { | | |
| 244 | std.testing.base_allocator_instance.reset(); | | |
| 245 | const info = try std.zig.system.NativeTargetInfo.detect(std.testing.allocator, case.cross_target); | | |
| 246 | try self.runOneZIRErrorCase(std.testing.allocator, root_node, case, info.target); | | |
| 247 | try std.testing.allocator_instance.validate(); | | |
| 248 | } | | |
| 249 | } | 234 | } |
| 250 | | 235 | |
| 251 | fn runOneZIRCase(self: *TestContext, allocator: *Allocator, root_node: *std.Progress.Node, case: ZIRCase, target: std.Target) !void { | 236 | fn runOneZIRCase(self: *TestContext, allocator: *Allocator, root_node: *std.Progress.Node, case: ZIRCase, target: std.Target) !void { |
| ... | @@ -419,103 +404,4 @@ pub const TestContext = struct { | ... | @@ -419,103 +404,4 @@ pub const TestContext = struct { |
| 419 | } | 404 | } |
| 420 | } | 405 | } |
| 421 | } | 406 | } |
| 422 | | | |
| 423 | fn runOneZIRErrorCase( | | |
| 424 | self: *TestContext, | | |
| 425 | allocator: *Allocator, | | |
| 426 | root_node: *std.Progress.Node, | | |
| 427 | case: ZIRErrorCase, | | |
| 428 | target: std.Target, | | |
| 429 | ) !void { | | |
| 430 | var tmp = std.testing.tmpDir(.{}); | | |
| 431 | defer tmp.cleanup(); | | |
| 432 | | | |
| 433 | var prg_node = root_node.start(case.name, 1); | | |
| 434 | prg_node.activate(); | | |
| 435 | defer prg_node.end(); | | |
| 436 | | | |
| 437 | const tmp_src_path = "test-case.zir"; | | |
| 438 | try tmp.dir.writeFile(tmp_src_path, case.src); | | |
| 439 | | | |
| 440 | const root_pkg = try Package.create(allocator, tmp.dir, ".", tmp_src_path); | | |
| 441 | defer root_pkg.destroy(); | | |
| 442 | | | |
| 443 | var module = try Module.init(allocator, .{ | | |
| 444 | .target = target, | | |
| 445 | .output_mode = .Obj, | | |
| 446 | .optimize_mode = .Debug, | | |
| 447 | .bin_file_dir = tmp.dir, | | |
| 448 | .bin_file_path = "test-case.o", | | |
| 449 | .root_pkg = root_pkg, | | |
| 450 | }); | | |
| 451 | defer module.deinit(); | | |
| 452 | | | |
| 453 | var module_node = prg_node.start("parse/analysis/codegen", null); | | |
| 454 | module_node.activate(); | | |
| 455 | try module.update(); | | |
| 456 | module_node.end(); | | |
| 457 | var err: ?anyerror = null; | | |
| 458 | | | |
| 459 | var handled_errors = allocator.alloc(bool, case.expected_errors.len) catch unreachable; | | |
| 460 | defer allocator.free(handled_errors); | | |
| 461 | for (handled_errors) |*e| { | | |
| 462 | e.* = false; | | |
| 463 | } | | |
| 464 | | | |
| 465 | var all_errors = try module.getAllErrorsAlloc(); | | |
| 466 | defer all_errors.deinit(allocator); | | |
| 467 | for (all_errors.list) |e| { | | |
| 468 | var handled = false; | | |
| 469 | for (case.expected_errors) |ex, i| { | | |
| 470 | if (e.line == ex.line and e.column == ex.column and std.mem.eql(u8, ex.msg, e.msg)) { | | |
| 471 | if (handled_errors[i]) { | | |
| 472 | err = error.ErrorReceivedMultipleTimes; | | |
| 473 | std.debug.warn("Received error multiple times: {}\n", .{e.msg}); | | |
| 474 | } else { | | |
| 475 | handled_errors[i] = true; | | |
| 476 | handled = true; | | |
| 477 | } | | |
| 478 | break; | | |
| 479 | } | | |
| 480 | } | | |
| 481 | if (!handled) { | | |
| 482 | err = error.ErrorNotExpected; | | |
| 483 | std.debug.warn("Received an unexpected error: {}:{}: {}\n", .{ e.line, e.column, e.msg }); | | |
| 484 | } | | |
| 485 | } | | |
| 486 | | | |
| 487 | for (handled_errors) |e, i| { | | |
| 488 | if (!e) { | | |
| 489 | err = error.MissingExpectedError; | | |
| 490 | const er = case.expected_errors[i]; | | |
| 491 | std.debug.warn("Did not receive error: {}:{}: {}\n", .{ er.line, er.column, er.msg }); | | |
| 492 | } | | |
| 493 | } | | |
| 494 | | | |
| 495 | if (err) |e| { | | |
| 496 | return e; | | |
| 497 | } | | |
| 498 | } | | |
| 499 | }; | 407 | }; |
| 500 | | | |
| 501 | fn debugPrintErrors(src: []const u8, errors: var) void { | | |
| 502 | std.debug.warn("\n", .{}); | | |
| 503 | var nl = true; | | |
| 504 | var line: usize = 1; | | |
| 505 | for (src) |byte| { | | |
| 506 | if (nl) { | | |
| 507 | std.debug.warn("{: >3}| ", .{line}); | | |
| 508 | nl = false; | | |
| 509 | } | | |
| 510 | if (byte == '\n') { | | |
| 511 | nl = true; | | |
| 512 | line += 1; | | |
| 513 | } | | |
| 514 | std.debug.warn("{c}", .{byte}); | | |
| 515 | } | | |
| 516 | std.debug.warn("\n", .{}); | | |
| 517 | for (errors) |err_msg| { | | |
| 518 | const loc = std.zig.findLineColumn(src, err_msg.byte_offset); | | |
| 519 | std.debug.warn("{}:{}: error: {}\n", .{ loc.line + 1, loc.column + 1, err_msg.msg }); | | |
| 520 | } | | |
| 521 | } | | |