diff --git a/src/format.jule b/src/format.jule index 09f033c..8248f3c 100644 --- a/src/format.jule +++ b/src/format.jule @@ -14,6 +14,7 @@ use strings for std::strings struct Field { f: &ast::FieldDecl token: Token + expr: str } struct Formatter { @@ -103,6 +104,17 @@ impl Formatter { ret self.write_comments_except(row + 1) } + fn pop_row_comments(&self, row: int) { + for { + let c = self.cm.pop(row) + if c == nil { + break + } + self.write(" ") + self.write_comment(c) + } + } + fn format_expr(&self, mut &expr: &ast::Expr) { self.ef.format(expr) } @@ -312,26 +324,26 @@ impl Formatter { // Only parses last field. // Leading fields used to calculate maximum declaration length of group for padding. - fn field(&self, mut f: &ast::FieldDecl, mut max: int) { + fn field(&self, mut f: &Field, mut max: int) { self.write(self.indent) - if f.public { + if f.f.public { self.write("pub ") max -= 4 } - if f.mutable { + if f.f.mutable { self.write("mut ") max -= 4 } - self.write(f.ident) - max -= f.ident.len + self.write(f.f.ident) + max -= f.f.ident.len self.write(": ") if max > 0 { self.write(strings::repeat(" ", max)) } - self.format_type(f.kind) - if f.default != nil { + self.format_type(f.f.kind) + if f.expr != "" { self.write(" = ") - self.format_expr(f.default) + self.write(f.expr) } } @@ -401,11 +413,7 @@ impl Formatter { 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_comment(c) - } + self.pop_row_comments(m.token.row) self.write("\n") } self.done_indent() @@ -464,19 +472,21 @@ impl Formatter { } fn field_group_decls(&self, mut fields: []&Field, mut &i: int) { + const CAP = 1 << 4 + let mut lines = make([]str, 0, CAP) + let mut rows = make([]int, 0, CAP) + let mut start = i - let mut row = -1 + self.ef.row = -1 let mut max = 0 let mut field_max = 0 let n = self.buf.len - _ = n, start, max - loop: for i < fields.len { let mut decl = fields[i] - if row != -1 && decl.token.row - 1 != row { - break loop + if self.ef.row != -1 && decl.token.row - 1 != self.ef.row { + break } - row = decl.token.row + self.ef.row = decl.token.row let mut fm = 0 if decl.f.public { fm += "pub ".len @@ -489,29 +499,34 @@ impl Formatter { field_max = fm } i++ + if decl.f.default != nil { + self.format_expr(decl.f.default) + decl.expr = self.buf[n:] + self.buf = self.buf[:n] + } + rows = append(rows, self.ef.row) } - const CAP = 1 << 4 - let mut lines = make([]str, 0, CAP) let mut j = start for j < i; j++ { - self.field(fields[j].f, field_max) + let mut f = fields[j] + self.field(f, field_max) lines = append(lines, self.buf[n:]) let diff = self.buf.len - n - if max < diff { + if max < diff && f.f.token.row == rows[j - start] { max = diff } self.buf = self.buf[:self.buf.len - diff] } - for _, line in lines { - row = fields[start].token.row + for k, line in lines { + let row = rows[k] self.write_comments_except(row) self.write(line) let c = self.cm.first(row) if c != nil && c.row == row { self.cm.drop_first() - self.write(strings::repeat(" ", max - line.len + 1)) + self.write(strings::repeat(" ", padding_abs(max - line.len) + 1)) self.write_comment(c) } self.write("\n") @@ -522,14 +537,20 @@ impl Formatter { fn group_decls[T, Node](&self, mut nodes: []Node, mut &i: int) { const CAP = 1 << 4 let mut lines = make([]str, 0, CAP) + let mut rows = make([]int, 0, CAP) let all = i == -1 if all { i = 0 } - let mut start = i - let mut row = -1 + self.ef.ignore_comments = true + let ignore_comments = self.ef.ignore_comments + defer { + self.ef.ignore_comments = ignore_comments + } + + self.ef.row = -1 let mut max = 0 let n = self.buf.len loop: @@ -548,10 +569,11 @@ impl Formatter { break loop } } - if !all && row != -1 && decl.token.row - 1 != row { + if !all && self.ef.row != -1 && decl.token.row - 1 != self.ef.row { break loop } - row = decl.token.row + self.ef.row = decl.token.row + let row = self.ef.row match type T { | &ast::VarDecl: self.var_decl(decl) @@ -561,26 +583,26 @@ impl Formatter { self.enum_item(decl) } let diff = self.buf.len - n - if max < diff { + if max < diff && row == self.ef.row { max = diff } lines = append(lines, self.buf[n:]) + rows = append(rows, self.ef.row) self.buf = self.buf[:self.buf.len - diff] i++ } - for _, line in lines { - row = nodes[start].token.row + for j, line in lines { + let row = rows[j] self.write_comments_except(row) self.write(line) let c = self.cm.first(row) if c != nil && c.row == row { self.cm.drop_first() - self.write(strings::repeat(" ", max - line.len + 1)) + self.write(strings::repeat(" ", padding_abs(max - line.len) + 1)) self.write_comment(c) } self.write("\n") - start++ } } @@ -940,11 +962,7 @@ impl ScopeFormatter { let mut row = c.exprs[0].token.row for (i, mut expr) in c.exprs { if row != expr.token.row { - let c = self.fmt.cm.pop(row) - if c != nil { - self.write(" ") - self.fmt.write_comment(c) - } + self.fmt.pop_row_comments(row) } self.fmt.write_comments_except(expr.token.row) if row != expr.token.row { @@ -960,11 +978,7 @@ impl ScopeFormatter { self.fmt.format_expr(expr) } self.write(":") - let cmt = self.fmt.cm.pop(row) - if cmt != nil { - self.write(" ") - self.fmt.write_comment(cmt) - } + self.fmt.pop_row_comments(row) self.write("\n") self.fmt.add_indent() self.format_stmts(c.scope.stmts) @@ -1094,11 +1108,7 @@ impl ScopeFormatter { self.fmt.write_comments_except(stmt.token.row) self.write(self.fmt.indent) self.format_stmt(stmt.data) - let c = self.fmt.cm.pop(stmt.token.row) - if c != nil { - self.write(" ") - self.fmt.write_comment(c) - } + self.fmt.pop_row_comments(stmt.token.row) } if old != i { i-- @@ -1137,7 +1147,9 @@ impl ScopeFormatter { } struct ExprFormatter { - mut fmt: &Formatter + mut fmt: &Formatter + mut row: int // Last seen row. + mut ignore_comments: bool } impl ExprFormatter { @@ -1220,10 +1232,8 @@ impl ExprFormatter { ret } self.fmt.add_indent() - let c = self.fmt.cm.pop(bin.op.row) - if c != nil { - self.write(" ") - self.fmt.write_comment(c) + if !self.ignore_comments { + self.fmt.pop_row_comments(bin.op.row) } self.write("\n") self.write(self.fmt.indent) @@ -1237,6 +1247,7 @@ impl ExprFormatter { goto rep |: self.format(bin.right) + self.row = bin.right.token.row } self.fmt.done_indent() } @@ -1256,18 +1267,14 @@ impl ExprFormatter { indented = true self.fmt.add_indent() } - let c = self.fmt.cm.pop(row) - if c != nil { - self.write(" ") - self.fmt.write_comment(c) - } + self.fmt.pop_row_comments(self.fmt.ef.row) self.write("\n") self.write(self.fmt.indent) - row = arg.token.row } else if i > 0 { self.write(" ") } self.format(arg) + row = self.fmt.ef.row } if indented { self.fmt.done_indent() @@ -1284,11 +1291,7 @@ impl ExprFormatter { self.args(f.args) self.write(")") if f.args.len > 0 { - let c = self.fmt.cm.pop(f.args[f.args.len - 1].token.row) - if c != nil { - self.write(" ") - self.fmt.write_comment(c) - } + self.fmt.pop_row_comments(f.args[f.args.len - 1].token.row) } if f.ignored() { self.write("!") @@ -1332,7 +1335,9 @@ impl ExprFormatter { } self.format(expr) if newline { - self.write(",\n") + self.write(",") + self.fmt.pop_row_comments(self.fmt.ef.row) + self.write("\n") } else if lit.exprs.len - i > 1 { self.write(", ") } @@ -1347,56 +1352,70 @@ impl ExprFormatter { fn responsive_exprs[T](self, mut &lit: T) { const CAP = 1 << 8 let mut exprs = make([]str, 0, CAP) + let mut rows = make([]int, 0, CAP) + let n = self.fmt.buf.len let mut max = 0 let mut row = lit.token.row let mut lined = false + + self.fmt.add_indent() + self.fmt.ef.ignore_comments = true + let ignore_comments = self.fmt.ef.ignore_comments + defer { + self.fmt.ef.ignore_comments = ignore_comments + } + for (i, mut expr) in lit.exprs { if row != expr.token.row { lined = true let diff = self.fmt.buf.len - n if diff > 0 { - if max < diff { + if max < diff && self.fmt.ef.row == row { max = diff } exprs = append(exprs, self.fmt.buf[n:]) self.fmt.buf = self.fmt.buf[:n] + rows = append(rows, self.fmt.ef.row) } } else if i > 0 { self.write(" ") } - row = expr.token.row self.format(expr) + row = expr.token.row 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 { + if max < diff && self.fmt.ef.row == row { max = diff } exprs = append(exprs, self.fmt.buf[n:]) + rows = append(rows, self.fmt.ef.row) 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 { + if lit.token.row != lit.exprs[0].token.row { + self.write("\n") + self.write(self.fmt.indent) + } + for i, expr in exprs { + let erow = rows[i] + self.write(expr) + for { + let c = self.fmt.cm.pop(erow) + if c == nil { + break + } + self.write(strings::repeat(" ", padding_abs(max - expr.len) + 1)) + self.fmt.write_comment(c) + } + if exprs.len - i > 1 { 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.fmt.write_comment(c) - } - j++ } - row = expr.token.row } self.fmt.done_indent() if self.fmt.buf[self.fmt.buf.len - 1] == '\n' { @@ -1404,8 +1423,6 @@ impl ExprFormatter { } else if lined { self.write("\n") self.write(self.fmt.indent) - } else if j < exprs.len { - self.write(exprs[j]) } } @@ -1413,11 +1430,7 @@ 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.fmt.write_comment(c) - } + self.fmt.pop_row_comments(lit.token.row) } fn key_val_pair(self, mut pair: &ast::KeyValPair) { @@ -1430,11 +1443,7 @@ 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.fmt.write_comment(c) - } + self.fmt.pop_row_comments(s.token.row) } fn indexing(self, mut i: &ast::IndexingExpr) { @@ -1518,6 +1527,7 @@ impl ExprFormatter { if expr == nil { ret } + self.row = expr.token.row if expr.range { self.write("(") } @@ -1527,3 +1537,10 @@ impl ExprFormatter { } } } + +fn padding_abs(x: int): int { + if x < 0 { + ret 0 + } + ret x +}