|
59 | 59 | extra, |
60 | 60 | parse, |
61 | 61 | sourceMap, |
| 62 | + sourceCode, |
| 63 | + preserveBlankLines, |
62 | 64 | FORMAT_MINIFY, |
63 | 65 | FORMAT_DEFAULTS; |
64 | 66 |
|
|
185 | 187 | compact: false, |
186 | 188 | parentheses: true, |
187 | 189 | semicolons: true, |
188 | | - safeConcatenation: false |
| 190 | + safeConcatenation: false, |
| 191 | + preserveBlankLines: false |
189 | 192 | }, |
190 | 193 | moz: { |
191 | 194 | comprehensionExpressionStartsWithAssignment: false, |
|
196 | 199 | sourceMapWithCode: false, |
197 | 200 | directive: false, |
198 | 201 | raw: true, |
199 | | - verbatim: null |
| 202 | + verbatim: null, |
| 203 | + sourceCode: null |
200 | 204 | }; |
201 | 205 | } |
202 | 206 |
|
|
645 | 649 | return '//' + comment.value; |
646 | 650 | } else { |
647 | 651 | // Always use LineTerminator |
648 | | - return '//' + comment.value + '\n'; |
| 652 | + var result = '//' + comment.value; |
| 653 | + if (!preserveBlankLines) { |
| 654 | + result += '\n'; |
| 655 | + } |
| 656 | + return result; |
649 | 657 | } |
650 | 658 | } |
651 | 659 | if (extra.format.indent.adjustMultilineComment && /[\n\r]/.test(comment.value)) { |
|
655 | 663 | } |
656 | 664 |
|
657 | 665 | function addComments(stmt, result) { |
658 | | - var i, len, comment, save, tailingToStatement, specialBase, fragment; |
| 666 | + var i, len, comment, save, tailingToStatement, specialBase, fragment, |
| 667 | + extRange, range, prevRange, prefix, infix, suffix, count; |
659 | 668 |
|
660 | 669 | if (stmt.leadingComments && stmt.leadingComments.length > 0) { |
661 | 670 | save = result; |
662 | 671 |
|
663 | | - comment = stmt.leadingComments[0]; |
664 | | - result = []; |
665 | | - if (safeConcatenation && stmt.type === Syntax.Program && stmt.body.length === 0) { |
666 | | - result.push('\n'); |
667 | | - } |
668 | | - result.push(generateComment(comment)); |
669 | | - if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { |
670 | | - result.push('\n'); |
671 | | - } |
| 672 | + if (preserveBlankLines) { |
| 673 | + comment = stmt.leadingComments[0]; |
| 674 | + result = []; |
| 675 | + |
| 676 | + extRange = comment.extendedRange; |
| 677 | + range = comment.range; |
| 678 | + |
| 679 | + prefix = sourceCode.substring(extRange[0], range[0]); |
| 680 | + count = (prefix.match(/\n/g) || []).length; |
| 681 | + if (count > 0) { |
| 682 | + result.push(stringRepeat('\n', count)); |
| 683 | + result.push(addIndent(generateComment(comment))); |
| 684 | + } else { |
| 685 | + result.push(prefix); |
| 686 | + result.push(generateComment(comment)); |
| 687 | + } |
| 688 | + |
| 689 | + prevRange = range; |
| 690 | + |
| 691 | + for (i = 1, len = stmt.leadingComments.length; i < len; i++) { |
| 692 | + comment = stmt.leadingComments[i]; |
| 693 | + range = comment.range; |
| 694 | + |
| 695 | + infix = sourceCode.substring(prevRange[1], range[0]); |
| 696 | + count = (infix.match(/\n/g) || []).length; |
| 697 | + result.push(stringRepeat('\n', count)); |
| 698 | + result.push(addIndent(generateComment(comment))); |
| 699 | + |
| 700 | + prevRange = range; |
| 701 | + } |
| 702 | + |
| 703 | + suffix = sourceCode.substring(range[1], extRange[1]); |
| 704 | + count = (suffix.match(/\n/g) || []).length; |
| 705 | + result.push(stringRepeat('\n', count)); |
| 706 | + } else { |
| 707 | + comment = stmt.leadingComments[0]; |
| 708 | + result = []; |
| 709 | + if (safeConcatenation && stmt.type === Syntax.Program && stmt.body.length === 0) { |
| 710 | + result.push('\n'); |
| 711 | + } |
| 712 | + result.push(generateComment(comment)); |
| 713 | + if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { |
| 714 | + result.push('\n'); |
| 715 | + } |
672 | 716 |
|
673 | | - for (i = 1, len = stmt.leadingComments.length; i < len; ++i) { |
674 | | - comment = stmt.leadingComments[i]; |
675 | | - fragment = [generateComment(comment)]; |
676 | | - if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { |
677 | | - fragment.push('\n'); |
| 717 | + for (i = 1, len = stmt.leadingComments.length; i < len; ++i) { |
| 718 | + comment = stmt.leadingComments[i]; |
| 719 | + fragment = [generateComment(comment)]; |
| 720 | + if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { |
| 721 | + fragment.push('\n'); |
| 722 | + } |
| 723 | + result.push(addIndent(fragment)); |
678 | 724 | } |
679 | | - result.push(addIndent(fragment)); |
680 | 725 | } |
681 | 726 |
|
682 | 727 | result.push(addIndent(save)); |
683 | 728 | } |
684 | 729 |
|
685 | 730 | if (stmt.trailingComments) { |
686 | | - tailingToStatement = !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString()); |
687 | | - specialBase = stringRepeat(' ', calculateSpaces(toSourceNodeWhenNeeded([base, result, indent]).toString())); |
688 | | - for (i = 0, len = stmt.trailingComments.length; i < len; ++i) { |
689 | | - comment = stmt.trailingComments[i]; |
690 | | - if (tailingToStatement) { |
691 | | - // We assume target like following script |
692 | | - // |
693 | | - // var t = 20; /** |
694 | | - // * This is comment of t |
695 | | - // */ |
696 | | - if (i === 0) { |
697 | | - // first case |
698 | | - result = [result, indent]; |
699 | | - } else { |
700 | | - result = [result, specialBase]; |
701 | | - } |
702 | | - result.push(generateComment(comment, specialBase)); |
| 731 | + |
| 732 | + if (preserveBlankLines) { |
| 733 | + comment = stmt.trailingComments[0]; |
| 734 | + extRange = comment.extendedRange; |
| 735 | + range = comment.range; |
| 736 | + |
| 737 | + prefix = sourceCode.substring(extRange[0], range[0]); |
| 738 | + count = (prefix.match(/\n/g) || []).length; |
| 739 | + |
| 740 | + if (count > 0) { |
| 741 | + result.push(stringRepeat('\n', count)); |
| 742 | + result.push(addIndent(generateComment(comment))); |
703 | 743 | } else { |
704 | | - result = [result, addIndent(generateComment(comment))]; |
| 744 | + result.push(prefix); |
| 745 | + result.push(generateComment(comment)); |
705 | 746 | } |
706 | | - if (i !== len - 1 && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { |
707 | | - result = [result, '\n']; |
| 747 | + } else { |
| 748 | + tailingToStatement = !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString()); |
| 749 | + specialBase = stringRepeat(' ', calculateSpaces(toSourceNodeWhenNeeded([base, result, indent]).toString())); |
| 750 | + for (i = 0, len = stmt.trailingComments.length; i < len; ++i) { |
| 751 | + comment = stmt.trailingComments[i]; |
| 752 | + if (tailingToStatement) { |
| 753 | + // We assume target like following script |
| 754 | + // |
| 755 | + // var t = 20; /** |
| 756 | + // * This is comment of t |
| 757 | + // */ |
| 758 | + if (i === 0) { |
| 759 | + // first case |
| 760 | + result = [result, indent]; |
| 761 | + } else { |
| 762 | + result = [result, specialBase]; |
| 763 | + } |
| 764 | + result.push(generateComment(comment, specialBase)); |
| 765 | + } else { |
| 766 | + result = [result, addIndent(generateComment(comment))]; |
| 767 | + } |
| 768 | + if (i !== len - 1 && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) { |
| 769 | + result = [result, '\n']; |
| 770 | + } |
708 | 771 | } |
709 | 772 | } |
710 | 773 | } |
711 | 774 |
|
712 | 775 | return result; |
713 | 776 | } |
714 | 777 |
|
| 778 | + function generateBlankLines(start, end, result) { |
| 779 | + var j, newlineCount = 0; |
| 780 | + |
| 781 | + for (j = start; j < end; j++) { |
| 782 | + if (sourceCode[j] === '\n') { |
| 783 | + newlineCount++; |
| 784 | + } |
| 785 | + } |
| 786 | + |
| 787 | + for (j = 1; j < newlineCount; j++) { |
| 788 | + result.push(newline); |
| 789 | + } |
| 790 | + } |
| 791 | + |
715 | 792 | function parenthesize(text, current, should) { |
716 | 793 | if (current < should) { |
717 | 794 | return ['(', text, ')']; |
|
924 | 1001 | CodeGenerator.Statement = { |
925 | 1002 |
|
926 | 1003 | BlockStatement: function (stmt, flags) { |
927 | | - var result = ['{', newline], that = this; |
| 1004 | + var range, content, result = ['{', newline], that = this; |
928 | 1005 |
|
929 | 1006 | withIndent(function () { |
| 1007 | + // handle functions without any code |
| 1008 | + if (stmt.body.length === 0 && preserveBlankLines) { |
| 1009 | + range = stmt.range; |
| 1010 | + if (range[1] - range[0] > 2) { |
| 1011 | + content = sourceCode.substring(range[0] + 1, range[1] - 1); |
| 1012 | + if (content[0] === '\n') { |
| 1013 | + result = ['{']; |
| 1014 | + } |
| 1015 | + result.push(content); |
| 1016 | + } |
| 1017 | + } |
| 1018 | + |
930 | 1019 | var i, iz, fragment, bodyFlags; |
931 | 1020 | bodyFlags = S_TFFF; |
932 | 1021 | if (flags & F_FUNC_BODY) { |
933 | 1022 | bodyFlags |= F_DIRECTIVE_CTX; |
934 | 1023 | } |
| 1024 | + |
935 | 1025 | for (i = 0, iz = stmt.body.length; i < iz; ++i) { |
| 1026 | + if (preserveBlankLines) { |
| 1027 | + // handle spaces before the first line |
| 1028 | + if (i === 0) { |
| 1029 | + if (stmt.body[0].leadingComments) { |
| 1030 | + range = stmt.body[0].leadingComments[0].extendedRange; |
| 1031 | + content = sourceCode.substring(range[0], range[1]); |
| 1032 | + if (content[0] === '\n') { |
| 1033 | + result = ['{']; |
| 1034 | + } |
| 1035 | + } |
| 1036 | + if (!stmt.body[0].leadingComments) { |
| 1037 | + generateBlankLines(stmt.range[0], stmt.body[0].range[0], result); |
| 1038 | + } |
| 1039 | + } |
| 1040 | + |
| 1041 | + // handle spaces between lines |
| 1042 | + if (i > 0) { |
| 1043 | + if (!stmt.body[i - 1].trailingComments && !stmt.body[i].leadingComments) { |
| 1044 | + generateBlankLines(stmt.body[i - 1].range[1], stmt.body[i].range[0], result); |
| 1045 | + } |
| 1046 | + } |
| 1047 | + } |
| 1048 | + |
936 | 1049 | if (i === iz - 1) { |
937 | 1050 | bodyFlags |= F_SEMICOLON_OPT; |
938 | 1051 | } |
939 | | - fragment = addIndent(that.generateStatement(stmt.body[i], bodyFlags)); |
| 1052 | + |
| 1053 | + if (stmt.body[i].leadingComments && preserveBlankLines) { |
| 1054 | + fragment = that.generateStatement(stmt.body[i], bodyFlags); |
| 1055 | + } else { |
| 1056 | + fragment = addIndent(that.generateStatement(stmt.body[i], bodyFlags)); |
| 1057 | + } |
| 1058 | + |
940 | 1059 | result.push(fragment); |
941 | 1060 | if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { |
942 | | - result.push(newline); |
| 1061 | + if (preserveBlankLines && i < iz - 1) { |
| 1062 | + // don't add a new line if there are leading coments |
| 1063 | + // in the next statement |
| 1064 | + if (!stmt.body[i + 1].leadingComments) { |
| 1065 | + result.push(newline); |
| 1066 | + } |
| 1067 | + } else { |
| 1068 | + result.push(newline); |
| 1069 | + } |
| 1070 | + } |
| 1071 | + |
| 1072 | + if (preserveBlankLines) { |
| 1073 | + // handle spaces after the last line |
| 1074 | + if (i === iz - 1) { |
| 1075 | + if (!stmt.body[i].trailingComments) { |
| 1076 | + generateBlankLines(stmt.body[i].range[1], stmt.range[1], result); |
| 1077 | + } |
| 1078 | + } |
943 | 1079 | } |
944 | 1080 | } |
945 | 1081 | }); |
|
1474 | 1610 | if (!safeConcatenation && i === iz - 1) { |
1475 | 1611 | bodyFlags |= F_SEMICOLON_OPT; |
1476 | 1612 | } |
| 1613 | + |
| 1614 | + if (preserveBlankLines) { |
| 1615 | + // handle spaces before the first line |
| 1616 | + if (i === 0) { |
| 1617 | + if (!stmt.body[0].leadingComments) { |
| 1618 | + generateBlankLines(stmt.range[0], stmt.body[i].range[0], result); |
| 1619 | + } |
| 1620 | + } |
| 1621 | + |
| 1622 | + // handle spaces between lines |
| 1623 | + if (i > 0) { |
| 1624 | + if (!stmt.body[i - 1].trailingComments && !stmt.body[i].leadingComments) { |
| 1625 | + generateBlankLines(stmt.body[i - 1].range[1], stmt.body[i].range[0], result); |
| 1626 | + } |
| 1627 | + } |
| 1628 | + } |
| 1629 | + |
1477 | 1630 | fragment = addIndent(this.generateStatement(stmt.body[i], bodyFlags)); |
1478 | 1631 | result.push(fragment); |
1479 | 1632 | if (i + 1 < iz && !endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) { |
1480 | | - result.push(newline); |
| 1633 | + if (preserveBlankLines) { |
| 1634 | + if (!stmt.body[i + 1].leadingComments) { |
| 1635 | + result.push(newline); |
| 1636 | + } |
| 1637 | + } else { |
| 1638 | + result.push(newline); |
| 1639 | + } |
| 1640 | + } |
| 1641 | + |
| 1642 | + if (preserveBlankLines) { |
| 1643 | + // handle spaces after the last line |
| 1644 | + if (i === iz - 1) { |
| 1645 | + if (!stmt.body[i].trailingComments) { |
| 1646 | + generateBlankLines(stmt.body[i].range[1], stmt.range[1], result); |
| 1647 | + } |
| 1648 | + } |
1481 | 1649 | } |
1482 | 1650 | } |
1483 | 1651 | return result; |
|
2257 | 2425 | directive = options.directive; |
2258 | 2426 | parse = json ? null : options.parse; |
2259 | 2427 | sourceMap = options.sourceMap; |
| 2428 | + sourceCode = options.sourceCode; |
| 2429 | + preserveBlankLines = options.format.preserveBlankLines && sourceCode !== null; |
2260 | 2430 | extra = options; |
2261 | 2431 |
|
2262 | 2432 | if (sourceMap) { |
|
0 commit comments