Commit a0c8d54823

Andrew Kelley <andrew@ziglang.org>
2023-11-27 01:04:01
add Package.Manifest.copyErrorsIntoBundle
1 parent 70d51be
Changed files (2)
src/Package/Fetch.zig
@@ -520,24 +520,7 @@ fn loadManifest(f: *Fetch, pkg_root: Package.Path) RunError!void {
 
     if (manifest.errors.len > 0) {
         const src_path = try eb.printString("{}{s}", .{ pkg_root, Manifest.basename });
-        const token_starts = ast.tokens.items(.start);
-
-        for (manifest.errors) |msg| {
-            const start_loc = ast.tokenLocation(0, msg.tok);
-
-            try eb.addRootErrorMessage(.{
-                .msg = try eb.addString(msg.msg),
-                .src_loc = try eb.addSourceLocation(.{
-                    .src_path = src_path,
-                    .span_start = token_starts[msg.tok],
-                    .span_end = @intCast(token_starts[msg.tok] + ast.tokenSlice(msg.tok).len),
-                    .span_main = token_starts[msg.tok] + msg.off,
-                    .line = @intCast(start_loc.line),
-                    .column = @intCast(start_loc.column),
-                    .source_line = try eb.addString(ast.source[start_loc.line_start..start_loc.line_end]),
-                }),
-            });
-        }
+        try manifest.copyErrorsIntoBundle(ast.*, src_path, eb);
         return error.FetchFailed;
     }
 }
src/Package/Manifest.zig
@@ -11,6 +11,7 @@ pub const Dependency = struct {
     location_tok: Ast.TokenIndex,
     hash: ?[]const u8,
     hash_tok: Ast.TokenIndex,
+    node: Ast.Node.Index,
 
     pub const Location = union(enum) {
         url: []const u8,
@@ -55,7 +56,9 @@ comptime {
 
 name: []const u8,
 version: std.SemanticVersion,
+version_node: Ast.Node.Index,
 dependencies: std.StringArrayHashMapUnmanaged(Dependency),
+dependencies_node: Ast.Node.Index,
 paths: std.StringArrayHashMapUnmanaged(void),
 minimum_zig_version: ?std.SemanticVersion,
 
@@ -68,7 +71,7 @@ pub const ParseOptions = struct {
 
 pub const Error = Allocator.Error;
 
-pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Manifest {
+pub fn parse(gpa: Allocator, ast: Ast, options: ParseOptions) Error!Manifest {
     const node_tags = ast.nodes.items(.tag);
     const node_datas = ast.nodes.items(.data);
     assert(node_tags[0] == .root);
@@ -85,7 +88,9 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Mani
 
         .name = undefined,
         .version = undefined,
+        .version_node = 0,
         .dependencies = .{},
+        .dependencies_node = 0,
         .paths = .{},
         .allow_missing_paths_field = options.allow_missing_paths_field,
         .minimum_zig_version = null,
@@ -104,7 +109,9 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Mani
     return .{
         .name = p.name,
         .version = p.version,
+        .version_node = p.version_node,
         .dependencies = try p.dependencies.clone(p.arena),
+        .dependencies_node = p.dependencies_node,
         .paths = try p.paths.clone(p.arena),
         .minimum_zig_version = p.minimum_zig_version,
         .errors = try p.arena.dupe(ErrorMessage, p.errors.items),
@@ -117,6 +124,33 @@ pub fn deinit(man: *Manifest, gpa: Allocator) void {
     man.* = undefined;
 }
 
+pub fn copyErrorsIntoBundle(
+    man: Manifest,
+    ast: Ast,
+    /// ErrorBundle null-terminated string index
+    src_path: u32,
+    eb: *std.zig.ErrorBundle.Wip,
+) Allocator.Error!void {
+    const token_starts = ast.tokens.items(.start);
+
+    for (man.errors) |msg| {
+        const start_loc = ast.tokenLocation(0, msg.tok);
+
+        try eb.addRootErrorMessage(.{
+            .msg = try eb.addString(msg.msg),
+            .src_loc = try eb.addSourceLocation(.{
+                .src_path = src_path,
+                .span_start = token_starts[msg.tok],
+                .span_end = @intCast(token_starts[msg.tok] + ast.tokenSlice(msg.tok).len),
+                .span_main = token_starts[msg.tok] + msg.off,
+                .line = @intCast(start_loc.line),
+                .column = @intCast(start_loc.column),
+                .source_line = try eb.addString(ast.source[start_loc.line_start..start_loc.line_end]),
+            }),
+        });
+    }
+}
+
 const hex_charset = "0123456789abcdef";
 
 pub fn hex64(x: u64) [16]u8 {
@@ -153,14 +187,16 @@ pub fn hexDigest(digest: Digest) MultiHashHexDigest {
 
 const Parse = struct {
     gpa: Allocator,
-    ast: std.zig.Ast,
+    ast: Ast,
     arena: Allocator,
     buf: std.ArrayListUnmanaged(u8),
     errors: std.ArrayListUnmanaged(ErrorMessage),
 
     name: []const u8,
     version: std.SemanticVersion,
+    version_node: Ast.Node.Index,
     dependencies: std.StringArrayHashMapUnmanaged(Dependency),
+    dependencies_node: Ast.Node.Index,
     paths: std.StringArrayHashMapUnmanaged(void),
     allow_missing_paths_field: bool,
     minimum_zig_version: ?std.SemanticVersion,
@@ -188,6 +224,7 @@ const Parse = struct {
             // things manually provides an opportunity to do any additional verification
             // that is desirable on a per-field basis.
             if (mem.eql(u8, field_name, "dependencies")) {
+                p.dependencies_node = field_init;
                 try parseDependencies(p, field_init);
             } else if (mem.eql(u8, field_name, "paths")) {
                 have_included_paths = true;
@@ -196,6 +233,7 @@ const Parse = struct {
                 p.name = try parseString(p, field_init);
                 have_name = true;
             } else if (mem.eql(u8, field_name, "version")) {
+                p.version_node = field_init;
                 const version_text = try parseString(p, field_init);
                 p.version = std.SemanticVersion.parse(version_text) catch |err| v: {
                     try appendError(p, main_tokens[field_init], "unable to parse semantic version: {s}", .{@errorName(err)});
@@ -264,6 +302,7 @@ const Parse = struct {
             .location_tok = 0,
             .hash = null,
             .hash_tok = 0,
+            .node = node,
         };
         var has_location = false;
 
@@ -548,7 +587,7 @@ test "basic" {
         \\}
     ;
 
-    var ast = try std.zig.Ast.parse(gpa, example, .zon);
+    var ast = try Ast.parse(gpa, example, .zon);
     defer ast.deinit(gpa);
 
     try testing.expect(ast.errors.len == 0);
@@ -591,7 +630,7 @@ test "minimum_zig_version" {
         \\}
     ;
 
-    var ast = try std.zig.Ast.parse(gpa, example, .zon);
+    var ast = try Ast.parse(gpa, example, .zon);
     defer ast.deinit(gpa);
 
     try testing.expect(ast.errors.len == 0);
@@ -623,7 +662,7 @@ test "minimum_zig_version - invalid version" {
         \\}
     ;
 
-    var ast = try std.zig.Ast.parse(gpa, example, .zon);
+    var ast = try Ast.parse(gpa, example, .zon);
     defer ast.deinit(gpa);
 
     try testing.expect(ast.errors.len == 0);