mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-31 20:00:09 +00:00
work on switch alignment
This commit is contained in:
@@ -8,7 +8,7 @@ import "core:fmt"
|
|||||||
import "core:unicode/utf8"
|
import "core:unicode/utf8"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
Line_Type_Enum :: enum{Line_Comment, Value_Decl};
|
Line_Type_Enum :: enum{Line_Comment, Value_Decl, Switch_Stmt};
|
||||||
|
|
||||||
Line_Type :: bit_set[Line_Type_Enum];
|
Line_Type :: bit_set[Line_Type_Enum];
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@ Format_Token :: struct {
|
|||||||
kind: tokenizer.Token_Kind,
|
kind: tokenizer.Token_Kind,
|
||||||
text: string,
|
text: string,
|
||||||
spaces_before: int,
|
spaces_before: int,
|
||||||
|
parameter_count: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
Printer :: struct {
|
Printer :: struct {
|
||||||
@@ -58,6 +59,7 @@ Config :: struct {
|
|||||||
align_assignments: bool,
|
align_assignments: bool,
|
||||||
align_style: Alignment_Style,
|
align_style: Alignment_Style,
|
||||||
indent_cases: bool,
|
indent_cases: bool,
|
||||||
|
newline_style: Newline_Style,
|
||||||
}
|
}
|
||||||
|
|
||||||
Brace_Style :: enum {
|
Brace_Style :: enum {
|
||||||
@@ -73,6 +75,7 @@ Block_Type :: enum {
|
|||||||
Proc,
|
Proc,
|
||||||
Generic,
|
Generic,
|
||||||
Comp_Lit,
|
Comp_Lit,
|
||||||
|
Switch_Stmt,
|
||||||
}
|
}
|
||||||
|
|
||||||
Alignment_Style :: enum {
|
Alignment_Style :: enum {
|
||||||
@@ -80,6 +83,11 @@ Alignment_Style :: enum {
|
|||||||
Align_On_Type_And_Equals,
|
Align_On_Type_And_Equals,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Newline_Style :: enum {
|
||||||
|
CRLF,
|
||||||
|
LF,
|
||||||
|
}
|
||||||
|
|
||||||
default_style := Config {
|
default_style := Config {
|
||||||
spaces = 4,
|
spaces = 4,
|
||||||
newline_limit = 2,
|
newline_limit = 2,
|
||||||
@@ -126,16 +134,24 @@ print :: proc(p: ^Printer, file: ^ast.File) -> string {
|
|||||||
|
|
||||||
fix_lines(p);
|
fix_lines(p);
|
||||||
|
|
||||||
builder := strings.make_builder(p.allocator);
|
builder := strings.make_builder(0, mem.megabytes(5), p.allocator);
|
||||||
|
|
||||||
last_line := 0;
|
last_line := 0;
|
||||||
|
|
||||||
|
newline: string;
|
||||||
|
|
||||||
|
if p.config.newline_style == .LF {
|
||||||
|
newline = "\n";
|
||||||
|
} else {
|
||||||
|
newline = "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
for line, line_index in p.lines {
|
for line, line_index in p.lines {
|
||||||
diff_line := line_index - last_line;
|
diff_line := line_index - last_line;
|
||||||
|
|
||||||
for i := 0; i < diff_line; i += 1 {
|
for i := 0; i < diff_line; i += 1 {
|
||||||
strings.write_byte(&builder, '\n');
|
strings.write_string(&builder, newline);
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.config.tabs {
|
if p.config.tabs {
|
||||||
for i := 0; i < line.depth; i += 1 {
|
for i := 0; i < line.depth; i += 1 {
|
||||||
@@ -167,17 +183,118 @@ print :: proc(p: ^Printer, file: ^ast.File) -> string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fix_lines :: proc(p: ^Printer) {
|
fix_lines :: proc(p: ^Printer) {
|
||||||
align_comments(p);
|
|
||||||
align_var_decls(p);
|
align_var_decls(p);
|
||||||
align_blocks(p);
|
align_blocks(p);
|
||||||
|
align_comments(p); //align them last since they rely on the other alignments
|
||||||
}
|
}
|
||||||
|
|
||||||
align_var_decls :: proc(p: ^Printer) {
|
align_var_decls :: proc(p: ^Printer) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
align_switch_smt :: proc(p: ^Printer, index: int) {
|
||||||
|
|
||||||
|
switch_found := false;
|
||||||
|
brace_token: Format_Token;
|
||||||
|
brace_line: int;
|
||||||
|
|
||||||
|
found_switch_brace: for line, line_index in p.lines[index:] {
|
||||||
|
|
||||||
|
for format_token in line.format_tokens {
|
||||||
|
|
||||||
|
if format_token.kind == .Open_Brace && switch_found {
|
||||||
|
brace_token = format_token;
|
||||||
|
brace_line = line_index;
|
||||||
|
break found_switch_brace;
|
||||||
|
} else if format_token.kind == .Open_Brace {
|
||||||
|
break;
|
||||||
|
} else if format_token.kind == .Switch {
|
||||||
|
switch_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if !switch_found {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
largest := 0;
|
||||||
|
|
||||||
|
//find all the switch cases that are one lined
|
||||||
|
for line, line_index in p.lines[brace_line+1:] {
|
||||||
|
|
||||||
|
case_found := false;
|
||||||
|
colon_found := false;
|
||||||
|
length := 0;
|
||||||
|
|
||||||
|
for format_token in line.format_tokens {
|
||||||
|
|
||||||
|
if format_token.kind == .Comment {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this will only happen if the case is one lined
|
||||||
|
if case_found && colon_found {
|
||||||
|
largest = max(length, largest);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if format_token.kind == .Case {
|
||||||
|
case_found = true;
|
||||||
|
} else if format_token.kind == .Colon {
|
||||||
|
colon_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
length += len(format_token.text) + format_token.spaces_before;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for line, line_index in p.lines[brace_line+1:] {
|
||||||
|
|
||||||
|
case_found := false;
|
||||||
|
colon_found := false;
|
||||||
|
length := 0;
|
||||||
|
|
||||||
|
for format_token, i in line.format_tokens {
|
||||||
|
|
||||||
|
if format_token.kind == .Comment {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this will only happen if the case is one lined
|
||||||
|
if case_found && colon_found {
|
||||||
|
line.format_tokens[i].spaces_before += (largest - length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if format_token.kind == .Case {
|
||||||
|
case_found = true;
|
||||||
|
} else if format_token.kind == .Colon {
|
||||||
|
colon_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
length += len(format_token.text) + format_token.spaces_before;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
align_blocks :: proc(p: ^Printer) {
|
align_blocks :: proc(p: ^Printer) {
|
||||||
|
|
||||||
|
for line, line_index in p.lines {
|
||||||
|
|
||||||
|
if len(line.format_tokens) <= 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if .Switch_Stmt in line.types {
|
||||||
|
align_switch_smt(p, line_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
align_comments :: proc(p: ^Printer) {
|
align_comments :: proc(p: ^Printer) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import "core:unicode/utf8"
|
|||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:sort"
|
import "core:sort"
|
||||||
|
|
||||||
|
//right the attribute order is not linearly parsed(bug?)
|
||||||
@(private)
|
@(private)
|
||||||
sort_attribute :: proc(s: ^[dynamic]^ast.Attribute) -> sort.Interface {
|
sort_attribute :: proc(s: ^[dynamic]^ast.Attribute) -> sort.Interface {
|
||||||
return sort.Interface {
|
return sort.Interface {
|
||||||
@@ -209,8 +210,11 @@ append_format_token :: proc(p: ^Printer, format_token: Format_Token) -> ^Format_
|
|||||||
push_comments(p, p.source_position);
|
push_comments(p, p.source_position);
|
||||||
|
|
||||||
unwrapped_line := p.current_line;
|
unwrapped_line := p.current_line;
|
||||||
unwrapped_line.used = true;
|
|
||||||
unwrapped_line.depth = p.depth;
|
if !unwrapped_line.used {
|
||||||
|
unwrapped_line.used = true;
|
||||||
|
unwrapped_line.depth = p.depth;
|
||||||
|
}
|
||||||
|
|
||||||
if len(unwrapped_line.format_tokens) == 0 && format_token.spaces_before == 1 {
|
if len(unwrapped_line.format_tokens) == 0 && format_token.spaces_before == 1 {
|
||||||
format_token.spaces_before = 0;
|
format_token.spaces_before = 0;
|
||||||
@@ -223,6 +227,11 @@ append_format_token :: proc(p: ^Printer, format_token: Format_Token) -> ^Format_
|
|||||||
return &unwrapped_line.format_tokens[len(unwrapped_line.format_tokens)-1];
|
return &unwrapped_line.format_tokens[len(unwrapped_line.format_tokens)-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
push_format_token :: proc(p: ^Printer, format_token: Format_Token) {
|
||||||
|
p.last_token = append_format_token(p, format_token);
|
||||||
|
}
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
push_generic_token :: proc(p: ^Printer, kind: tokenizer.Token_Kind, spaces_before: int, value := "") {
|
push_generic_token :: proc(p: ^Printer, kind: tokenizer.Token_Kind, spaces_before: int, value := "") {
|
||||||
|
|
||||||
@@ -541,7 +550,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
|
|||||||
if v.pos.line == v.end.line && len(v.stmts) > 1 && p.config.split_multiple_stmts {
|
if v.pos.line == v.end.line && len(v.stmts) > 1 && p.config.split_multiple_stmts {
|
||||||
|
|
||||||
if !empty_block {
|
if !empty_block {
|
||||||
visit_begin_brace(p, v.pos, block_type);
|
visit_begin_brace(p, v.pos, block_type, len(v.stmts));
|
||||||
}
|
}
|
||||||
|
|
||||||
set_source_position(p, v.pos);
|
set_source_position(p, v.pos);
|
||||||
@@ -569,7 +578,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !empty_block {
|
if !empty_block {
|
||||||
visit_begin_brace(p, v.pos, block_type);
|
visit_begin_brace(p, v.pos, block_type, len(v.stmts));
|
||||||
}
|
}
|
||||||
|
|
||||||
set_source_position(p, v.pos);
|
set_source_position(p, v.pos);
|
||||||
@@ -644,6 +653,8 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
|
|||||||
|
|
||||||
push_generic_token(p, .Switch, 1);
|
push_generic_token(p, .Switch, 1);
|
||||||
|
|
||||||
|
hint_current_line(p, {.Switch_Stmt});
|
||||||
|
|
||||||
if v.init != nil {
|
if v.init != nil {
|
||||||
p.skip_semicolon = true;
|
p.skip_semicolon = true;
|
||||||
visit_stmt(p, v.init);
|
visit_stmt(p, v.init);
|
||||||
@@ -1201,7 +1212,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
visit_begin_brace :: proc(p: ^Printer, begin: tokenizer.Pos, type: Block_Type) {
|
visit_begin_brace :: proc(p: ^Printer, begin: tokenizer.Pos, type: Block_Type, count := 0) {
|
||||||
|
|
||||||
set_source_position(p, begin);
|
set_source_position(p, begin);
|
||||||
|
|
||||||
@@ -1209,12 +1220,19 @@ visit_begin_brace :: proc(p: ^Printer, begin: tokenizer.Pos, type: Block_Type) {
|
|||||||
newline_braced |= p.config.brace_style == .K_And_R && type == .Proc;
|
newline_braced |= p.config.brace_style == .K_And_R && type == .Proc;
|
||||||
newline_braced &= p.config.brace_style != ._1TBS;
|
newline_braced &= p.config.brace_style != ._1TBS;
|
||||||
|
|
||||||
|
format_token := Format_Token {
|
||||||
|
kind = .Open_Brace,
|
||||||
|
parameter_count = count,
|
||||||
|
text = "{",
|
||||||
|
};
|
||||||
|
|
||||||
if newline_braced {
|
if newline_braced {
|
||||||
newline_position(p, 1);
|
newline_position(p, 1);
|
||||||
push_generic_token(p, .Open_Brace, 0);
|
push_format_token(p, format_token);
|
||||||
indent(p);
|
indent(p);
|
||||||
} else {
|
} else {
|
||||||
push_generic_token(p, .Open_Brace, 1);
|
format_token.spaces_before = 1;
|
||||||
|
push_format_token(p, format_token);
|
||||||
indent(p);
|
indent(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user