| ... | ... | @@ -19,7 +19,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) (@typeOf( |
| 19 | 19 | var tok_it = tree.tokens.iterator(0); |
| 20 | 20 | while (tok_it.next()) |token| { |
| 21 | 21 | if (token.id != Token.Id.LineComment) break; |
| 22 | | try stream.print("{}\n", tree.tokenSlicePtr(token)); |
| 22 | try stream.print("{}\n", mem.trimRight(u8, tree.tokenSlicePtr(token), " ")); |
| 23 | 23 | if (tok_it.peek()) |next_token| { |
| 24 | 24 | const loc = tree.tokenLocationPtr(token.end, next_token); |
| 25 | 25 | if (loc.line >= 2) { |
| ... | ... | @@ -532,12 +532,73 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind |
| 532 | 532 | |
| 533 | 533 | try renderExpression(allocator, stream, tree, indent, suffix_op.lhs, Space.None); |
| 534 | 534 | |
| 535 | // scan to find row size |
| 536 | const maybe_row_size: ?usize = blk: { |
| 537 | var count: usize = 0; |
| 538 | var it = exprs.iterator(0); |
| 539 | var prev_token = (??it.peek()).*.lastToken() + 1; |
| 540 | while (it.next()) |expr| { |
| 541 | const expr_last_token = expr.*.lastToken() + 1; |
| 542 | const next_token = tree.tokens.at(expr_last_token + 1); |
| 543 | const loc = tree.tokenLocationPtr(tree.tokens.at(prev_token).end, next_token); |
| 544 | if (loc.line != 0) break :blk null; |
| 545 | if (next_token.id == Token.Id.LineComment) { |
| 546 | const trimmed = mem.trimRight(u8, tree.tokenSlicePtr(next_token), " "); |
| 547 | if (trimmed.len == 2) { |
| 548 | break :blk count; |
| 549 | } else { |
| 550 | break :blk null; |
| 551 | } |
| 552 | } |
| 553 | prev_token = expr_last_token; |
| 554 | count += 1; |
| 555 | } |
| 556 | break :blk null; |
| 557 | }; |
| 558 | |
| 559 | |
| 535 | 560 | const new_indent = indent + indent_delta; |
| 536 | 561 | try renderToken(tree, stream, lbrace, new_indent, Space.Newline); |
| 562 | try stream.writeByteNTimes(' ', new_indent); |
| 563 | |
| 564 | if (maybe_row_size) |row_size| { |
| 565 | var it = exprs.iterator(0); |
| 566 | var i: usize = 0; |
| 567 | while (it.next()) |expr| { |
| 568 | if (it.peek()) |next_expr| { |
| 569 | try renderExpression(allocator, stream, tree, new_indent, expr.*, Space.None); |
| 570 | |
| 571 | const comma = tree.nextToken(expr.*.lastToken()); |
| 572 | |
| 573 | if (i != row_size) { |
| 574 | try renderToken(tree, stream, comma, new_indent, Space.IgnoreEmptyComment); // , |
| 575 | i += 1; |
| 576 | continue; |
| 577 | } |
| 578 | i = 0; |
| 579 | |
| 580 | try renderToken(tree, stream, comma, new_indent, Space.NoIndent); // , |
| 581 | |
| 582 | const next_token = tree.tokens.at(comma + 1); |
| 583 | if (next_token.id != Token.Id.LineComment) { |
| 584 | try stream.print(" //\n"); |
| 585 | } |
| 586 | |
| 587 | try renderExtraNewline(tree, stream, next_expr.*); |
| 588 | try stream.writeByteNTimes(' ', new_indent); |
| 589 | } else if (i == row_size) { |
| 590 | try renderTrailingCommaAndEmptyComment(allocator, stream, tree, new_indent, expr.*); // , // |
| 591 | } else { |
| 592 | try renderTrailingComma(allocator, stream, tree, new_indent, expr.*, Space.Newline); // , |
| 593 | } |
| 594 | } |
| 595 | try stream.writeByteNTimes(' ', indent); |
| 596 | try renderToken(tree, stream, suffix_op.rtoken, indent, space); |
| 597 | return; |
| 598 | } |
| 537 | 599 | |
| 538 | 600 | var it = exprs.iterator(0); |
| 539 | 601 | while (it.next()) |expr| { |
| 540 | | try stream.writeByteNTimes(' ', new_indent); |
| 541 | 602 | |
| 542 | 603 | if (it.peek()) |next_expr| { |
| 543 | 604 | try renderExpression(allocator, stream, tree, new_indent, expr.*, Space.None); |
| ... | ... | @@ -546,6 +607,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind |
| 546 | 607 | try renderToken(tree, stream, comma, new_indent, Space.Newline); // , |
| 547 | 608 | |
| 548 | 609 | try renderExtraNewline(tree, stream, next_expr.*); |
| 610 | try stream.writeByteNTimes(' ', new_indent); |
| 549 | 611 | } else { |
| 550 | 612 | try renderTrailingComma(allocator, stream, tree, new_indent, expr.*, Space.Newline); |
| 551 | 613 | } |
| ... | ... | @@ -1496,11 +1558,12 @@ const Space = enum { |
| 1496 | 1558 | NoNewline, |
| 1497 | 1559 | NoIndent, |
| 1498 | 1560 | NoComment, |
| 1561 | IgnoreEmptyComment, |
| 1499 | 1562 | }; |
| 1500 | 1563 | |
| 1501 | 1564 | fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, space: Space) (@typeOf(stream).Child.Error || Error)!void { |
| 1502 | 1565 | var token = tree.tokens.at(token_index); |
| 1503 | | try stream.write(tree.tokenSlicePtr(token)); |
| 1566 | try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(token), " ")); |
| 1504 | 1567 | |
| 1505 | 1568 | if (space == Space.NoComment) return; |
| 1506 | 1569 | |
| ... | ... | @@ -1515,15 +1578,19 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent |
| 1515 | 1578 | return stream.write("\n"); |
| 1516 | 1579 | } |
| 1517 | 1580 | }, |
| 1518 | | Space.Space => return stream.writeByte(' '), |
| 1581 | Space.Space, Space.IgnoreEmptyComment => return stream.writeByte(' '), |
| 1519 | 1582 | Space.NoComment => unreachable, |
| 1520 | 1583 | } |
| 1521 | 1584 | } |
| 1522 | 1585 | |
| 1586 | if (space == Space.IgnoreEmptyComment and mem.trimRight(u8, tree.tokenSlicePtr(next_token), " ").len == 2) { |
| 1587 | return stream.writeByte(' '); |
| 1588 | } |
| 1589 | |
| 1523 | 1590 | var loc = tree.tokenLocationPtr(token.end, next_token); |
| 1524 | 1591 | var offset: usize = 1; |
| 1525 | 1592 | if (loc.line == 0) { |
| 1526 | | try stream.print(" {}", tree.tokenSlicePtr(next_token)); |
| 1593 | try stream.print(" {}", mem.trimRight(u8, tree.tokenSlicePtr(next_token), " ")); |
| 1527 | 1594 | offset = 2; |
| 1528 | 1595 | token = next_token; |
| 1529 | 1596 | next_token = tree.tokens.at(token_index + offset); |
| ... | ... | @@ -1546,7 +1613,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent |
| 1546 | 1613 | } |
| 1547 | 1614 | }, |
| 1548 | 1615 | Space.NoNewline => {}, |
| 1549 | | Space.NoComment => unreachable, |
| 1616 | Space.NoComment, Space.IgnoreEmptyComment => unreachable, |
| 1550 | 1617 | } |
| 1551 | 1618 | return; |
| 1552 | 1619 | } |
| ... | ... | @@ -1558,7 +1625,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent |
| 1558 | 1625 | const newline_count = if (loc.line == 1) u8(1) else u8(2); |
| 1559 | 1626 | try stream.writeByteNTimes('\n', newline_count); |
| 1560 | 1627 | try stream.writeByteNTimes(' ', indent); |
| 1561 | | try stream.write(tree.tokenSlicePtr(next_token)); |
| 1628 | try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(next_token), " ")); |
| 1562 | 1629 | |
| 1563 | 1630 | offset += 1; |
| 1564 | 1631 | token = next_token; |
| ... | ... | @@ -1583,7 +1650,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent |
| 1583 | 1650 | try stream.writeByteNTimes(' ', next_line_indent); |
| 1584 | 1651 | }, |
| 1585 | 1652 | Space.NoNewline => {}, |
| 1586 | | Space.NoComment => unreachable, |
| 1653 | Space.NoComment, Space.IgnoreEmptyComment => unreachable, |
| 1587 | 1654 | } |
| 1588 | 1655 | return; |
| 1589 | 1656 | } |
| ... | ... | @@ -1621,3 +1688,28 @@ fn renderTrailingComma(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, |
| 1621 | 1688 | }, |
| 1622 | 1689 | } |
| 1623 | 1690 | } |
| 1691 | |
| 1692 | fn renderTrailingCommaAndEmptyComment(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, base: &ast.Node) (@typeOf(stream).Child.Error || Error)!void |
| 1693 | { |
| 1694 | const end_token = base.lastToken() + 1; |
| 1695 | switch (tree.tokens.at(end_token).id) { |
| 1696 | Token.Id.Comma => { |
| 1697 | try renderExpression(allocator, stream, tree, indent, base, Space.None); |
| 1698 | try renderToken(tree, stream, end_token, indent, Space.Space); // , |
| 1699 | |
| 1700 | const next_token = tree.tokens.at(end_token + 1); |
| 1701 | if (next_token.id != Token.Id.LineComment) { |
| 1702 | try stream.print("//\n"); |
| 1703 | } |
| 1704 | }, |
| 1705 | Token.Id.LineComment => { |
| 1706 | try renderExpression(allocator, stream, tree, indent, base, Space.NoComment); |
| 1707 | try stream.write(", "); |
| 1708 | try renderToken(tree, stream, end_token, indent, Space.Newline); |
| 1709 | }, |
| 1710 | else => { |
| 1711 | try renderExpression(allocator, stream, tree, indent, base, Space.None); |
| 1712 | try stream.write(", //\n"); |
| 1713 | }, |
| 1714 | } |
| 1715 | } |