fmt: keep newlines between toplevel stmts (#8383)
							parent
							
								
									afddcda7a3
								
							
						
					
					
						commit
						e47c13903b
					
				|  | @ -61,14 +61,10 @@ pub fn fmt(file ast.File, table &table.Table, is_debug bool) string { | |||
| 	} | ||||
| 	f.process_file_imports(file) | ||||
| 	f.set_current_module_name('main') | ||||
| 	for stmt in file.stmts { | ||||
| 		if stmt is ast.Import { | ||||
| 			// Just remember the position of the imports for now
 | ||||
| 			f.import_pos = f.out.len | ||||
| 			// f.imports(f.file.imports)
 | ||||
| 		} | ||||
| 		f.stmt(stmt) | ||||
| 	} | ||||
| 	// As these are toplevel stmts, the indent increase done in f.stmts() has to be compensated
 | ||||
| 	f.indent-- | ||||
| 	f.stmts(file.stmts) | ||||
| 	f.indent++ | ||||
| 	// for comment in file.comments { println('$comment.line_nr $comment.text')	}
 | ||||
| 	f.imports(f.file.imports) // now that we have all autoimports, handle them
 | ||||
| 	res := f.out.str().trim_space() + '\n' | ||||
|  | @ -271,20 +267,39 @@ pub fn (f Fmt) imp_stmt_str(imp ast.Import) string { | |||
| 	return '$imp.mod$imp_alias_suffix' | ||||
| } | ||||
| 
 | ||||
| pub fn (mut f Fmt) stmts(stmts []ast.Stmt) { | ||||
| 	f.indent++ | ||||
| 	mut prev_line_nr := 0 | ||||
| 	if stmts.len >= 1 { | ||||
| 		prev_pos := stmts[0].position() | ||||
| 		prev_line_nr = util.imax(prev_pos.line_nr, prev_pos.last_line) | ||||
| fn (mut f Fmt) should_insert_newline_before_stmt(stmt ast.Stmt, prev_stmt ast.Stmt) bool { | ||||
| 	prev_line_nr := prev_stmt.position().last_line | ||||
| 	// The stmt either has or shouldn't have a newline before
 | ||||
| 	if stmt.position().line_nr - prev_line_nr <= 1 || f.out.last_n(2) == '\n\n' { | ||||
| 		return false | ||||
| 	} | ||||
| 	// Imports are handled special hence they are ignored here
 | ||||
| 	if stmt is ast.Import || prev_stmt is ast.Import { | ||||
| 		return false | ||||
| 	} | ||||
| 	// Attributes are not respected in the stmts position, so we have to check it manually
 | ||||
| 	if stmt is ast.StructDecl { | ||||
| 		if stmt.attrs.len > 0 && stmt.attrs[0].pos.line_nr - prev_line_nr <= 1 { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	if stmt is ast.FnDecl { | ||||
| 		if stmt.attrs.len > 0 && stmt.attrs[0].pos.line_nr - prev_line_nr <= 1 { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| pub fn (mut f Fmt) stmts(stmts []ast.Stmt) { | ||||
| 	mut prev_stmt := if stmts.len > 0 { stmts[0] } else { ast.Stmt{} } | ||||
| 	f.indent++ | ||||
| 	for stmt in stmts { | ||||
| 		if stmt.position().line_nr - prev_line_nr > 1 { | ||||
| 		if f.should_insert_newline_before_stmt(stmt, prev_stmt) { | ||||
| 			f.out.writeln('') | ||||
| 		} | ||||
| 		f.stmt(stmt) | ||||
| 		prev_pos := stmt.position() | ||||
| 		prev_line_nr = util.imax(prev_pos.line_nr, prev_pos.last_line) | ||||
| 		prev_stmt = stmt | ||||
| 	} | ||||
| 	f.indent-- | ||||
| } | ||||
|  | @ -362,6 +377,8 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) { | |||
| 		} | ||||
| 		ast.Import { | ||||
| 			// Imports are handled after the file is formatted, to automatically add necessary modules
 | ||||
| 			// Just remember the position of the imports for now
 | ||||
| 			f.import_pos = f.out.len | ||||
| 			// f.imports(f.file.imports)
 | ||||
| 		} | ||||
| 		ast.InterfaceDecl { | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import semver | ||||
| 
 | ||||
| // as semver
 | ||||
| 
 | ||||
| fn main() { | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,8 @@ | |||
| // comment above HashStmts
 | ||||
| #flag linux -lsdl2 | ||||
| #include "stdio.h" | ||||
| 
 | ||||
| // comment between with newlines around
 | ||||
| 
 | ||||
| #include "header.h" | ||||
| #include "sqlite3.h" | ||||
|  | @ -0,0 +1,5 @@ | |||
| // import time This should be commented out
 | ||||
| import os | ||||
| import rand | ||||
| 
 | ||||
| // another comment after imports
 | ||||
|  | @ -0,0 +1,19 @@ | |||
| // Module with attribute
 | ||||
| [manualfree] | ||||
| module websocket | ||||
| 
 | ||||
| fn main() {} | ||||
| 
 | ||||
| // This should stay between both functions
 | ||||
| 
 | ||||
| fn x() {} | ||||
| 
 | ||||
| // doc comment above an attributed function
 | ||||
| [inline] | ||||
| fn y_with_attr() { | ||||
| } | ||||
| 
 | ||||
| // doc comment above an attributed struct
 | ||||
| [typedef] | ||||
| struct Foo { | ||||
| } | ||||
|  | @ -13,6 +13,7 @@ type MyInt = int | |||
| pub type Abc = f32 | ||||
| 
 | ||||
| // Fn type decl
 | ||||
| 
 | ||||
| type EmptyFn = fn () | ||||
| 
 | ||||
| type OneArgFn = fn (i int) | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ const ( | |||
| 
 | ||||
| // // #include, #flag, #v
 | ||||
| fn (mut p Parser) hash() ast.HashStmt { | ||||
| 	mut pos := p.prev_tok.position() | ||||
| 	pos := p.tok.position() | ||||
| 	val := p.tok.lit | ||||
| 	kind := val.all_before(' ') | ||||
| 	p.next() | ||||
|  |  | |||
|  | @ -15,12 +15,11 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr { | |||
| 		p.inside_ct_if_expr = was_inside_ct_if_expr | ||||
| 	} | ||||
| 	p.inside_if_expr = true | ||||
| 	mut pos := if is_comptime { | ||||
| 	mut pos := p.tok.position() | ||||
| 	if is_comptime { | ||||
| 		p.inside_ct_if_expr = true | ||||
| 		p.next() // `$`
 | ||||
| 		p.prev_tok.position().extend(p.tok.position()) | ||||
| 	} else { | ||||
| 		p.tok.position() | ||||
| 		pos = p.prev_tok.position().extend(p.tok.position()) | ||||
| 	} | ||||
| 	mut branches := []ast.IfBranch{} | ||||
| 	mut has_else := false | ||||
|  |  | |||
|  | @ -204,7 +204,11 @@ pub fn (mut p Parser) parse() ast.File { | |||
| 	} | ||||
| 	// module
 | ||||
| 	module_decl := p.module_decl() | ||||
| 	stmts << module_decl | ||||
| 	if module_decl.is_skipped { | ||||
| 		stmts.insert(0, ast.Stmt(module_decl)) | ||||
| 	} else { | ||||
| 		stmts << module_decl | ||||
| 	} | ||||
| 	// imports
 | ||||
| 	for { | ||||
| 		if p.tok.kind == .key_import { | ||||
|  | @ -513,8 +517,10 @@ pub fn (mut p Parser) top_stmt() ast.Stmt { | |||
| 				return p.struct_decl() | ||||
| 			} | ||||
| 			.dollar { | ||||
| 				if_expr := p.if_expr(true) | ||||
| 				return ast.ExprStmt{ | ||||
| 					expr: p.if_expr(true) | ||||
| 					expr: if_expr | ||||
| 					pos: if_expr.pos | ||||
| 				} | ||||
| 			} | ||||
| 			.hash { | ||||
|  | @ -1753,6 +1759,7 @@ fn (mut p Parser) parse_number_literal() ast.Expr { | |||
| 
 | ||||
| fn (mut p Parser) module_decl() ast.Module { | ||||
| 	mut module_attrs := []table.Attr{} | ||||
| 	mut attrs_pos := p.tok.position() | ||||
| 	if p.tok.kind == .lsbr { | ||||
| 		p.attributes() | ||||
| 		module_attrs = p.attrs | ||||
|  | @ -1788,7 +1795,7 @@ fn (mut p Parser) module_decl() ast.Module { | |||
| 				return mod_node | ||||
| 			} | ||||
| 		} | ||||
| 		module_pos = module_pos.extend(name_pos) | ||||
| 		module_pos = attrs_pos.extend(name_pos) | ||||
| 	} | ||||
| 	full_name := util.qualify_module(name, p.file_name) | ||||
| 	p.mod = full_name | ||||
|  |  | |||
|  | @ -154,10 +154,11 @@ pub fn (mut s Scanner) set_current_tidx(cidx int) { | |||
| fn (mut s Scanner) new_token(tok_kind token.Kind, lit string, len int) token.Token { | ||||
| 	cidx := s.tidx | ||||
| 	s.tidx++ | ||||
| 	line_offset := if tok_kind == .hash { 0 } else { 1 } | ||||
| 	return token.Token{ | ||||
| 		kind: tok_kind | ||||
| 		lit: lit | ||||
| 		line_nr: s.line_nr + 1 | ||||
| 		line_nr: s.line_nr + line_offset | ||||
| 		pos: s.pos - len + 1 | ||||
| 		len: len | ||||
| 		tidx: cidx | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue