authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-02-23 17:23:53-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-02-26 11:42:03-08:00
loge03bc7ac78820b7763d6ecd21cfa19653535f8d0
tree0a21038656cb286c26e615dd669976d33ebbdd7a
parent12355cfb4cb14ba78423fb38838f4485bb563c9b

require package names to be valid zig identifiers


1 files changed, 29 insertions(+), 1 deletions(-)

src/Package/Manifest.zig+29-1
...@@ -46,6 +46,8 @@ arena_state: std.heap.ArenaAllocator.State,...@@ -46,6 +46,8 @@ arena_state: std.heap.ArenaAllocator.State,
4646
47pub const ParseOptions = struct {47pub const ParseOptions = struct {
48 allow_missing_paths_field: bool = false,48 allow_missing_paths_field: bool = false,
49 /// Deprecated, to be removed after 0.14.0 is tagged.
50 allow_name_string: bool = true,
49};51};
5052
51pub const Error = Allocator.Error;53pub const Error = Allocator.Error;
...@@ -72,6 +74,7 @@ pub fn parse(gpa: Allocator, ast: Ast, options: ParseOptions) Error!Manifest {...@@ -72,6 +74,7 @@ pub fn parse(gpa: Allocator, ast: Ast, options: ParseOptions) Error!Manifest {
72 .dependencies_node = 0,74 .dependencies_node = 0,
73 .paths = .{},75 .paths = .{},
74 .allow_missing_paths_field = options.allow_missing_paths_field,76 .allow_missing_paths_field = options.allow_missing_paths_field,
77 .allow_name_string = options.allow_name_string,
75 .minimum_zig_version = null,78 .minimum_zig_version = null,
76 .buf = .{},79 .buf = .{},
77 };80 };
...@@ -144,6 +147,7 @@ const Parse = struct {...@@ -144,6 +147,7 @@ const Parse = struct {
144 dependencies_node: Ast.Node.Index,147 dependencies_node: Ast.Node.Index,
145 paths: std.StringArrayHashMapUnmanaged(void),148 paths: std.StringArrayHashMapUnmanaged(void),
146 allow_missing_paths_field: bool,149 allow_missing_paths_field: bool,
150 allow_name_string: bool,
147 minimum_zig_version: ?std.SemanticVersion,151 minimum_zig_version: ?std.SemanticVersion,
148152
149 const InnerError = error{ ParseFailure, OutOfMemory };153 const InnerError = error{ ParseFailure, OutOfMemory };
...@@ -175,7 +179,7 @@ const Parse = struct {...@@ -175,7 +179,7 @@ const Parse = struct {
175 have_included_paths = true;179 have_included_paths = true;
176 try parseIncludedPaths(p, field_init);180 try parseIncludedPaths(p, field_init);
177 } else if (mem.eql(u8, field_name, "name")) {181 } else if (mem.eql(u8, field_name, "name")) {
178 p.name = try parseString(p, field_init);182 p.name = try parseName(p, field_init);
179 have_name = true;183 have_name = true;
180 } else if (mem.eql(u8, field_name, "version")) {184 } else if (mem.eql(u8, field_name, "version")) {
181 p.version_node = field_init;185 p.version_node = field_init;
...@@ -350,6 +354,30 @@ const Parse = struct {...@@ -350,6 +354,30 @@ const Parse = struct {
350 }354 }
351 }355 }
352356
357 fn parseName(p: *Parse, node: Ast.Node.Index) ![]const u8 {
358 const ast = p.ast;
359 const node_tags = ast.nodes.items(.tag);
360 const main_tokens = ast.nodes.items(.main_token);
361 const main_token = main_tokens[node];
362
363 if (p.allow_name_string and node_tags[node] == .string_literal) {
364 const name = try parseString(p, node);
365 if (!std.zig.isValidId(name))
366 return fail(p, main_token, "name must be a valid bare zig identifier (hint: switch from string to enum literal)", .{});
367
368 return name;
369 }
370
371 if (node_tags[node] != .enum_literal)
372 return fail(p, main_token, "expected enum literal", .{});
373
374 const ident_name = ast.tokenSlice(main_token);
375 if (mem.startsWith(u8, ident_name, "@"))
376 return fail(p, main_token, "name must be a valid bare zig identifier", .{});
377
378 return ident_name;
379 }
380
353 fn parseString(p: *Parse, node: Ast.Node.Index) ![]const u8 {381 fn parseString(p: *Parse, node: Ast.Node.Index) ![]const u8 {
354 const ast = p.ast;382 const ast = p.ast;
355 const node_tags = ast.nodes.items(.tag);383 const node_tags = ast.nodes.items(.tag);