Răsfoiți Sursa

now aligning comments

Daniel Gavin 4 ani în urmă
părinte
comite
b09e53d7fe
2 a modificat fișierele cu 125 adăugiri și 22 ștergeri
  1. 105 13
      core/odin/printer/printer.odin
  2. 20 9
      core/odin/printer/visit.odin

+ 105 - 13
core/odin/printer/printer.odin

@@ -8,11 +8,16 @@ import "core:fmt"
 import "core:unicode/utf8"
 import "core:mem"
 
+Line_Type_Enum :: enum{Line_Comment, Value_Decl};
+
+Line_Type :: bit_set[Line_Type_Enum];
+
 Line :: struct {
     format_tokens: [dynamic] Format_Token,
     finalized: bool,
     used: bool,
 	depth: int,
+	types: Line_Type,
 }
 
 Format_Token :: struct {
@@ -31,7 +36,7 @@ Printer :: struct {
 	file:                 ^ast.File,
     source_position:      tokenizer.Pos,
 	last_source_position: tokenizer.Pos,
-    lines:                map [int]^Line,
+    lines:                [dynamic] Line, //need to look into a better data structure, one that can handle inserting lines rather than appending
     skip_semicolon:       bool,
 	current_line:         ^Line,
 	current_line_index:   int,
@@ -80,7 +85,7 @@ default_style := Config {
 	newline_limit = 2,
 	convert_do = false,
 	semicolons = true,
-	tabs = true,
+	tabs = false,
 	brace_style = ._1TBS,
 	split_multiple_stmts = true,
 	align_assignments = true,
@@ -99,6 +104,15 @@ make_printer :: proc(config: Config, allocator := context.allocator) -> Printer
 print :: proc(p: ^Printer, file: ^ast.File) -> string {
 
 	p.comments = file.comments;
+	
+	if len(file.decls) > 0 {
+		p.lines = make([dynamic] Line, 0, (file.decls[len(file.decls)-1].end.line - file.decls[0].pos.line) * 2, context.temp_allocator);
+	}
+
+	set_line(p, 0);
+
+	push_generic_token(p, .Package, 0);
+	push_ident_token(p, file.pkg_name, 1);
 
     for decl in file.decls {
         visit_decl(p, cast(^ast.Decl)decl);
@@ -110,22 +124,28 @@ print :: proc(p: ^Printer, file: ^ast.File) -> string {
 
     last_line := 0;
 
-    for key, value in p.lines {
-        diff_line := key - last_line;
-        
+    for line, line_index in p.lines {
+        diff_line := line_index - last_line;
+
         for i := 0; i < diff_line; i += 1 {
             strings.write_byte(&builder, '\n');
         }
 
-		for i := 0; i < value.depth * 4; i += 1 {
-			strings.write_byte(&builder, ' ');
+		if p.config.tabs {
+			for i := 0; i < line.depth; i += 1 {
+				strings.write_byte(&builder, '\t');
+			}
+		} else {
+			for i := 0; i < line.depth * p.config.spaces; i += 1 {
+				strings.write_byte(&builder, ' ');
+			}
 		}
 
 		if p.debug {
-			strings.write_string(&builder, fmt.tprintf("line %v: ", key));
+			strings.write_string(&builder, fmt.tprintf("line %v: ", line_index));
 		}
 
-		for format_token in value.format_tokens {
+		for format_token in line.format_tokens {
 
 			for i := 0; i < format_token.spaces_before; i += 1 {
 				strings.write_byte(&builder, ' ');
@@ -134,23 +154,95 @@ print :: proc(p: ^Printer, file: ^ast.File) -> string {
 			strings.write_string(&builder, format_token.text);
 		}
     
-		last_line = key;
+		last_line = line_index;
     }
 
     return strings.to_string(builder);
 }
 
 fix_lines :: proc(p: ^Printer) {
+	align_comments(p);
+	align_var_decls(p);
+}
 
-	for key, value in p.lines {
+align_var_decls :: proc(p: ^Printer) {
 
-		if len(value.format_tokens) <= 0 {
+}
+
+align_comments :: proc(p: ^Printer) {
+	
+	Comment_Align_Info :: struct {
+		length: int,
+		begin: int,
+		end: int,
+	};
+
+	comment_infos := make([dynamic]Comment_Align_Info, 0, context.temp_allocator);
+
+	current_info: Comment_Align_Info;
+
+	for line, line_index in p.lines {
+
+		if len(line.format_tokens) <= 0 {
 			continue;
 		}
 
+		if .Line_Comment in line.types {
+
+			if current_info.end + 1 != line_index {
+
+				if (current_info.begin != 0 && current_info.end != 0) || current_info.length > 0 {
+					append(&comment_infos, current_info);
+				}
+
+				current_info.begin = line_index;
+				current_info.end = line_index;
+				current_info.length = 0;
+			}
 
+			length := 0;
+
+			for format_token, i in line.format_tokens {
+
+				if format_token.kind == .Comment {
+					current_info.length = max(current_info.length, length);
+					current_info.end = line_index;
+				}
+
+				length += format_token.spaces_before + len(format_token.text);
+			}
+
+		}
 
 	}
 
+	if (current_info.begin != 0 && current_info.end != 0) || current_info.length > 0 {
+		append(&comment_infos, current_info);
+	}
 
-}
+	for info in comment_infos {
+
+		for i := info.begin; i <= info.end; i += 1 {
+
+			l := p.lines[i];
+
+			length := 0;
+
+			for format_token, i in l.format_tokens {
+
+				if format_token.kind == .Comment {
+					if len(l.format_tokens) == 1 {
+						l.format_tokens[i].spaces_before += info.length + 1;
+					} else {
+						l.format_tokens[i].spaces_before += info.length - length;
+					}			
+				}
+
+				length += format_token.spaces_before + len(format_token.text);
+			}
+
+		}
+
+	}
+
+}

+ 20 - 9
core/odin/printer/visit.odin

@@ -27,7 +27,7 @@ next_comment_group :: proc(p: ^Printer) {
 }
  
 @(private) 
-write_comment :: proc(p: ^Printer, comment: tokenizer.Token) -> int {
+push_comment :: proc(p: ^Printer, comment: tokenizer.Token) -> int {
 
 	if len(comment.text) == 0 {
 		return 0;
@@ -50,6 +50,8 @@ write_comment :: proc(p: ^Printer, comment: tokenizer.Token) -> int {
 		append(&p.current_line.format_tokens, format_token); 
 		p.last_token = &p.current_line.format_tokens[len(p.current_line.format_tokens)-1];
 
+		hint_current_line(p, {.Line_Comment});
+
 		return 0;
 	} else {
 
@@ -132,7 +134,7 @@ write_comment :: proc(p: ^Printer, comment: tokenizer.Token) -> int {
 }
 
 @(private)
-write_comments :: proc(p: ^Printer, pos: tokenizer.Pos, format_token: Format_Token) {
+push_comments :: proc(p: ^Printer, pos: tokenizer.Pos, format_token: Format_Token) {
 
 	prev_comment: ^tokenizer.Token;
 	prev_comment_lines: int;
@@ -152,7 +154,7 @@ write_comments :: proc(p: ^Printer, pos: tokenizer.Pos, format_token: Format_Tok
 			 	newline_position(p, min(p.config.newline_limit, comment.pos.line - prev_comment.pos.line - prev_comment_lines));
 			}
 
-			prev_comment_lines = write_comment(p, comment);
+			prev_comment_lines = push_comment(p, comment);
 			prev_comment = &comment_group.list[i];
 		}
 
@@ -181,7 +183,7 @@ append_format_token :: proc(p: ^Printer, format_token: Format_Token) -> ^Format_
 		p.space_next_token = false;
 	}
 
-	write_comments(p, p.source_position, format_token);
+	push_comments(p, p.source_position, format_token);
 
 	unwrapped_line := p.current_line;
     unwrapped_line.used = true;
@@ -262,12 +264,15 @@ set_line :: proc(p: ^Printer, line: int) -> ^Line {
 
 	unwrapped_line: ^Line;
 
-	if line not_in p.lines {
-        unwrapped_line = new(Line, p.allocator);
-        unwrapped_line.format_tokens = make([dynamic] Format_Token, 0, 50, p.allocator);
-		p.lines[line] = unwrapped_line;
+	if line >= len(p.lines) {
+		for i := len(p.lines); i <= line; i += 1 {
+			new_line: Line;
+			new_line.format_tokens = make([dynamic] Format_Token, 0, 50, p.allocator);
+			append(&p.lines, new_line);
+		}
+		unwrapped_line = &p.lines[line];
     } else {
-        unwrapped_line = p.lines[line];
+        unwrapped_line = &p.lines[line];
     }
 
 	p.current_line = unwrapped_line;
@@ -297,10 +302,16 @@ merge_next_token :: proc(p: ^Printer) {
 	p.merge_next_token = true;
 }
 
+@(private)
 space_next_token :: proc(p: ^Printer) {
 	p.space_next_token = true;
 }
 
+@(private)
+hint_current_line :: proc(p: ^Printer, hint: Line_Type) {
+	p.current_line.types |= hint;
+}
+
 @(private)
 visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) {