mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
zig reduce: add transformation of replacing var init with undefined
This commit is contained in:
parent
a2f4adbd19
commit
31529f912b
@ -24,23 +24,28 @@ pub const Fixups = struct {
|
|||||||
gut_functions: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{},
|
gut_functions: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{},
|
||||||
/// These global declarations will be omitted.
|
/// These global declarations will be omitted.
|
||||||
omit_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{},
|
omit_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{},
|
||||||
|
/// These expressions will be replaced with `undefined`.
|
||||||
|
replace_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{},
|
||||||
|
|
||||||
pub fn count(f: Fixups) usize {
|
pub fn count(f: Fixups) usize {
|
||||||
return f.unused_var_decls.count() +
|
return f.unused_var_decls.count() +
|
||||||
f.gut_functions.count() +
|
f.gut_functions.count() +
|
||||||
f.omit_nodes.count();
|
f.omit_nodes.count() +
|
||||||
|
f.replace_nodes.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clearRetainingCapacity(f: *Fixups) void {
|
pub fn clearRetainingCapacity(f: *Fixups) void {
|
||||||
f.unused_var_decls.clearRetainingCapacity();
|
f.unused_var_decls.clearRetainingCapacity();
|
||||||
f.gut_functions.clearRetainingCapacity();
|
f.gut_functions.clearRetainingCapacity();
|
||||||
f.omit_nodes.clearRetainingCapacity();
|
f.omit_nodes.clearRetainingCapacity();
|
||||||
|
f.replace_nodes.clearRetainingCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(f: *Fixups, gpa: Allocator) void {
|
pub fn deinit(f: *Fixups, gpa: Allocator) void {
|
||||||
f.unused_var_decls.deinit(gpa);
|
f.unused_var_decls.deinit(gpa);
|
||||||
f.gut_functions.deinit(gpa);
|
f.gut_functions.deinit(gpa);
|
||||||
f.omit_nodes.deinit(gpa);
|
f.omit_nodes.deinit(gpa);
|
||||||
|
f.replace_nodes.deinit(gpa);
|
||||||
f.* = undefined;
|
f.* = undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -272,6 +277,11 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
|
|||||||
const main_tokens = tree.nodes.items(.main_token);
|
const main_tokens = tree.nodes.items(.main_token);
|
||||||
const node_tags = tree.nodes.items(.tag);
|
const node_tags = tree.nodes.items(.tag);
|
||||||
const datas = tree.nodes.items(.data);
|
const datas = tree.nodes.items(.data);
|
||||||
|
if (r.fixups.replace_nodes.contains(node)) {
|
||||||
|
try ais.writer().writeAll("undefined");
|
||||||
|
try renderOnlySpace(r, space);
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (node_tags[node]) {
|
switch (node_tags[node]) {
|
||||||
.identifier => {
|
.identifier => {
|
||||||
const token_index = main_tokens[node];
|
const token_index = main_tokens[node];
|
||||||
@ -2775,6 +2785,19 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn renderOnlySpace(r: *Render, space: Space) Error!void {
|
||||||
|
const ais = r.ais;
|
||||||
|
switch (space) {
|
||||||
|
.none => {},
|
||||||
|
.space => try ais.writer().writeByte(' '),
|
||||||
|
.newline => try ais.insertNewline(),
|
||||||
|
.comma => try ais.writer().writeAll(",\n"),
|
||||||
|
.comma_space => try ais.writer().writeAll(", "),
|
||||||
|
.semicolon => try ais.writer().writeAll(";\n"),
|
||||||
|
.skip => unreachable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const QuoteBehavior = enum {
|
const QuoteBehavior = enum {
|
||||||
preserve_when_shadowing,
|
preserve_when_shadowing,
|
||||||
eagerly_unquote,
|
eagerly_unquote,
|
||||||
|
|||||||
@ -253,6 +253,9 @@ fn transformationsToFixups(
|
|||||||
.delete_node => |decl_node| {
|
.delete_node => |decl_node| {
|
||||||
try fixups.omit_nodes.put(gpa, decl_node, {});
|
try fixups.omit_nodes.put(gpa, decl_node, {});
|
||||||
},
|
},
|
||||||
|
.replace_with_undef => |node| {
|
||||||
|
try fixups.replace_nodes.put(gpa, node, {});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,8 @@ pub const Transformation = union(enum) {
|
|||||||
gut_function: Ast.Node.Index,
|
gut_function: Ast.Node.Index,
|
||||||
/// Omit a global declaration.
|
/// Omit a global declaration.
|
||||||
delete_node: Ast.Node.Index,
|
delete_node: Ast.Node.Index,
|
||||||
|
/// Replace an expression with `undefined`.
|
||||||
|
replace_with_undef: Ast.Node.Index,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Error = error{OutOfMemory};
|
pub const Error = error{OutOfMemory};
|
||||||
@ -279,7 +281,8 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void {
|
|||||||
.local_var_decl,
|
.local_var_decl,
|
||||||
.simple_var_decl,
|
.simple_var_decl,
|
||||||
.aligned_var_decl,
|
.aligned_var_decl,
|
||||||
=> try walkVarDecl(w, ast.fullVarDecl(lhs_node).?),
|
=> try walkLocalVarDecl(w, ast.fullVarDecl(lhs_node).?),
|
||||||
|
|
||||||
else => try walkExpression(w, lhs_node),
|
else => try walkExpression(w, lhs_node),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -539,7 +542,7 @@ fn walkGlobalVarDecl(w: *Walk, decl_node: Ast.Node.Index, var_decl: Ast.full.Var
|
|||||||
return walkExpression(w, var_decl.ast.init_node);
|
return walkExpression(w, var_decl.ast.init_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walkVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void {
|
fn walkLocalVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void {
|
||||||
try walkIdentifierNew(w, var_decl.ast.mut_token + 1); // name
|
try walkIdentifierNew(w, var_decl.ast.mut_token + 1); // name
|
||||||
|
|
||||||
if (var_decl.ast.type_node != 0) {
|
if (var_decl.ast.type_node != 0) {
|
||||||
@ -559,6 +562,9 @@ fn walkVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(var_decl.ast.init_node != 0);
|
assert(var_decl.ast.init_node != 0);
|
||||||
|
if (!isUndefinedIdent(w.ast, var_decl.ast.init_node)) {
|
||||||
|
try w.transformations.append(.{ .replace_with_undef = var_decl.ast.init_node });
|
||||||
|
}
|
||||||
|
|
||||||
return walkExpression(w, var_decl.ast.init_node);
|
return walkExpression(w, var_decl.ast.init_node);
|
||||||
}
|
}
|
||||||
@ -588,7 +594,7 @@ fn walkBlock(
|
|||||||
.local_var_decl,
|
.local_var_decl,
|
||||||
.simple_var_decl,
|
.simple_var_decl,
|
||||||
.aligned_var_decl,
|
.aligned_var_decl,
|
||||||
=> try walkVarDecl(w, ast.fullVarDecl(stmt).?),
|
=> try walkLocalVarDecl(w, ast.fullVarDecl(stmt).?),
|
||||||
|
|
||||||
else => try walkExpression(w, stmt),
|
else => try walkExpression(w, stmt),
|
||||||
}
|
}
|
||||||
@ -872,3 +878,16 @@ fn isDiscardIdent(ast: *const Ast, node: Ast.Node.Index) bool {
|
|||||||
else => return false,
|
else => return false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn isUndefinedIdent(ast: *const Ast, node: Ast.Node.Index) bool {
|
||||||
|
const node_tags = ast.nodes.items(.tag);
|
||||||
|
const main_tokens = ast.nodes.items(.main_token);
|
||||||
|
switch (node_tags[node]) {
|
||||||
|
.identifier => {
|
||||||
|
const token_index = main_tokens[node];
|
||||||
|
const name_bytes = ast.tokenSlice(token_index);
|
||||||
|
return std.mem.eql(u8, name_bytes, "undefined");
|
||||||
|
},
|
||||||
|
else => return false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user