From 57b80a0e9ef5830c2971f4b1ea9407a7b87472b7 Mon Sep 17 00:00:00 2001 From: mertcandav Date: Mon, 25 Mar 2024 15:04:49 +0300 Subject: [PATCH] julefmt: major improvements --- src/format.jule | 140 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 122 insertions(+), 18 deletions(-) diff --git a/src/format.jule b/src/format.jule index f7b65a1..e96ab71 100644 --- a/src/format.jule +++ b/src/format.jule @@ -45,21 +45,27 @@ impl Formatter { self.indent = self.indent[:self.indent.len - 4] } - fn write_comments_except(&self, row: int) { + fn write_comments_except(&self, row: int): int { + let mut lrow = row for { let mut c = self.cm.first(row) if c == nil || c.row == row { break } + if c.row - lrow > 1 { + self.write("\n") + } + lrow = c.row self.cm.drop_first() self.write(self.indent) self.write(c.txt) self.write("\n") } + ret lrow } - fn write_comments(&self, row: int) { - self.write_comments_except(row + 1) + fn write_comments(&self, row: int): int { + ret self.write_comments_except(row + 1) } fn format_expr(&self, mut &expr: &ast::Expr) { @@ -366,9 +372,14 @@ impl Formatter { self.add_indent() for (_, mut m) in d.methods { self.write("\n") - self.write_comments(m.token.row) + self.write_comments_except(m.token.row) self.write(self.indent) self.fn_decl(m) + let c = self.cm.pop(m.token.row) + if c != nil { + self.write(" ") + self.write(c.txt) + } self.write("\n") } self.done_indent() @@ -486,6 +497,11 @@ impl Formatter { const CAP = 1 << 4 let mut lines = make([]str, 0, CAP) + let all = i == -1 + if all { + i = 0 + } + let mut start = i let mut row = -1 let mut max = 0 @@ -494,7 +510,8 @@ impl Formatter { for i < nodes.len { let mut decl: T = nil match type Node { - | &ast::EnumItemDecl: + | &ast::EnumItemDecl + | &ast::VarDecl: decl = nodes[i] | ast::Node: let node = nodes[i] @@ -505,7 +522,7 @@ impl Formatter { break loop } } - if row != -1 && decl.token.row - 1 != row { + if !all && row != -1 && decl.token.row - 1 != row { break loop } row = decl.token.row @@ -552,19 +569,49 @@ impl Formatter { self.write(" {}") ret } - self.write(" {\n") + self.write(" {") self.add_indent() - for (_, mut s) in d.statics { - self.write_comments(s.token.row) - self.var_decl(s) - self.write("\n") - } - for (_, mut m) in d.methods { + let (mut si, mut mi, mut statics) = 0, 0, -1 + for { + let mut s: &ast::VarDecl = nil + let mut m: &ast::FnDecl = nil + if si < d.statics.len { + s = d.statics[si] + } + if mi < d.methods.len { + m = d.methods[mi] + } + if s == nil && m == nil { + break + } + if s != nil && (m == nil || s.token.row < m.token.row) { + if statics == -1 { + statics = si + } + si++ + continue + } self.write("\n") + if statics != -1 { + let mut vars = d.statics[statics:si] + let mut j = -1 + self.group_decls[&ast::VarDecl, &ast::VarDecl](vars, j) + statics = -1 + self.write("\n") + } self.write_comments(m.token.row) self.write(self.indent) self.fn_decl(m) self.write("\n") + mi++ + } + if statics != -1 { + if mi > 0 || self.buf[self.buf.len - 1] != '\n' { + self.write("\n") + } + let mut vars = d.statics[statics:si] + let mut j = -1 + self.group_decls[&ast::VarDecl, &ast::VarDecl](vars, j) } self.done_indent() self.write("}") @@ -573,12 +620,21 @@ impl Formatter { fn node(&self, mut &node: ast::Node) { match type node.data { | &ast::TypeAliasDecl: + if node.token.row - self.write_comments_except(node.token.row) > 1 { + self.write("\n") + } self.group_decls[&ast::TypeAliasDecl, ast::Node](self.f.nodes, self.i) + ret | &ast::VarDecl: + if node.token.row - self.write_comments_except(node.token.row) > 1 { + self.write("\n") + } self.group_decls[&ast::VarDecl, ast::Node](self.f.nodes, self.i) + ret + } + if node.token.row - self.write_comments(node.token.row) > 1 { + self.write("\n") } - - self.write_comments(node.token.row) match type node.data { | &ast::EnumDecl: self.enum_decl((&ast::EnumDecl)(node.data)) @@ -1197,21 +1253,57 @@ impl ExprFormatter { } fn responsive_exprs[T](self, mut &lit: T) { - self.fmt.add_indent() + const CAP = 1 << 8 + let mut exprs = make([]str, 0, CAP) + let n = self.fmt.buf.len + let mut max = 0 let mut row = lit.token.row let mut lined = false for (i, mut expr) in lit.exprs { if row != expr.token.row { lined = true - self.write("\n") - self.write(self.fmt.indent) + let diff = self.fmt.buf.len - n + if diff > 0 { + if max < diff { + max = diff + } + exprs = append(exprs, self.fmt.buf[n:]) + self.fmt.buf = self.fmt.buf[:n] + } } else if i > 0 { self.write(" ") } + row = expr.token.row self.format(expr) if lined || lit.exprs.len - i > 1 { self.write(",") } + } + if n != self.fmt.buf.len { + let diff = self.fmt.buf.len - n + if max < diff { + max = diff + } + exprs = append(exprs, self.fmt.buf[n:]) + self.fmt.buf = self.fmt.buf[:n] + } + + self.fmt.add_indent() + row = lit.token.row + let mut j = 0 + for _, expr in lit.exprs { + if row != expr.token.row { + self.write("\n") + self.fmt.write_comments_except(expr.token.row) + self.write(self.fmt.indent) + self.write(exprs[j]) + let c = self.fmt.cm.pop(expr.token.row) + if c != nil { + self.write(strings::repeat(" ", max - exprs[j].len + 1)) + self.write(c.txt) + } + j++ + } row = expr.token.row } self.fmt.done_indent() @@ -1220,6 +1312,8 @@ impl ExprFormatter { } else if lined { self.write("\n") self.write(self.fmt.indent) + } else if j < exprs.len { + self.write(exprs[j]) } } @@ -1227,6 +1321,11 @@ impl ExprFormatter { self.write("{") self.responsive_exprs[&ast::BraceLit](lit) self.write("}") + let c = self.fmt.cm.pop(lit.token.row) + if c != nil { + self.write(" ") + self.write(c.txt) + } } fn key_val_pair(self, mut pair: &ast::KeyValPair) { @@ -1239,6 +1338,11 @@ impl ExprFormatter { self.write("[") self.responsive_exprs[&ast::SliceExpr](s) self.write("]") + let c = self.fmt.cm.pop(s.token.row) + if c != nil { + self.write(" ") + self.write(c.txt) + } } fn indexing(self, mut i: &ast::IndexingExpr) {