| ... | @@ -94,12 +94,8 @@ pub const Error = struct { | ... | @@ -94,12 +94,8 @@ pub const Error = struct { |
| 94 | /// Errors encountered while parsing ZON. See `log` and `fatal` for reporting errors to the user. | 94 | /// Errors encountered while parsing ZON. See `log` and `fatal` for reporting errors to the user. |
| 95 | pub const Errors = struct { | 95 | pub const Errors = struct { |
| 96 | items: []const Error, | 96 | items: []const Error, |
| 97 | oom: bool, | | |
| 98 | | 97 | |
| 99 | pub const empty: Errors = .{ | 98 | pub const empty: Errors = .{ .items = &.{} }; |
| 100 | .items = &.{}, | | |
| 101 | .oom = false, | | |
| 102 | }; | | |
| 103 | | 99 | |
| 104 | /// Log the failure with `std.log.err`. | 100 | /// Log the failure with `std.log.err`. |
| 105 | pub fn log(self: *const Errors, path: []const u8) void { | 101 | pub fn log(self: *const Errors, path: []const u8) void { |
| ... | @@ -123,9 +119,12 @@ pub const Errors = struct { | ... | @@ -123,9 +119,12 @@ pub const Errors = struct { |
| 123 | .arena = arena, | 119 | .arena = arena, |
| 124 | .source = ".{ .foo = 1, .bar = 2 }", | 120 | .source = ".{ .foo = 1, .bar = 2 }", |
| 125 | .errors = &errors, | 121 | .errors = &errors, |
| 126 | }) catch b: { | 122 | }) catch |err| switch (err) { |
| 127 | errors.log("input.zon"); | 123 | error.OutOfMemory => return error.OutOfMemory, |
| 128 | break :b .{ .foo = 0, .bar = 0 }; | 124 | error.ParseZon => b: { |
| | 125 | errors.log("input.zon"); |
| | 126 | break :b .{ .foo = 0, .bar = 0 }; |
| | 127 | }, |
| 129 | }; | 128 | }; |
| 130 | _ = parsed; | 129 | _ = parsed; |
| 131 | } | 130 | } |
| ... | @@ -152,14 +151,16 @@ pub const Errors = struct { | ... | @@ -152,14 +151,16 @@ pub const Errors = struct { |
| 152 | .arena = arena, | 151 | .arena = arena, |
| 153 | .source = ".{ .foo = 1, .bar = 2 }", | 152 | .source = ".{ .foo = 1, .bar = 2 }", |
| 154 | .errors = &errors, | 153 | .errors = &errors, |
| 155 | }) catch errors.fatal("input.zon"); | 154 | }) catch |err| switch (err) { |
| | 155 | error.OutOfMemory => return error.OutOfMemory, |
| | 156 | error.ParseZon => errors.fatal("input.zon"), |
| | 157 | }; |
| 156 | _ = parsed; | 158 | _ = parsed; |
| 157 | } | 159 | } |
| 158 | | 160 | |
| 159 | pub fn fmt(self: *const Errors, path: []const u8) Formatter { | 161 | pub fn fmt(self: *const Errors, path: []const u8) Formatter { |
| 160 | return .{ | 162 | return .{ |
| 161 | .items = self.items, | 163 | .items = self.items, |
| 162 | .oom = self.oom, | | |
| 163 | .path = path, | 164 | .path = path, |
| 164 | }; | 165 | }; |
| 165 | } | 166 | } |
| ... | @@ -167,12 +168,8 @@ pub const Errors = struct { | ... | @@ -167,12 +168,8 @@ pub const Errors = struct { |
| 167 | pub const Formatter = struct { | 168 | pub const Formatter = struct { |
| 168 | path: []const u8, | 169 | path: []const u8, |
| 169 | items: []const Error, | 170 | items: []const Error, |
| 170 | oom: bool, | | |
| 171 | | 171 | |
| 172 | pub fn format(self: *const @This(), w: *std.Io.Writer) std.Io.Writer.Error!void { | 172 | pub fn format(self: *const @This(), w: *std.Io.Writer) std.Io.Writer.Error!void { |
| 173 | if (self.oom) { | | |
| 174 | try w.print("{s}: out of memory", .{self.path}); | | |
| 175 | } | | |
| 176 | for (self.items) |e| { | 173 | for (self.items) |e| { |
| 177 | try w.print("{s}:", .{self.path}); | 174 | try w.print("{s}:", .{self.path}); |
| 178 | try w.print("{d}:{d}: error: {s}\n", .{ | 175 | try w.print("{d}:{d}: error: {s}\n", .{ |
| ... | @@ -192,11 +189,6 @@ pub const Errors = struct { | ... | @@ -192,11 +189,6 @@ pub const Errors = struct { |
| 192 | } | 189 | } |
| 193 | } | 190 | } |
| 194 | }; | 191 | }; |
| 195 | | | |
| 196 | fn checkOom(self: *Errors, result: anytype) @TypeOf(result) { | | |
| 197 | self.oom |= result == error.OutOfMemory; | | |
| 198 | return result; | | |
| 199 | } | | |
| 200 | }; | 192 | }; |
| 201 | | 193 | |
| 202 | pub const Options = struct { | 194 | pub const Options = struct { |
| ... | @@ -246,9 +238,12 @@ test fromSlice { | ... | @@ -246,9 +238,12 @@ test fromSlice { |
| 246 | .arena = arena, | 238 | .arena = arena, |
| 247 | .source = source, | 239 | .source = source, |
| 248 | .errors = &errors, | 240 | .errors = &errors, |
| 249 | }) catch |err| { | 241 | }) catch |err| switch (err) { |
| 250 | errors.log("texture_options.zon"); | 242 | error.OutOfMemory => return err, |
| 251 | return err; | 243 | error.ParseZon => { |
| | 244 | errors.log("texture_options.zon"); |
| | 245 | return err; |
| | 246 | }, |
| 252 | }; | 247 | }; |
| 253 | | 248 | |
| 254 | try std.testing.expectEqualDeep(TextureOptions{ | 249 | try std.testing.expectEqualDeep(TextureOptions{ |
| ... | @@ -318,18 +313,24 @@ test updateFromSlice { | ... | @@ -318,18 +313,24 @@ test updateFromSlice { |
| 318 | .arena = arena, | 313 | .arena = arena, |
| 319 | .source = global_config, | 314 | .source = global_config, |
| 320 | .errors = &errors, | 315 | .errors = &errors, |
| 321 | }) catch |err| { | 316 | }) catch |err| switch (err) { |
| 322 | errors.log("global_config.zon"); | 317 | error.OutOfMemory => return err, |
| 323 | return err; | 318 | error.ParseZon => { |
| | 319 | errors.log("global_config.zon"); |
| | 320 | return err; |
| | 321 | }, |
| 324 | }; | 322 | }; |
| 325 | updateFromSlice(MyTextEditorConfig, &config, .{ | 323 | updateFromSlice(MyTextEditorConfig, &config, .{ |
| 326 | .gpa = gpa, | 324 | .gpa = gpa, |
| 327 | .arena = arena, | 325 | .arena = arena, |
| 328 | .source = project_config, | 326 | .source = project_config, |
| 329 | .errors = &errors, | 327 | .errors = &errors, |
| 330 | }) catch |err| { | 328 | }) catch |err| switch (err) { |
| 331 | errors.log("project_config.zon"); | 329 | error.OutOfMemory => return err, |
| 332 | return err; | 330 | error.ParseZon => { |
| | 331 | errors.log("project_config.zon"); |
| | 332 | return err; |
| | 333 | }, |
| 333 | }; | 334 | }; |
| 334 | | 335 | |
| 335 | try std.testing.expectEqualDeep(MyTextEditorConfig{ | 336 | try std.testing.expectEqualDeep(MyTextEditorConfig{ |
| ... | @@ -357,32 +358,23 @@ fn fromSliceInner( | ... | @@ -357,32 +358,23 @@ fn fromSliceInner( |
| 357 | initialized: bool, | 358 | initialized: bool, |
| 358 | options: Options, | 359 | options: Options, |
| 359 | ) error{ OutOfMemory, ParseZon }!void { | 360 | ) error{ OutOfMemory, ParseZon }!void { |
| 360 | options.errors.oom = false; | | |
| 361 | var errors: std.ArrayList(Error) = .empty; | 361 | var errors: std.ArrayList(Error) = .empty; |
| 362 | defer options.errors.items = errors.items; | 362 | defer options.errors.items = errors.items; |
| 363 | | 363 | |
| 364 | var ast = try options.errors.checkOom(std.zig.Ast.parse( | 364 | var ast = try std.zig.Ast.parse(options.gpa, options.source, .{ .mode = .zon }); |
| 365 | options.gpa, | | |
| 366 | options.source, | | |
| 367 | .{ .mode = .zon }, | | |
| 368 | )); | | |
| 369 | defer ast.deinit(options.gpa); | 365 | defer ast.deinit(options.gpa); |
| 370 | | 366 | |
| 371 | var zoir = try options.errors.checkOom(ZonGen.generate( | 367 | var zoir = try ZonGen.generate(options.gpa, ast, .{ .parse_str_lits = false }); |
| 372 | options.gpa, | | |
| 373 | ast, | | |
| 374 | .{ .parse_str_lits = false }, | | |
| 375 | )); | | |
| 376 | defer zoir.deinit(options.gpa); | 368 | defer zoir.deinit(options.gpa); |
| 377 | | 369 | |
| 378 | try options.errors.checkOom(inner(T, value, initialized, .{ | 370 | try inner(T, value, initialized, .{ |
| 379 | .arena = options.arena, | 371 | .arena = options.arena, |
| 380 | .ast = &ast, | 372 | .ast = &ast, |
| 381 | .zoir = &zoir, | 373 | .zoir = &zoir, |
| 382 | .node = .root, | 374 | .node = .root, |
| 383 | .errors = &errors, | 375 | .errors = &errors, |
| 384 | .ignore_unknown_fields = options.ignore_unknown_fields, | 376 | .ignore_unknown_fields = options.ignore_unknown_fields, |
| 385 | })); | 377 | }); |
| 386 | } | 378 | } |
| 387 | | 379 | |
| 388 | pub const FromZoirOptions = struct { | 380 | pub const FromZoirOptions = struct { |
| ... | @@ -439,16 +431,15 @@ fn fromZoirInner( | ... | @@ -439,16 +431,15 @@ fn fromZoirInner( |
| 439 | initialized: bool, | 431 | initialized: bool, |
| 440 | options: FromZoirOptions, | 432 | options: FromZoirOptions, |
| 441 | ) error{ OutOfMemory, ParseZon }!void { | 433 | ) error{ OutOfMemory, ParseZon }!void { |
| 442 | options.errors.oom = false; | | |
| 443 | var errors: std.ArrayList(Error) = .empty; | 434 | var errors: std.ArrayList(Error) = .empty; |
| 444 | defer options.errors.items = errors.items; | 435 | defer options.errors.items = errors.items; |
| 445 | return options.errors.checkOom(inner(T, value, initialized, .{ | 436 | return inner(T, value, initialized, .{ |
| 446 | .arena = options.arena, | 437 | .arena = options.arena, |
| 447 | .ast = options.ast, | 438 | .ast = options.ast, |
| 448 | .zoir = options.zoir, | 439 | .zoir = options.zoir, |
| 449 | .errors = &errors, | 440 | .errors = &errors, |
| 450 | .ignore_unknown_fields = options.ignore_unknown_fields, | 441 | .ignore_unknown_fields = options.ignore_unknown_fields, |
| 451 | })); | 442 | }); |
| 452 | } | 443 | } |
| 453 | | 444 | |
| 454 | const InnerOptions = struct { | 445 | const InnerOptions = struct { |
| ... | @@ -1450,38 +1441,17 @@ test "std.zon failure/oom formatting" { | ... | @@ -1450,38 +1441,17 @@ test "std.zon failure/oom formatting" { |
| 1450 | var arena_allocator: ArenaAllocator = .init(gpa); | 1441 | var arena_allocator: ArenaAllocator = .init(gpa); |
| 1451 | defer arena_allocator.deinit(); | 1442 | defer arena_allocator.deinit(); |
| 1452 | const arena = arena_allocator.allocator(); | 1443 | const arena = arena_allocator.allocator(); |
| | 1444 | var errors: Errors = .empty; |
| 1453 | | 1445 | |
| 1454 | { | 1446 | try std.testing.expectError(error.OutOfMemory, fromSlice([]const u8, .{ |
| 1455 | var errors: Errors = .empty; | 1447 | .gpa = .failing, |
| 1456 | try std.testing.expectError(error.OutOfMemory, fromSlice([]const u8, .{ | 1448 | .arena = arena, |
| 1457 | .gpa = .failing, | 1449 | .source = "\"foo\"", |
| 1458 | .arena = arena, | 1450 | .errors = &errors, |
| 1459 | .source = "\"foo\"", | 1451 | })); |
| 1460 | .errors = &errors, | 1452 | try std.testing.expectFmt( |
| 1461 | })); | 1453 | \\ |
| 1462 | try std.testing.expectFmt( | 1454 | , "{f}", .{errors.fmt("input.zon")}); |
| 1463 | \\input.zon: out of memory | | |
| 1464 | , "{f}", .{errors.fmt("input.zon")}); | | |
| 1465 | } | | |
| 1466 | | | |
| 1467 | { | | |
| 1468 | var ast = try std.zig.Ast.parse(gpa, "\"foo\"", .{ .mode = .zon }); | | |
| 1469 | defer ast.deinit(gpa); | | |
| 1470 | | | |
| 1471 | var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false }); | | |
| 1472 | defer zoir.deinit(gpa); | | |
| 1473 | | | |
| 1474 | var errors: Errors = .empty; | | |
| 1475 | try std.testing.expectError(error.OutOfMemory, fromZoir([]const u8, .{ | | |
| 1476 | .arena = .failing, | | |
| 1477 | .ast = &ast, | | |
| 1478 | .zoir = &zoir, | | |
| 1479 | .errors = &errors, | | |
| 1480 | })); | | |
| 1481 | try std.testing.expectFmt( | | |
| 1482 | \\input.zon: out of memory | | |
| 1483 | , "{f}", .{errors.fmt("input.zon")}); | | |
| 1484 | } | | |
| 1485 | } | 1455 | } |
| 1486 | | 1456 | |
| 1487 | test "std.zon fromSlice syntax error" { | 1457 | test "std.zon fromSlice syntax error" { |