From 25c3b6dc95847d530b8856478a2437ec17db698f Mon Sep 17 00:00:00 2001 From: Daniel Gavin Date: Wed, 21 Apr 2021 23:21:45 +0200 Subject: [PATCH] align value decls --- core/odin/printer/printer.odin | 132 ++++++++++++++++++++++++++++++++- core/odin/printer/visit.odin | 13 +++- 2 files changed, 139 insertions(+), 6 deletions(-) diff --git a/core/odin/printer/printer.odin b/core/odin/printer/printer.odin index b7c87f111..0da6a9b38 100644 --- a/core/odin/printer/printer.odin +++ b/core/odin/printer/printer.odin @@ -124,7 +124,7 @@ print :: proc(p: ^Printer, file: ^ast.File) -> string { } set_source_position(p, file.pkg_token.pos); - + p.last_source_position.line = 1; set_line(p, 0); @@ -195,7 +195,7 @@ print :: proc(p: ^Printer, file: ^ast.File) -> string { } fix_lines :: proc(p: ^Printer) { - align_var_decls_and_assignments(p); + align_var_decls(p); format_generic(p); align_comments(p); //align them last since they rely on the other alignments } @@ -439,7 +439,131 @@ format_generic :: proc(p: ^Printer) { } } -align_var_decls_and_assignments :: proc(p: ^Printer) { +align_var_decls :: proc(p: ^Printer) { + + current_line: int; + current_typed: bool; + + largest_lhs := 0; + largest_rhs := 0; + + TokenAndLength :: struct { + format_token: ^Format_Token, + length: int, + }; + + colon_tokens := make([dynamic]TokenAndLength, 0, 10, context.temp_allocator); + type_tokens := make([dynamic]TokenAndLength, 0, 10, context.temp_allocator); + equal_tokens := make([dynamic]TokenAndLength, 0, 10, context.temp_allocator); + + for line, line_index in p.lines { + + //It is only possible to align value decls that are one one line, otherwise just ignore them + if .Value_Decl not_in line.types { + continue; + } + + typed := true; + + for i := 0; i < len(line.format_tokens) - 1; i += 1 { + if line.format_tokens[i].kind == .Colon && line.format_tokens[i + 1].kind == .Eq { + typed = false; + break; + } + } + + if line_index != current_line + 1 || typed != current_typed { + + if p.config.align_style == .Align_On_Colon_And_Equals || !current_typed { + for colon_token in colon_tokens { + colon_token.format_token.spaces_before = largest_lhs - colon_token.length + 1; + } + } else if p.config.align_style == .Align_On_Type_And_Equals { + for type_token in type_tokens { + type_token.format_token.spaces_before = largest_lhs - type_token.length + 1; + } + } + + if current_typed { + for equal_token in equal_tokens { + equal_token.format_token.spaces_before = largest_rhs - equal_token.length + 1; + } + } else { + for equal_token in equal_tokens { + equal_token.format_token.spaces_before = 0; + } + } + + clear(&colon_tokens); + clear(&type_tokens); + clear(&equal_tokens); + + largest_rhs = 0; + largest_lhs = 0; + current_typed = typed; + } + + current_line = line_index; + + current_token_index := 0; + lhs_length := 0; + rhs_length := 0; + + //calcuate the length of lhs of a value decl i.e. `a, b:` + for; current_token_index < len(line.format_tokens); current_token_index += 1 { + + lhs_length += len(line.format_tokens[current_token_index].text) + line.format_tokens[current_token_index].spaces_before; + + if line.format_tokens[current_token_index].kind == .Colon { + append(&colon_tokens, TokenAndLength {format_token = &line.format_tokens[current_token_index], length = lhs_length}); + + if len(line.format_tokens) > current_token_index && line.format_tokens[current_token_index + 1].kind != .Eq { + append(&type_tokens, TokenAndLength {format_token = &line.format_tokens[current_token_index + 1], length = lhs_length}); + } + + current_token_index += 1; + + break; + } + } + + //calcuate the length of the rhs i.e. `[dynamic]int = 123123` + for; current_token_index < len(line.format_tokens); current_token_index += 1 { + + rhs_length += len(line.format_tokens[current_token_index].text) + line.format_tokens[current_token_index].spaces_before; + + if line.format_tokens[current_token_index].kind == .Eq { + append(&equal_tokens, TokenAndLength {format_token = &line.format_tokens[current_token_index], length = rhs_length}); + break; + } + } + + largest_lhs = max(largest_lhs, lhs_length); + largest_rhs = max(largest_rhs, rhs_length); + } + + fmt.println(current_typed); + + //repeating myself, move to sub procedure + if p.config.align_style == .Align_On_Colon_And_Equals || !current_typed { + for colon_token in colon_tokens { + colon_token.format_token.spaces_before = largest_lhs - colon_token.length + 1; + } + } else if p.config.align_style == .Align_On_Type_And_Equals { + for type_token in type_tokens { + type_token.format_token.spaces_before = largest_lhs - type_token.length + 1; + } + } + + if current_typed { + for equal_token in equal_tokens { + equal_token.format_token.spaces_before = largest_rhs - equal_token.length + 1; + } + } else { + for equal_token in equal_tokens { + equal_token.format_token.spaces_before = 0; + } + } } align_switch_stmt :: proc(p: ^Printer, index: int) { @@ -699,4 +823,4 @@ align_comments :: proc(p: ^Printer) { } } } -} \ No newline at end of file +} diff --git a/core/odin/printer/visit.odin b/core/odin/printer/visit.odin index 953e0951f..67d0fdc50 100644 --- a/core/odin/printer/visit.odin +++ b/core/odin/printer/visit.odin @@ -485,7 +485,10 @@ visit_exprs :: proc(p: ^Printer, list: []^ast.Expr, add_comma := false, trailing //we have to newline the expressions to respect the source for expr, i in list { - move_line_limit(p, expr.pos, 1); + //Don't move the first expression, it looks bad + if i != 0 { + move_line_limit(p, expr.pos, 1); + } visit_expr(p, expr); @@ -614,7 +617,11 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener newline_position(p, 1); } + set_source_position(p, v.body.pos); + visit_stmt(p, v.body, .If_Stmt); + + set_source_position(p, v.body.end); } if v.else_stmt != nil { @@ -1445,7 +1452,9 @@ visit_signature_list :: proc(p: ^Printer, list: ^ast.Field_List, remove_blank := for field, i in list.list { - move_line_limit(p, field.pos, 1); + if i != 0 { + move_line_limit(p, field.pos, 1); + } if .Using in field.flags { push_generic_token(p, .Using, 0);