From 87a18338628fc42ba49c24d095b37e351e779ede Mon Sep 17 00:00:00 2001 From: Daniel Gavin Date: Sat, 1 May 2021 21:26:40 +0200 Subject: [PATCH] fix weird behavior of nesting proc types in structs --- core/odin/printer/printer.odin | 56 ++++++++++++++++++++++++++-------- core/odin/printer/visit.odin | 19 ++++++++++-- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/core/odin/printer/printer.odin b/core/odin/printer/printer.odin index 407e5a415..bef1235e9 100644 --- a/core/odin/printer/printer.odin +++ b/core/odin/printer/printer.odin @@ -8,7 +8,7 @@ import "core:fmt" import "core:unicode/utf8" import "core:mem" -Type_Enum :: enum {Line_Comment, Value_Decl, Switch_Stmt, Struct, Assign, Call, Enum, If, For} +Type_Enum :: enum {Line_Comment, Value_Decl, Switch_Stmt, Struct, Assign, Call, Enum, If, For, Proc_Lit} Line_Type :: bit_set[Type_Enum]; @@ -68,6 +68,7 @@ Config :: struct { align_structs: bool, align_style: Alignment_Style, align_enums: bool, + align_length_break: int, indent_cases: bool, newline_style: Newline_Style, } @@ -113,6 +114,7 @@ default_style := Config { align_structs = true, align_enums = true, newline_style = .CRLF, + align_length_break = 9, }; make_printer :: proc(config: Config, allocator := context.allocator) -> Printer { @@ -383,11 +385,9 @@ format_keyword_to_brace :: proc(p: ^Printer, line_index: int, format_index: int, if format_token.kind == .Comment { break; - } - - if format_token.kind == .Undef || format_token.kind == .Comma { + } else if format_token.kind == .Undef { return; - } + } if line_index == 0 && i <= format_index { continue; @@ -416,6 +416,8 @@ format_keyword_to_brace :: proc(p: ^Printer, line_index: int, format_index: int, format_generic :: proc(p: ^Printer) { + next_struct_line := 0; + for line, line_index in p.lines { if len(line.format_tokens) <= 0 { @@ -423,10 +425,9 @@ format_generic :: proc(p: ^Printer) { } for format_token, token_index in line.format_tokens { - if format_token.kind == .For || format_token.kind == .If || format_token.kind == .When || format_token.kind == .Switch || - format_token.kind == .Proc { + (format_token.kind == .Proc && format_token.type == .Proc_Lit) { format_keyword_to_brace(p, line_index, token_index, format_token.kind); } else if format_token.type == .Call { format_call(p, line_index, token_index); @@ -441,8 +442,8 @@ format_generic :: proc(p: ^Printer) { align_enum(p, line_index); } - if .Struct in line.types && p.config.align_structs { - align_struct(p, line_index); + if .Struct in line.types && p.config.align_structs && next_struct_line <= 0 { + next_struct_line = align_struct(p, line_index); } if .Value_Decl in line.types { @@ -452,6 +453,8 @@ format_generic :: proc(p: ^Printer) { if .Assign in line.types { format_assignment(p, line_index); } + + next_struct_line -= 1; } } @@ -743,7 +746,7 @@ align_enum :: proc(p: ^Printer, index: int) { } -align_struct :: proc(p: ^Printer, index: int) { +align_struct :: proc(p: ^Printer, index: int) -> int { struct_found := false; brace_token: Format_Token; brace_line: int; @@ -763,11 +766,12 @@ align_struct :: proc(p: ^Printer, index: int) { } if !struct_found { - return; + return 0; } largest := 0; colon_count := 0; + nested := false; seen_brace := false; TokenAndLength :: struct { @@ -778,15 +782,21 @@ align_struct :: proc(p: ^Printer, index: int) { format_tokens := make([]TokenAndLength, brace_token.parameter_count, context.temp_allocator); if brace_token.parameter_count == 0 { - return; + return 0; } + end_line_index := 0; + for line, line_index in p.lines[brace_line + 1:] { length := 0; for format_token, i in line.format_tokens { + + //give up on nested structs if format_token.kind == .Comment { break; + } else if format_token.kind == .Open_Paren { + break; } else if format_token.kind == .Open_Brace { seen_brace = true; } else if format_token.kind == .Close_Brace { @@ -797,23 +807,43 @@ align_struct :: proc(p: ^Printer, index: int) { if format_token.kind == .Colon { format_tokens[colon_count] = {format_token = &line.format_tokens[i + 1], length = length}; + + if format_tokens[colon_count].format_token.kind == .Struct { + nested = true; + } + colon_count += 1; largest = max(length, largest); - break; } length += len(format_token.text) + format_token.spaces_before; } + if nested { + end_line_index = line_index + brace_line + 1; + } + if colon_count >= brace_token.parameter_count { break; } + } + + //give up aligning nested, it never looks good + if nested { + for line, line_index in p.lines[end_line_index:] { + for format_token in line.format_tokens { + if format_token.kind == .Close_Brace { + return end_line_index + line_index - index; + } + } + } } for token in format_tokens { token.format_token.spaces_before = largest - token.length + 1; } + return 0; } align_comments :: proc(p: ^Printer) { diff --git a/core/odin/printer/visit.odin b/core/odin/printer/visit.odin index a8f7068c8..c2bd8eaf8 100644 --- a/core/odin/printer/visit.odin +++ b/core/odin/printer/visit.odin @@ -1095,7 +1095,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr) { push_ident_token(p, "#force_inline", 0); } - visit_proc_type(p, v.type^); + visit_proc_type(p, v.type^, true); if v.where_clauses != nil { move_line(p, v.where_clauses[0].pos); @@ -1324,9 +1324,22 @@ visit_field_list :: proc(p: ^Printer, list: ^ast.Field_List, add_comma := false, } } -visit_proc_type :: proc(p: ^Printer, proc_type: ast.Proc_Type) { +visit_proc_type :: proc(p: ^Printer, proc_type: ast.Proc_Type, is_proc_lit := false) { - push_generic_token(p, .Proc, 1); + if is_proc_lit { + push_format_token(p, Format_Token { + kind = .Proc, + type = .Proc_Lit, + text = "proc", + spaces_before = 1, + }); + } else { + push_format_token(p, Format_Token { + kind = .Proc, + text = "proc", + spaces_before = 1, + }); + } explicit_calling := false;