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()
|
||||
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