| ... | @@ -11,6 +11,7 @@ pub const Dependency = struct { | ... | @@ -11,6 +11,7 @@ pub const Dependency = struct { |
| 11 | location_tok: Ast.TokenIndex, | 11 | location_tok: Ast.TokenIndex, |
| 12 | hash: ?[]const u8, | 12 | hash: ?[]const u8, |
| 13 | hash_tok: Ast.TokenIndex, | 13 | hash_tok: Ast.TokenIndex, |
| | 14 | node: Ast.Node.Index, |
| 14 | | 15 | |
| 15 | pub const Location = union(enum) { | 16 | pub const Location = union(enum) { |
| 16 | url: []const u8, | 17 | url: []const u8, |
| ... | @@ -55,7 +56,9 @@ comptime { | ... | @@ -55,7 +56,9 @@ comptime { |
| 55 | | 56 | |
| 56 | name: []const u8, | 57 | name: []const u8, |
| 57 | version: std.SemanticVersion, | 58 | version: std.SemanticVersion, |
| | 59 | version_node: Ast.Node.Index, |
| 58 | dependencies: std.StringArrayHashMapUnmanaged(Dependency), | 60 | dependencies: std.StringArrayHashMapUnmanaged(Dependency), |
| | 61 | dependencies_node: Ast.Node.Index, |
| 59 | paths: std.StringArrayHashMapUnmanaged(void), | 62 | paths: std.StringArrayHashMapUnmanaged(void), |
| 60 | minimum_zig_version: ?std.SemanticVersion, | 63 | minimum_zig_version: ?std.SemanticVersion, |
| 61 | | 64 | |
| ... | @@ -68,7 +71,7 @@ pub const ParseOptions = struct { | ... | @@ -68,7 +71,7 @@ pub const ParseOptions = struct { |
| 68 | | 71 | |
| 69 | pub const Error = Allocator.Error; | 72 | pub const Error = Allocator.Error; |
| 70 | | 73 | |
| 71 | pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Manifest { | 74 | pub fn parse(gpa: Allocator, ast: Ast, options: ParseOptions) Error!Manifest { |
| 72 | const node_tags = ast.nodes.items(.tag); | 75 | const node_tags = ast.nodes.items(.tag); |
| 73 | const node_datas = ast.nodes.items(.data); | 76 | const node_datas = ast.nodes.items(.data); |
| 74 | assert(node_tags[0] == .root); | 77 | assert(node_tags[0] == .root); |
| ... | @@ -85,7 +88,9 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Mani | ... | @@ -85,7 +88,9 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Mani |
| 85 | | 88 | |
| 86 | .name = undefined, | 89 | .name = undefined, |
| 87 | .version = undefined, | 90 | .version = undefined, |
| | 91 | .version_node = 0, |
| 88 | .dependencies = .{}, | 92 | .dependencies = .{}, |
| | 93 | .dependencies_node = 0, |
| 89 | .paths = .{}, | 94 | .paths = .{}, |
| 90 | .allow_missing_paths_field = options.allow_missing_paths_field, | 95 | .allow_missing_paths_field = options.allow_missing_paths_field, |
| 91 | .minimum_zig_version = null, | 96 | .minimum_zig_version = null, |
| ... | @@ -104,7 +109,9 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Mani | ... | @@ -104,7 +109,9 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Mani |
| 104 | return .{ | 109 | return .{ |
| 105 | .name = p.name, | 110 | .name = p.name, |
| 106 | .version = p.version, | 111 | .version = p.version, |
| | 112 | .version_node = p.version_node, |
| 107 | .dependencies = try p.dependencies.clone(p.arena), | 113 | .dependencies = try p.dependencies.clone(p.arena), |
| | 114 | .dependencies_node = p.dependencies_node, |
| 108 | .paths = try p.paths.clone(p.arena), | 115 | .paths = try p.paths.clone(p.arena), |
| 109 | .minimum_zig_version = p.minimum_zig_version, | 116 | .minimum_zig_version = p.minimum_zig_version, |
| 110 | .errors = try p.arena.dupe(ErrorMessage, p.errors.items), | 117 | .errors = try p.arena.dupe(ErrorMessage, p.errors.items), |
| ... | @@ -117,6 +124,33 @@ pub fn deinit(man: *Manifest, gpa: Allocator) void { | ... | @@ -117,6 +124,33 @@ pub fn deinit(man: *Manifest, gpa: Allocator) void { |
| 117 | man.* = undefined; | 124 | man.* = undefined; |
| 118 | } | 125 | } |
| 119 | | 126 | |
| | 127 | pub fn copyErrorsIntoBundle( |
| | 128 | man: Manifest, |
| | 129 | ast: Ast, |
| | 130 | /// ErrorBundle null-terminated string index |
| | 131 | src_path: u32, |
| | 132 | eb: *std.zig.ErrorBundle.Wip, |
| | 133 | ) Allocator.Error!void { |
| | 134 | const token_starts = ast.tokens.items(.start); |
| | 135 | |
| | 136 | for (man.errors) |msg| { |
| | 137 | const start_loc = ast.tokenLocation(0, msg.tok); |
| | 138 | |
| | 139 | try eb.addRootErrorMessage(.{ |
| | 140 | .msg = try eb.addString(msg.msg), |
| | 141 | .src_loc = try eb.addSourceLocation(.{ |
| | 142 | .src_path = src_path, |
| | 143 | .span_start = token_starts[msg.tok], |
| | 144 | .span_end = @intCast(token_starts[msg.tok] + ast.tokenSlice(msg.tok).len), |
| | 145 | .span_main = token_starts[msg.tok] + msg.off, |
| | 146 | .line = @intCast(start_loc.line), |
| | 147 | .column = @intCast(start_loc.column), |
| | 148 | .source_line = try eb.addString(ast.source[start_loc.line_start..start_loc.line_end]), |
| | 149 | }), |
| | 150 | }); |
| | 151 | } |
| | 152 | } |
| | 153 | |
| 120 | const hex_charset = "0123456789abcdef"; | 154 | const hex_charset = "0123456789abcdef"; |
| 121 | | 155 | |
| 122 | pub fn hex64(x: u64) [16]u8 { | 156 | pub fn hex64(x: u64) [16]u8 { |
| ... | @@ -153,14 +187,16 @@ pub fn hexDigest(digest: Digest) MultiHashHexDigest { | ... | @@ -153,14 +187,16 @@ pub fn hexDigest(digest: Digest) MultiHashHexDigest { |
| 153 | | 187 | |
| 154 | const Parse = struct { | 188 | const Parse = struct { |
| 155 | gpa: Allocator, | 189 | gpa: Allocator, |
| 156 | ast: std.zig.Ast, | 190 | ast: Ast, |
| 157 | arena: Allocator, | 191 | arena: Allocator, |
| 158 | buf: std.ArrayListUnmanaged(u8), | 192 | buf: std.ArrayListUnmanaged(u8), |
| 159 | errors: std.ArrayListUnmanaged(ErrorMessage), | 193 | errors: std.ArrayListUnmanaged(ErrorMessage), |
| 160 | | 194 | |
| 161 | name: []const u8, | 195 | name: []const u8, |
| 162 | version: std.SemanticVersion, | 196 | version: std.SemanticVersion, |
| | 197 | version_node: Ast.Node.Index, |
| 163 | dependencies: std.StringArrayHashMapUnmanaged(Dependency), | 198 | dependencies: std.StringArrayHashMapUnmanaged(Dependency), |
| | 199 | dependencies_node: Ast.Node.Index, |
| 164 | paths: std.StringArrayHashMapUnmanaged(void), | 200 | paths: std.StringArrayHashMapUnmanaged(void), |
| 165 | allow_missing_paths_field: bool, | 201 | allow_missing_paths_field: bool, |
| 166 | minimum_zig_version: ?std.SemanticVersion, | 202 | minimum_zig_version: ?std.SemanticVersion, |
| ... | @@ -188,6 +224,7 @@ const Parse = struct { | ... | @@ -188,6 +224,7 @@ const Parse = struct { |
| 188 | // things manually provides an opportunity to do any additional verification | 224 | // things manually provides an opportunity to do any additional verification |
| 189 | // that is desirable on a per-field basis. | 225 | // that is desirable on a per-field basis. |
| 190 | if (mem.eql(u8, field_name, "dependencies")) { | 226 | if (mem.eql(u8, field_name, "dependencies")) { |
| | 227 | p.dependencies_node = field_init; |
| 191 | try parseDependencies(p, field_init); | 228 | try parseDependencies(p, field_init); |
| 192 | } else if (mem.eql(u8, field_name, "paths")) { | 229 | } else if (mem.eql(u8, field_name, "paths")) { |
| 193 | have_included_paths = true; | 230 | have_included_paths = true; |
| ... | @@ -196,6 +233,7 @@ const Parse = struct { | ... | @@ -196,6 +233,7 @@ const Parse = struct { |
| 196 | p.name = try parseString(p, field_init); | 233 | p.name = try parseString(p, field_init); |
| 197 | have_name = true; | 234 | have_name = true; |
| 198 | } else if (mem.eql(u8, field_name, "version")) { | 235 | } else if (mem.eql(u8, field_name, "version")) { |
| | 236 | p.version_node = field_init; |
| 199 | const version_text = try parseString(p, field_init); | 237 | const version_text = try parseString(p, field_init); |
| 200 | p.version = std.SemanticVersion.parse(version_text) catch |err| v: { | 238 | p.version = std.SemanticVersion.parse(version_text) catch |err| v: { |
| 201 | try appendError(p, main_tokens[field_init], "unable to parse semantic version: {s}", .{@errorName(err)}); | 239 | try appendError(p, main_tokens[field_init], "unable to parse semantic version: {s}", .{@errorName(err)}); |
| ... | @@ -264,6 +302,7 @@ const Parse = struct { | ... | @@ -264,6 +302,7 @@ const Parse = struct { |
| 264 | .location_tok = 0, | 302 | .location_tok = 0, |
| 265 | .hash = null, | 303 | .hash = null, |
| 266 | .hash_tok = 0, | 304 | .hash_tok = 0, |
| | 305 | .node = node, |
| 267 | }; | 306 | }; |
| 268 | var has_location = false; | 307 | var has_location = false; |
| 269 | | 308 | |
| ... | @@ -548,7 +587,7 @@ test "basic" { | ... | @@ -548,7 +587,7 @@ test "basic" { |
| 548 | \\} | 587 | \\} |
| 549 | ; | 588 | ; |
| 550 | | 589 | |
| 551 | var ast = try std.zig.Ast.parse(gpa, example, .zon); | 590 | var ast = try Ast.parse(gpa, example, .zon); |
| 552 | defer ast.deinit(gpa); | 591 | defer ast.deinit(gpa); |
| 553 | | 592 | |
| 554 | try testing.expect(ast.errors.len == 0); | 593 | try testing.expect(ast.errors.len == 0); |
| ... | @@ -591,7 +630,7 @@ test "minimum_zig_version" { | ... | @@ -591,7 +630,7 @@ test "minimum_zig_version" { |
| 591 | \\} | 630 | \\} |
| 592 | ; | 631 | ; |
| 593 | | 632 | |
| 594 | var ast = try std.zig.Ast.parse(gpa, example, .zon); | 633 | var ast = try Ast.parse(gpa, example, .zon); |
| 595 | defer ast.deinit(gpa); | 634 | defer ast.deinit(gpa); |
| 596 | | 635 | |
| 597 | try testing.expect(ast.errors.len == 0); | 636 | try testing.expect(ast.errors.len == 0); |
| ... | @@ -623,7 +662,7 @@ test "minimum_zig_version - invalid version" { | ... | @@ -623,7 +662,7 @@ test "minimum_zig_version - invalid version" { |
| 623 | \\} | 662 | \\} |
| 624 | ; | 663 | ; |
| 625 | | 664 | |
| 626 | var ast = try std.zig.Ast.parse(gpa, example, .zon); | 665 | var ast = try Ast.parse(gpa, example, .zon); |
| 627 | defer ast.deinit(gpa); | 666 | defer ast.deinit(gpa); |
| 628 | | 667 | |
| 629 | try testing.expect(ast.errors.len == 0); | 668 | try testing.expect(ast.errors.len == 0); |