Skip to content

Commit

Permalink
Merge pull request #2033 from mhnaeem/feature/space-after-named-funct…
Browse files Browse the repository at this point in the history
…ion-classes

Fixes #1622 - Adds space_after_named_function option for ES6 classes
  • Loading branch information
bitwiseman committed Apr 22, 2022
2 parents 3f22fa1 + 4cc5e6e commit ffd14ab
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 1 deletion.
9 changes: 9 additions & 0 deletions js/src/javascript/beautifier.js
Expand Up @@ -185,6 +185,7 @@ Beautifier.prototype.create_flags = function(flags_base, mode) {
inline_frame: false,
if_block: false,
else_block: false,
class_start_block: false, // class A { INSIDE HERE } or class B extends C { INSIDE HERE }
do_block: false,
do_while: false,
import_block: false,
Expand Down Expand Up @@ -597,6 +598,8 @@ Beautifier.prototype.handle_start_expr = function(current_token) {
(peek_back_two.text === '*' && (peek_back_three.text === '{' || peek_back_three.text === ','))) {
this._output.space_before_token = true;
}
} else if (this._flags.parent && this._flags.parent.class_start_block) {
this._output.space_before_token = true;
}
}
} else {
Expand Down Expand Up @@ -711,6 +714,12 @@ Beautifier.prototype.handle_start_block = function(current_token) {
this.set_mode(MODE.BlockStatement);
}

if (this._flags.last_token) {
if (reserved_array(this._flags.last_token.previous, ['class', 'extends'])) {
this._flags.class_start_block = true;
}
}

var empty_braces = !next_token.comments_before && next_token.text === '}';
var empty_anonymous_function = empty_braces && this._flags.last_word === 'function' &&
this._flags.last_token.type === TOKEN.END_EXPR;
Expand Down
2 changes: 1 addition & 1 deletion js/src/javascript/tokenizer.js
Expand Up @@ -95,7 +95,7 @@ var punct_pattern = new RegExp(punct);

// words which should always start on new line.
var line_starters = 'continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export'.split(',');
var reserved_words = line_starters.concat(['do', 'in', 'of', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from', 'as']);
var reserved_words = line_starters.concat(['do', 'in', 'of', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from', 'as', 'class', 'extends']);
var reserved_word_pattern = new RegExp('^(?:' + reserved_words.join('|') + ')$');

// var template_pattern = /(?:(?:<\?php|<\?=)[\s\S]*?\?>)|(?:<%[\s\S]*?%>)/g;
Expand Down
7 changes: 7 additions & 0 deletions python/jsbeautifier/javascript/beautifier.py
Expand Up @@ -48,6 +48,7 @@ def __init__(self, mode):
self.inline_frame = False
self.if_block = False
self.else_block = False
self.class_start_block = False
self.do_block = False
self.do_while = False
self.import_block = False
Expand Down Expand Up @@ -609,6 +610,8 @@ def handle_start_expr(self, current_token):
)
):
self._output.space_before_token = True
elif self._flags.parent and self._flags.parent.class_start_block:
self._output.space_before_token = True
else:
# Support preserving wrapped arrow function expressions
# a.b('c',
Expand Down Expand Up @@ -759,6 +762,10 @@ def handle_start_block(self, current_token):
else:
self.set_mode(MODE.BlockStatement)

if self._flags.last_token:
if reserved_array(self._flags.last_token.previous, ["class", "extends"]):
self._flags.class_start_block = True

empty_braces = (
(next_token is not None)
and next_token.comments_before is None
Expand Down
2 changes: 2 additions & 0 deletions python/jsbeautifier/javascript/tokenizer.py
Expand Up @@ -113,6 +113,8 @@ def __init__(self):
"await",
"from",
"as",
"class",
"extends",
]
)

Expand Down
65 changes: 65 additions & 0 deletions test/data/javascript/tests.js
Expand Up @@ -3191,6 +3191,71 @@ exports.test_data = {
input: 'switch(x){case -1:break;case !y:{break;}}',
output: 'switch (x) {\n{{c}}case -1:\n{{c}} break;\n{{c}}case !y: {\n{{c}} break;\n{{c}}\}\n}'
},
{
comment: "Issue #1622 - basic class with function definitions",
input: [
'class blah {',
' constructor() {',
' this.doStuff()',
' }',
' doStuff() {',
' console.log("stuff")',
' }',
'}'
],
output: [
'class blah {',
' constructor{{nf}}() {',
' this.doStuff()',
' }',
' doStuff{{nf}}() {',
' console.log("stuff")',
' }',
'}'
]
},
{
comment: "Issue #1622 - class with extends and function definitions",
input: [
'class blah extends something {',
' constructor() {',
' this.zz = 2 + 2;',
' }',
' someOtherFunction() {',
'this.y = 1;',
' }',
'}'
],
output: [
'class blah extends something {',
' constructor{{nf}}() {',
' this.zz = 2 + 2;',
' }',
' someOtherFunction{{nf}}() {',
' this.y = 1;',
' }',
'}'
]
},
{
comment: "Issue #1622 - class/extends as a property",
input: [
'var a.class = {',
' ...abc(),',
'}',
'b.extends({',
' bb.s(),',
'})'
],
output: [
'var a.class = {',
' ...abc(),',
'}',
'b.extends({',
' bb.s(),',
'})'
]
},
{
comment: 'typical greasemonkey start',
fragment: true,
Expand Down

0 comments on commit ffd14ab

Please sign in to comment.