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 /src/reduce | |
| 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 'src/reduce')
| -rw-r--r-- | src/reduce/Walk.zig | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/src/reduce/Walk.zig b/src/reduce/Walk.zig index 5ef341fcbf..c68e58a4fa 100644 --- a/src/reduce/Walk.zig +++ b/src/reduce/Walk.zig @@ -2,6 +2,7 @@ const std = @import("std"); const Ast = std.zig.Ast; const Walk = @This(); const assert = std.debug.assert; +const BuiltinFn = @import("../BuiltinFn.zig"); ast: *const Ast, transformations: *std.ArrayList(Transformation), @@ -16,6 +17,11 @@ pub const Transformation = union(enum) { delete_node: Ast.Node.Index, /// Replace an expression with `undefined`. replace_with_undef: Ast.Node.Index, + /// Replace an `@import` with the imported file contents wrapped in a struct. + inline_imported_file: struct { + builtin_call_node: Ast.Node.Index, + imported_string: []const u8, + }, }; pub const Error = error{OutOfMemory}; @@ -437,16 +443,16 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { .builtin_call_two, .builtin_call_two_comma => { if (datas[node].lhs == 0) { - return walkBuiltinCall(w, main_tokens[node], &.{}); + return walkBuiltinCall(w, node, &.{}); } else if (datas[node].rhs == 0) { - return walkBuiltinCall(w, main_tokens[node], &.{datas[node].lhs}); + return walkBuiltinCall(w, node, &.{datas[node].lhs}); } else { - return walkBuiltinCall(w, main_tokens[node], &.{ datas[node].lhs, datas[node].rhs }); + return walkBuiltinCall(w, node, &.{ datas[node].lhs, datas[node].rhs }); } }, .builtin_call, .builtin_call_comma => { const params = ast.extra_data[datas[node].lhs..datas[node].rhs]; - return walkBuiltinCall(w, main_tokens[node], params); + return walkBuiltinCall(w, node, params); }, .fn_proto_simple, @@ -680,10 +686,31 @@ fn walkContainerDecl( fn walkBuiltinCall( w: *Walk, - builtin_token: Ast.TokenIndex, + call_node: Ast.Node.Index, params: []const Ast.Node.Index, ) Error!void { - _ = builtin_token; + const ast = w.ast; + const gpa = w.gpa; + const main_tokens = ast.nodes.items(.main_token); + const builtin_token = main_tokens[call_node]; + const builtin_name = ast.tokenSlice(builtin_token); + const info = BuiltinFn.list.get(builtin_name).?; + switch (info.tag) { + .import => { + const operand_node = params[0]; + const str_lit_token = main_tokens[operand_node]; + const token_bytes = ast.tokenSlice(str_lit_token); + const imported_string = std.zig.string_literal.parseAlloc(gpa, token_bytes) catch + unreachable; + if (std.mem.endsWith(u8, imported_string, ".zig")) { + try w.transformations.append(.{ .inline_imported_file = .{ + .builtin_call_node = call_node, + .imported_string = imported_string, + } }); + } + }, + else => {}, + } for (params) |param_node| { try walkExpression(w, param_node); } |
