From d953b6751bd05193b7fdb21334766a2cc4d5d258 Mon Sep 17 00:00:00 2001 From: Einar Lielmanis Date: Fri, 11 Oct 2013 06:36:35 +0300 Subject: [PATCH] Implement flags.had_comment, fix #329, fix #291 We deliberately lose token_type = TK_COMMENT and TK_INLINE_COMMENT to allow their transparent handling. To counteract this, flags.had_comment counter-spell is implemented, so that we had a possibility to know that there was, in fact, a comment somewhere. Thus, we can fix some corner-cases where an unexpected comment might break the structure. --- js/lib/beautify.js | 10 ++++++---- js/test/beautify-tests.js | 9 +++++++++ python/jsbeautifier/__init__.py | 8 +++++--- python/jsbeautifier/tests/testjsbeautifier.py | 9 +++++++++ 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/js/lib/beautify.js b/js/lib/beautify.js index 17a64236..2fc7b21e 100644 --- a/js/lib/beautify.js +++ b/js/lib/beautify.js @@ -163,6 +163,7 @@ indentation_level: next_indent_level, line_indent_level: flags_base ? flags_base.line_indent_level : next_indent_level, start_line_index: output_lines.length, + had_comment: false, ternary_depth: 0 } return next_flags; @@ -296,6 +297,8 @@ last_type = token_type; flags.last_text = token_text; } + flags.had_comment = (token_type === 'TK_INLINE_COMMENT' || token_type === 'TK_COMMENT' + || token_type === 'TK_BLOCK_COMMENT'); } @@ -1245,11 +1248,10 @@ if (flags.var_line && last_type !== 'TK_EQUALS') { flags.var_line_reindented = true; } - if ((just_added_newline() || flags.last_text === ';' || flags.last_text === '}') && - flags.last_text !== '{' && !is_array(flags.mode)) { + if (in_array(flags.last_text, ['}', ';']) || (just_added_newline() && ! in_array(flags.last_text, ['{', ':', '=', ',']))) { // make sure there is a nice clean space of at least one blank line - // before a new function definition, except in arrays - if (!just_added_blankline()) { + // before a new function definition + if ( ! just_added_blankline() && ! flags.had_comment) { print_newline(); print_newline(true); } diff --git a/js/test/beautify-tests.js b/js/test/beautify-tests.js index bd12947d..1528f02b 100755 --- a/js/test/beautify-tests.js +++ b/js/test/beautify-tests.js @@ -1297,6 +1297,14 @@ function run_beautifier_tests(test_obj, Urlencoded, js_beautify, html_beautify) bt('(if(a) b())\n\n\n(if(a) b())', '(\n if (a) b())\n\n\n(\n if (a) b())'); + // space between functions + bt('/*\n * foo\n */\nfunction foo() {}'); + bt('// a nice function\nfunction foo() {}'); + bt('function foo() {}\nfunction foo() {}', + 'function foo() {}\n\nfunction foo() {}' + ); + + bt("if\n(a)\nb();", "if (a)\n b();"); bt('var a =\nfoo', 'var a =\n foo'); @@ -1364,6 +1372,7 @@ function run_beautifier_tests(test_obj, Urlencoded, js_beautify, html_beautify) bt('xml=\n foox/]]>;', 'xml = \n foox/]]>;'); bt('xml=;', 'xml = ;'); bt('xml=;', 'xml = ;'); + // Handles messed up tags, as long as it isn't the same name // as the root tag. Also handles tags of same name as root tag // as long as nesting matches. diff --git a/python/jsbeautifier/__init__.py b/python/jsbeautifier/__init__.py index 1ffd3735..054bdedd 100644 --- a/python/jsbeautifier/__init__.py +++ b/python/jsbeautifier/__init__.py @@ -127,6 +127,7 @@ class BeautifierFlags: self.line_indent_level = 0 self.start_line_index = 0 self.ternary_depth = 0 + self.had_comment = False def apply_base(self, flags_base, added_newline): next_indent_level = flags_base.indentation_level; @@ -332,6 +333,7 @@ class Beautifier: self.last_last_text = self.flags.last_text self.last_type = token_type self.flags.last_text = self.token_text + self.flags.had_comment = token_type in ['TK_COMMENT', 'TK_INLINE_COMMENT', 'TK_BLOCK_COMMENT'] sweet_code = ''.join(self.output_lines[0].text) if len(self.output_lines) > 1: @@ -1063,11 +1065,11 @@ class Beautifier: if token_text == 'function': if self.flags.var_line and self.flags.last_text != '=': self.flags.var_line_reindented = not self.opts.keep_function_indentation - if (self.just_added_newline() or self.flags.last_text == ';' or self.flags.last_text == '}') and \ - self.flags.last_text != '{' and not self.is_array(self.flags.mode): + + if self.flags.last_text in ['}', ';'] or (self.just_added_newline() and not self.flags.last_text in ['{', ':', '=', ',']): # make sure there is a nice clean space of at least one blank line # before a new function definition, except in arrays - if not self.just_added_blankline(): + if not self.just_added_blankline() and not self.flags.had_comment: self.append_newline() self.append_newline(True) diff --git a/python/jsbeautifier/tests/testjsbeautifier.py b/python/jsbeautifier/tests/testjsbeautifier.py index 7a0da30b..fed709a7 100644 --- a/python/jsbeautifier/tests/testjsbeautifier.py +++ b/python/jsbeautifier/tests/testjsbeautifier.py @@ -1112,6 +1112,15 @@ class TestJSBeautifier(unittest.TestCase): bt('(if(a) b())\n\n\n(if(a) b())', '(\n if (a) b())\n(\n if (a) b())'); + # space between functions + bt('/*\n * foo\n */\nfunction foo() {}'); + bt('// a nice function\nfunction foo() {}'); + bt('function foo() {}\nfunction foo() {}', + 'function foo() {}\n\nfunction foo() {}' + ); + + + bt("if\n(a)\nb();", "if (a) b();"); bt('var a =\nfoo', 'var a = foo'); bt('var a = {\n"a":1,\n"b":2}', "var a = {\n \"a\": 1,\n \"b\": 2\n}");