diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-11-04 13:57:29 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-11-04 13:57:29 -0700 |
| commit | 8bd01d2d9bbda1a2e044223db4b2272e7c5020a0 (patch) | |
| tree | 9f7a7726478b6a1fc0a9b26385a08cf95b5d6e4c /lib/std | |
| parent | 98dc28bbe223cb7183aabe7ed7a847c67c1a4df9 (diff) | |
| download | zig-8bd01d2d9bbda1a2e044223db4b2272e7c5020a0.tar.gz zig-8bd01d2d9bbda1a2e044223db4b2272e7c5020a0.zip | |
zig reduce: add transformation for inlining file-based `@import`
One thing is missing for it to be useful, however, which is dealing with
ambiguous reference errors introduced by the inlining process.
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/zig/render.zig | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 45aaf1bd28..ce63c08533 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -24,8 +24,11 @@ pub const Fixups = struct { gut_functions: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{}, /// These global declarations will be omitted. omit_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{}, - /// These expressions will be replaced with `undefined`. - replace_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{}, + /// These expressions will be replaced with the string value. + replace_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, []const u8) = .{}, + /// All `@import` builtin calls which refer to a file path will be prefixed + /// with this path. + rebase_imported_paths: ?[]const u8 = null, pub fn count(f: Fixups) usize { return f.unused_var_decls.count() + @@ -277,8 +280,8 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { const main_tokens = tree.nodes.items(.main_token); const node_tags = tree.nodes.items(.tag); const datas = tree.nodes.items(.data); - if (r.fixups.replace_nodes.contains(node)) { - try ais.writer().writeAll("undefined"); + if (r.fixups.replace_nodes.get(node)) |replacement| { + try ais.writer().writeAll(replacement); try renderOnlySpace(r, space); return; } @@ -1515,6 +1518,7 @@ fn renderBuiltinCall( const tree = r.tree; const ais = r.ais; const token_tags = tree.tokens.items(.tag); + const main_tokens = tree.nodes.items(.main_token); // TODO remove before release of 0.12.0 const slice = tree.tokenSlice(builtin_token); @@ -1609,6 +1613,26 @@ fn renderBuiltinCall( return renderToken(r, builtin_token + 2, space); // ) } + if (r.fixups.rebase_imported_paths) |prefix| { + if (mem.eql(u8, slice, "@import")) f: { + const param = params[0]; + const str_lit_token = main_tokens[param]; + assert(token_tags[str_lit_token] == .string_literal); + const token_bytes = tree.tokenSlice(str_lit_token); + const imported_string = std.zig.string_literal.parseAlloc(r.gpa, token_bytes) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.InvalidLiteral => break :f, + }; + defer r.gpa.free(imported_string); + const new_string = try std.fs.path.resolvePosix(r.gpa, &.{ prefix, imported_string }); + defer r.gpa.free(new_string); + + try renderToken(r, builtin_token + 1, .none); // ( + try ais.writer().print("\"{}\"", .{std.zig.fmtEscapes(new_string)}); + return renderToken(r, str_lit_token + 1, space); // ) + } + } + const last_param = params[params.len - 1]; const after_last_param_token = tree.lastToken(last_param) + 1; |
