mirror of
https://github.com/beautifier/js-beautify.git
synced 2024-11-23 12:49:40 +00:00
Destructuring, importing, and short objects
Fixes #114 Fixes #315 Fixes #370 Fixes #382
This commit is contained in:
parent
49624f9c41
commit
55f111eecd
@ -1,5 +1,6 @@
|
||||
# JS Beautifier
|
||||
[![Build Status](https://img.shields.io/travis/beautify-web/js-beautify/master.svg)](http://travis-ci.org/beautify-web/js-beautify)
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/5bxmpvew5n3e58te/branch/master?svg=true)](https://ci.appveyor.com/project/beautify-web/js-beautify/branch/master)
|
||||
[![NPM version](https://img.shields.io/npm/v/js-beautify.svg)](https://www.npmjs.com/package/js-beautify)
|
||||
[![Download stats](https://img.shields.io/npm/dm/js-beautify.svg)](https://www.npmjs.com/package/js-beautify)
|
||||
[![Join the chat at https://gitter.im/beautify-web/js-beautify](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/beautify-web/js-beautify?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
@ -356,6 +356,7 @@
|
||||
|
||||
<select id="brace-style">
|
||||
<option value="collapse">Braces with control statement</option>
|
||||
<option value="collapse-preserve-inline">Braces with control statement, preserve inline</option>
|
||||
<option value="expand">Braces on own line</option>
|
||||
<option value="end-expand">End braces on own line</option>
|
||||
<option value="none">Attempt to keep braces where
|
||||
|
@ -61,7 +61,7 @@
|
||||
space_after_anon_function (default false) - should the space before an anonymous function's parens be added, "function()" vs "function ()",
|
||||
NOTE: This option is overriden by jslint_happy (i.e. if jslint_happy is true, space_after_anon_function is true by design)
|
||||
|
||||
brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "none"
|
||||
brace_style (default "collapse") - "collapse-preserve-inline" | "collapse" | "expand" | "end-expand" | "none"
|
||||
put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are.
|
||||
|
||||
space_before_conditional (default true) - should the space before conditional statement be added, "if(true)" vs "if (true)",
|
||||
@ -239,6 +239,7 @@
|
||||
declaration_statement: false,
|
||||
declaration_assignment: false,
|
||||
multiline_frame: false,
|
||||
inline_frame: false,
|
||||
if_block: false,
|
||||
else_block: false,
|
||||
do_block: false,
|
||||
@ -766,20 +767,22 @@
|
||||
set_mode(MODE.BlockStatement);
|
||||
}
|
||||
} else if (in_array(last_type, ['TK_EQUALS', 'TK_START_EXPR', 'TK_COMMA', 'TK_OPERATOR']) ||
|
||||
(last_type === 'TK_RESERVED' && in_array(flags.last_text, ['return', 'throw']))
|
||||
(last_type === 'TK_RESERVED' && in_array(flags.last_text, ['return', 'throw', 'import']))
|
||||
) {
|
||||
// Detecting shorthand function syntax is difficult by scanning forward, so check the surrounding context.
|
||||
// If the block is being returned, passed as arg, assigned with = or assigned in a nested object, treat as an ObjectLiteral.
|
||||
// Detecting shorthand function syntax is difficult by scanning forward,
|
||||
// so check the surrounding context.
|
||||
// If the block is being returned, imported, passed as arg,
|
||||
// assigned with = or assigned in a nested object, treat as an ObjectLiteral.
|
||||
set_mode(MODE.ObjectLiteral);
|
||||
} else {
|
||||
set_mode(MODE.BlockStatement);
|
||||
}
|
||||
|
||||
|
||||
var empty_braces = !next_token.comments_before.length && next_token.text === '}';
|
||||
var empty_anonymous_function = empty_braces && flags.last_word === 'function' &&
|
||||
last_type === 'TK_END_EXPR';
|
||||
|
||||
|
||||
if (opt.brace_style === "expand" ||
|
||||
(opt.brace_style === "none" && current_token.wanted_newline)) {
|
||||
if (last_type !== 'TK_OPERATOR' &&
|
||||
@ -791,22 +794,39 @@
|
||||
print_newline(false, true);
|
||||
}
|
||||
} else { // collapse
|
||||
if (last_type !== 'TK_OPERATOR' && last_type !== 'TK_START_EXPR') {
|
||||
if (opt.brace_style === 'collapse-preserve-inline') {
|
||||
// search forward for a newline wanted inside this block
|
||||
var index = 0;
|
||||
var check_token = null;
|
||||
flags.inline_frame = true;
|
||||
do {
|
||||
index += 1;
|
||||
check_token = get_token(index);
|
||||
if (check_token.wanted_newline) {
|
||||
flags.inline_frame = false;
|
||||
break;
|
||||
}
|
||||
} while (check_token.type !== 'TK_EOF' &&
|
||||
!(check_token.type === 'TK_END_BLOCK' && check_token.opened === current_token))
|
||||
}
|
||||
|
||||
if (is_array(previous_flags.mode) && (last_type === 'TK_START_EXPR' || last_type === 'TK_COMMA')) {
|
||||
// if we're preserving inline,
|
||||
// allow newline between comma and next brace.
|
||||
if (flags.inline_frame) {
|
||||
allow_wrap_or_preserved_newline();
|
||||
flags.inline_frame = true;
|
||||
previous_flags.multiline_frame = previous_flags.multiline_frame || flags.multiline_frame;
|
||||
flags.multiline_frame = false;
|
||||
} else {
|
||||
output.space_before_token = last_type === 'TK_COMMA';
|
||||
}
|
||||
} else if (last_type !== 'TK_OPERATOR' && last_type !== 'TK_START_EXPR') {
|
||||
if (last_type === 'TK_START_BLOCK') {
|
||||
print_newline();
|
||||
} else {
|
||||
output.space_before_token = true;
|
||||
}
|
||||
} else {
|
||||
// if TK_OPERATOR or TK_START_EXPR
|
||||
if (is_array(previous_flags.mode) && flags.last_text === ',') {
|
||||
if (last_last_text === '}') {
|
||||
// }, { in array context
|
||||
output.space_before_token = true;
|
||||
} else {
|
||||
print_newline(); // [a, b, c, {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print_token();
|
||||
@ -827,7 +847,9 @@
|
||||
} else {
|
||||
// skip {}
|
||||
if (!empty_braces) {
|
||||
if (is_array(flags.mode) && opt.keep_array_indentation) {
|
||||
if (flags.inline_frame) {
|
||||
output.space_before_token = true;
|
||||
} else if (is_array(flags.mode) && opt.keep_array_indentation) {
|
||||
// we REALLY need a newline here, but newliner would skip that
|
||||
opt.keep_array_indentation = false;
|
||||
print_newline();
|
||||
@ -951,7 +973,8 @@
|
||||
prefix = 'NONE';
|
||||
|
||||
if (last_type === 'TK_END_BLOCK') {
|
||||
if (!(current_token.type === 'TK_RESERVED' && in_array(current_token.text, ['else', 'catch', 'finally']))) {
|
||||
|
||||
if (!(current_token.type === 'TK_RESERVED' && in_array(current_token.text, ['else', 'catch', 'finally', 'from']))) {
|
||||
prefix = 'NEWLINE';
|
||||
} else {
|
||||
if (opt.brace_style === "expand" ||
|
||||
@ -974,7 +997,11 @@
|
||||
(flags.last_text === '*' && last_last_text === 'function')) {
|
||||
prefix = 'SPACE';
|
||||
} else if (last_type === 'TK_START_BLOCK') {
|
||||
prefix = 'NEWLINE';
|
||||
if (flags.inline_frame) {
|
||||
prefix = 'SPACE';
|
||||
} else {
|
||||
prefix = 'NEWLINE';
|
||||
}
|
||||
} else if (last_type === 'TK_END_EXPR') {
|
||||
output.space_before_token = true;
|
||||
prefix = 'NEWLINE';
|
||||
@ -1056,7 +1083,7 @@
|
||||
// The conditional starts the statement if appropriate.
|
||||
// One difference - strings want at least a space before
|
||||
output.space_before_token = true;
|
||||
} else if (last_type === 'TK_RESERVED' || last_type === 'TK_WORD') {
|
||||
} else if (last_type === 'TK_RESERVED' || last_type === 'TK_WORD' || flags.inline_frame) {
|
||||
output.space_before_token = true;
|
||||
} else if (last_type === 'TK_COMMA' || last_type === 'TK_START_EXPR' || last_type === 'TK_EQUALS' || last_type === 'TK_OPERATOR') {
|
||||
if (!start_of_object_property()) {
|
||||
@ -1106,15 +1133,18 @@
|
||||
}
|
||||
|
||||
print_token();
|
||||
output.space_before_token = true;
|
||||
if (flags.mode === MODE.ObjectLiteral ||
|
||||
(flags.mode === MODE.Statement && flags.parent.mode === MODE.ObjectLiteral)) {
|
||||
if (flags.mode === MODE.Statement) {
|
||||
restore_mode();
|
||||
}
|
||||
print_newline();
|
||||
|
||||
if (!flags.inline_frame) {
|
||||
print_newline();
|
||||
}
|
||||
} else {
|
||||
// EXPR or DO_BLOCK
|
||||
output.space_before_token = true;
|
||||
// for comma-first, we want to allow a newline before the comma
|
||||
// to turn into a newline after the comma, which we will fixup later
|
||||
if (opt.comma_first) {
|
||||
@ -1200,7 +1230,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags.mode === MODE.BlockStatement || flags.mode === MODE.Statement) && (flags.last_text === '{' || flags.last_text === ';')) {
|
||||
|
||||
if (((flags.mode === MODE.BlockStatement && !flags.inline_frame) || flags.mode === MODE.Statement)
|
||||
&& (flags.last_text === '{' || flags.last_text === ';')) {
|
||||
// { foo; --i }
|
||||
// foo(); --bar;
|
||||
print_newline();
|
||||
@ -1556,6 +1588,7 @@
|
||||
this.wanted_newline = newlines > 0;
|
||||
this.whitespace_before = whitespace_before || '';
|
||||
this.parent = null;
|
||||
this.opened = null;
|
||||
this.directives = null;
|
||||
}
|
||||
|
||||
@ -1570,7 +1603,7 @@
|
||||
var punct = ('+ - * / % & ++ -- = += -= *= /= %= == === != !== > < >= <= >> << >>> >>>= >>= <<= && &= | || ! ~ , : ? ^ ^= |= :: => **').split(' ');
|
||||
// words which should always start on new line.
|
||||
this.line_starters = 'continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export'.split(',');
|
||||
var reserved_words = this.line_starters.concat(['do', 'in', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await']);
|
||||
var reserved_words = this.line_starters.concat(['do', 'in', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from']);
|
||||
|
||||
// /* ... */ comment ends with nearest */ or end of file
|
||||
var block_comment_pattern = /([\s\S]*?)((?:\*\/)|$)/g;
|
||||
@ -1627,6 +1660,8 @@
|
||||
(next.text === ')' && open.text === '(') ||
|
||||
(next.text === '}' && open.text === '{')))) {
|
||||
next.parent = open.parent;
|
||||
next.opened = open
|
||||
|
||||
open = open_stack.pop();
|
||||
}
|
||||
|
||||
|
@ -300,6 +300,35 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify,
|
||||
test_fragment('\n', '');
|
||||
|
||||
|
||||
// Brace style permutations - (ibo = "", iao = "", ibc = "", iac = "", obo = " ", oao = " ", obc = " ", oac = " ")
|
||||
opts.brace_style = 'collapse-preserve-inline';
|
||||
bt('var a ={a: 2};\nvar a ={a: 2};', 'var a = { a: 2 };\nvar a = { a: 2 };');
|
||||
bt('//case 1\nif (a == 1){}\n//case 2\nelse if (a == 2){}', '//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}');
|
||||
bt('if(1){2}else{3}', 'if (1) { 2 } else { 3 }');
|
||||
bt('try{a();}catch(b){c();}catch(d){}finally{e();}', 'try { a(); } catch (b) { c(); } catch (d) {} finally { e(); }');
|
||||
|
||||
// Brace style permutations - (ibo = "\n", iao = "\n", ibc = "\n", iac = "\n", obo = " ", oao = "\n ", obc = "\n", oac = " ")
|
||||
opts.brace_style = 'collapse-preserve-inline';
|
||||
bt('var a =\n{\na: 2\n}\n;\nvar a =\n{\na: 2\n}\n;', 'var a = {\n a: 2\n};\nvar a = {\n a: 2\n};');
|
||||
bt('//case 1\nif (a == 1)\n{}\n//case 2\nelse if (a == 2)\n{}', '//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}');
|
||||
bt('if(1)\n{\n2\n}\nelse\n{\n3\n}', 'if (1) {\n 2\n} else {\n 3\n}');
|
||||
bt('try\n{\na();\n}\ncatch(b)\n{\nc();\n}\ncatch(d)\n{}\nfinally\n{\ne();\n}', 'try {\n a();\n} catch (b) {\n c();\n} catch (d) {} finally {\n e();\n}');
|
||||
|
||||
// Brace style permutations - (ibo = "", iao = "", ibc = "", iac = "", obo = " ", oao = "\n ", obc = "\n", oac = " ")
|
||||
opts.brace_style = 'collapse';
|
||||
bt('var a ={a: 2};\nvar a ={a: 2};', 'var a = {\n a: 2\n};\nvar a = {\n a: 2\n};');
|
||||
bt('//case 1\nif (a == 1){}\n//case 2\nelse if (a == 2){}', '//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}');
|
||||
bt('if(1){2}else{3}', 'if (1) {\n 2\n} else {\n 3\n}');
|
||||
bt('try{a();}catch(b){c();}catch(d){}finally{e();}', 'try {\n a();\n} catch (b) {\n c();\n} catch (d) {} finally {\n e();\n}');
|
||||
|
||||
// Brace style permutations - (ibo = "\n", iao = "\n", ibc = "\n", iac = "\n", obo = " ", oao = "\n ", obc = "\n", oac = " ")
|
||||
opts.brace_style = 'collapse';
|
||||
bt('var a =\n{\na: 2\n}\n;\nvar a =\n{\na: 2\n}\n;', 'var a = {\n a: 2\n};\nvar a = {\n a: 2\n};');
|
||||
bt('//case 1\nif (a == 1)\n{}\n//case 2\nelse if (a == 2)\n{}', '//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}');
|
||||
bt('if(1)\n{\n2\n}\nelse\n{\n3\n}', 'if (1) {\n 2\n} else {\n 3\n}');
|
||||
bt('try\n{\na();\n}\ncatch(b)\n{\nc();\n}\ncatch(d)\n{}\nfinally\n{\ne();\n}', 'try {\n a();\n} catch (b) {\n c();\n} catch (d) {} finally {\n e();\n}');
|
||||
|
||||
|
||||
// Comma-first option - (c0 = "\n, ", c1 = "\n , ", c2 = "\n , ", c3 = "\n , ")
|
||||
opts.comma_first = true;
|
||||
bt('{a:1, b:2}', '{\n a: 1\n , b: 2\n}');
|
||||
@ -1390,7 +1419,50 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify,
|
||||
|
||||
|
||||
|
||||
// Destructured and related
|
||||
opts.brace_style = 'collapse-preserve-inline';
|
||||
|
||||
// Issue 382 - import destructured
|
||||
bt(
|
||||
'module "Even" {\n' +
|
||||
' import { odd, oddly } from "Odd";\n' +
|
||||
'}');
|
||||
|
||||
// Issue 511 - destrutured
|
||||
bt(
|
||||
'var { b, c } = require("../stores");\n' +
|
||||
'var { ProjectStore } = require("../stores");\n' +
|
||||
'\n' +
|
||||
'function takeThing({ prop }) {\n' +
|
||||
' console.log("inner prop", prop)\n' +
|
||||
'}');
|
||||
|
||||
// Issue 315 - Short objects
|
||||
bt(
|
||||
'var a = { b: { c: { d: e } } };');
|
||||
bt(
|
||||
'var a = {\n' +
|
||||
' b: {\n' +
|
||||
' c: { d: e }\n' +
|
||||
' c3: { d: e }\n' +
|
||||
' },\n' +
|
||||
' b2: { c: { d: e } }\n' +
|
||||
'};');
|
||||
|
||||
// Issue 370 - Short objects in array
|
||||
bt(
|
||||
'var methods = [\n' +
|
||||
' { name: "to" },\n' +
|
||||
' { name: "step" },\n' +
|
||||
' { name: "move" },\n' +
|
||||
' { name: "min" },\n' +
|
||||
' { name: "max" }\n' +
|
||||
'];');
|
||||
|
||||
|
||||
|
||||
// Old tests
|
||||
opts.brace_style = 'collapse';
|
||||
bt('');
|
||||
test_fragment(' return .5');
|
||||
test_fragment(' return .5;\n a();');
|
||||
|
@ -128,6 +128,7 @@ class BeautifierFlags:
|
||||
self.declaration_statement = False
|
||||
self.declaration_assignment = False
|
||||
self.multiline_frame = False
|
||||
self.inline_frame = False
|
||||
self.if_block = False
|
||||
self.else_block = False
|
||||
self.do_block = False
|
||||
@ -230,6 +231,7 @@ class Token:
|
||||
self.wanted_newline = newlines > 0
|
||||
self.whitespace_before = whitespace_before
|
||||
self.parent = None
|
||||
self.opened = None
|
||||
self.directives = None
|
||||
|
||||
|
||||
@ -288,7 +290,7 @@ Output options:
|
||||
-E, --space-in-empty-paren Add a single space inside empty paren, ie. f( )
|
||||
-j, --jslint-happy More jslint-compatible output
|
||||
-a, --space_after_anon_function Add a space before an anonymous function's parens, ie. function ()
|
||||
-b, --brace-style=collapse Brace style (collapse, expand, end-expand)
|
||||
-b, --brace-style=collapse Brace style (collapse-preserve-inline, collapse, expand, end-expand)
|
||||
-k, --keep-array-indentation Keep array indentation.
|
||||
-r, --replace Write output in-place, replacing input
|
||||
-o, --outfile=FILE Specify a file to output to (default stdout)
|
||||
@ -381,8 +383,8 @@ class Beautifier:
|
||||
if opts != None:
|
||||
self.opts = copy.copy(opts)
|
||||
|
||||
if self.opts.brace_style not in ['expand', 'collapse', 'end-expand', 'none']:
|
||||
raise(Exception('opts.brace_style must be "expand", "collapse", "end-expand", or "none".'))
|
||||
if self.opts.brace_style not in ['expand', 'collapse', 'collapse-preserve-inline', 'end-expand', 'none']:
|
||||
raise(Exception('opts.brace_style must be "expand", "collapse", "collapse-preserve-inline", "end-expand", or "none".'))
|
||||
|
||||
s = self.blank_state(s)
|
||||
|
||||
@ -738,9 +740,11 @@ class Beautifier:
|
||||
else:
|
||||
self.set_mode(MODE.BlockStatement)
|
||||
elif self.last_type in ['TK_EQUALS', 'TK_START_EXPR', 'TK_COMMA', 'TK_OPERATOR'] or \
|
||||
(self.last_type == 'TK_RESERVED' and self.flags.last_text in ['return', 'throw']):
|
||||
# Detecting shorthand function syntax is difficult by scanning forward, so check the surrounding context.
|
||||
# If the block is being returned, passed as arg, assigned with = or assigned in a nested object, treat as an ObjectLiteral.
|
||||
(self.last_type == 'TK_RESERVED' and self.flags.last_text in ['return', 'throw', 'import']):
|
||||
# Detecting shorthand function syntax is difficult by scanning forward,
|
||||
# so check the surrounding context.
|
||||
# If the block is being returned, imported, passed as arg,
|
||||
# assigned with = or assigned in a nested object, treat as an ObjectLiteral.
|
||||
self.set_mode(MODE.ObjectLiteral);
|
||||
else:
|
||||
self.set_mode(MODE.BlockStatement)
|
||||
@ -759,18 +763,40 @@ class Beautifier:
|
||||
else:
|
||||
self.print_newline(preserve_statement_flags = True)
|
||||
else: # collapse
|
||||
if self.last_type not in ['TK_OPERATOR', 'TK_START_EXPR']:
|
||||
if self.opts.brace_style == 'collapse-preserve-inline':
|
||||
# search forward for newline wanted inside this block
|
||||
index = 0
|
||||
check_token = None
|
||||
self.flags.inline_frame = True
|
||||
do_loop = True
|
||||
while (do_loop):
|
||||
index += 1
|
||||
check_token = self.get_token(index)
|
||||
if check_token.wanted_newline:
|
||||
self.flags.inline_frame = False
|
||||
|
||||
do_loop = (check_token.type != 'TK_EOF' and
|
||||
not (check_token.type == 'TK_END_BLOCK' and check_token.opened == current_token))
|
||||
|
||||
|
||||
|
||||
if self.is_array(self.previous_flags.mode) and (self.last_type == 'TK_START_EXPR' or self.last_type == 'TK_COMMA'):
|
||||
# if we're preserving inline,
|
||||
# allow newline between comma and next brace.
|
||||
if self.flags.inline_frame:
|
||||
self.allow_wrap_or_preserved_newline(current_token)
|
||||
self.flags.inline_frame = True
|
||||
self.previous_flags.multiline_frame = self.previous_flags.multiline_frame or self.flags.multiline_frame
|
||||
self.flags.multiline_frame = False
|
||||
else:
|
||||
self.output.space_before_token = self.last_type == 'TK_COMMA'
|
||||
|
||||
|
||||
elif self.last_type not in ['TK_OPERATOR', 'TK_START_EXPR']:
|
||||
if self.last_type == 'TK_START_BLOCK':
|
||||
self.print_newline()
|
||||
else:
|
||||
self.output.space_before_token = True
|
||||
else:
|
||||
# if TK_OPERATOR or TK_START_EXPR
|
||||
if self.is_array(self.previous_flags.mode) and self.flags.last_text == ',':
|
||||
if self.last_last_text == '}':
|
||||
self.output.space_before_token = True
|
||||
else:
|
||||
self.print_newline()
|
||||
|
||||
self.print_token(current_token)
|
||||
self.indent()
|
||||
@ -788,7 +814,9 @@ class Beautifier:
|
||||
else:
|
||||
# skip {}
|
||||
if not empty_braces:
|
||||
if self.is_array(self.flags.mode) and self.opts.keep_array_indentation:
|
||||
if self.flags.inline_frame:
|
||||
self.output.space_before_token = True
|
||||
elif self.is_array(self.flags.mode) and self.opts.keep_array_indentation:
|
||||
self.opts.keep_array_indentation = False
|
||||
self.print_newline()
|
||||
self.opts.keep_array_indentation = True
|
||||
@ -891,7 +919,7 @@ class Beautifier:
|
||||
prefix = 'NONE'
|
||||
|
||||
if self.last_type == 'TK_END_BLOCK':
|
||||
if not (current_token.type == 'TK_RESERVED' and current_token.text in ['else', 'catch', 'finally']):
|
||||
if not (current_token.type == 'TK_RESERVED' and current_token.text in ['else', 'catch', 'finally', 'from']):
|
||||
prefix = 'NEWLINE'
|
||||
else:
|
||||
if self.opts.brace_style in ['expand', 'end-expand'] or \
|
||||
@ -911,7 +939,10 @@ class Beautifier:
|
||||
(self.flags.last_text == '*' and self.last_last_text == 'function'):
|
||||
prefix = 'SPACE'
|
||||
elif self.last_type == 'TK_START_BLOCK':
|
||||
prefix = 'NEWLINE'
|
||||
if self.flags.inline_frame:
|
||||
prefix = 'SPACE'
|
||||
else:
|
||||
prefix = 'NEWLINE'
|
||||
elif self.last_type == 'TK_END_EXPR':
|
||||
self.output.space_before_token = True
|
||||
prefix = 'NEWLINE'
|
||||
@ -983,7 +1014,7 @@ class Beautifier:
|
||||
# The conditional starts the statement if appropriate.
|
||||
# One difference - strings want at least a space before
|
||||
self.output.space_before_token = True
|
||||
elif self.last_type == 'TK_RESERVED' or self.last_type == 'TK_WORD':
|
||||
elif self.last_type == 'TK_RESERVED' or self.last_type == 'TK_WORD' or self.flags.inline_frame:
|
||||
self.output.space_before_token = True
|
||||
elif self.last_type in ['TK_COMMA', 'TK_START_EXPR', 'TK_EQUALS', 'TK_OPERATOR']:
|
||||
if not self.start_of_object_property():
|
||||
@ -1028,17 +1059,17 @@ class Beautifier:
|
||||
return
|
||||
|
||||
self.print_token(current_token)
|
||||
self.output.space_before_token = True
|
||||
|
||||
if self.flags.mode == MODE.ObjectLiteral \
|
||||
or (self.flags.mode == MODE.Statement and self.flags.parent.mode == MODE.ObjectLiteral):
|
||||
if self.flags.mode == MODE.Statement:
|
||||
self.restore_mode()
|
||||
|
||||
self.print_newline()
|
||||
if not self.flags.inline_frame:
|
||||
self.print_newline()
|
||||
else:
|
||||
# EXPR or DO_BLOCK
|
||||
self.output.space_before_token = True
|
||||
|
||||
# for comma-first, we want to allow a newline before the comma
|
||||
# to turn into a newline after the comma, which we will fixup later
|
||||
if self.opts.comma_first:
|
||||
@ -1115,7 +1146,8 @@ class Beautifier:
|
||||
if current_token.text in ['-', '+'] and self.flags.last_text in ['--', '++']:
|
||||
space_after = True
|
||||
|
||||
if self.flags.mode == MODE.BlockStatement and self.flags.last_text in ['{', ';']:
|
||||
if (((self.flags.mode == MODE.BlockStatement and not self.flags.inline_frame) or self.flags.mode == MODE.Statement)
|
||||
and self.flags.last_text in ['{', ';']):
|
||||
# { foo: --i }
|
||||
# foo(): --bar
|
||||
self.print_newline()
|
||||
@ -1423,7 +1455,7 @@ class Tokenizer:
|
||||
|
||||
# Words which always should start on a new line
|
||||
line_starters = 'continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export'.split(',')
|
||||
reserved_words = line_starters + ['do', 'in', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await']
|
||||
reserved_words = line_starters + ['do', 'in', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from']
|
||||
|
||||
def __init__ (self, input, opts, indent_string):
|
||||
self.input = input
|
||||
@ -1479,6 +1511,7 @@ class Tokenizer:
|
||||
(next.text == ')' and open.text == '(') or \
|
||||
(next.text == '}' and open.text == '{'))):
|
||||
next.parent = open.parent
|
||||
next.opened = open
|
||||
open = open_stack.pop()
|
||||
|
||||
self.tokens.append(next)
|
||||
|
@ -93,6 +93,34 @@ class TestJSBeautifier(unittest.TestCase):
|
||||
test_fragment(' \n\nreturn .5\n\n\n\n', ' return .5')
|
||||
test_fragment('\n', '')
|
||||
|
||||
# Brace style permutations - (ibo = "", iao = "", ibc = "", iac = "", obo = " ", oao = " ", obc = " ", oac = " ")
|
||||
self.options.brace_style = 'collapse-preserve-inline'
|
||||
bt('var a ={a: 2};\nvar a ={a: 2};', 'var a = { a: 2 };\nvar a = { a: 2 };')
|
||||
bt('//case 1\nif (a == 1){}\n//case 2\nelse if (a == 2){}', '//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}')
|
||||
bt('if(1){2}else{3}', 'if (1) { 2 } else { 3 }')
|
||||
bt('try{a();}catch(b){c();}catch(d){}finally{e();}', 'try { a(); } catch (b) { c(); } catch (d) {} finally { e(); }')
|
||||
|
||||
# Brace style permutations - (ibo = "\n", iao = "\n", ibc = "\n", iac = "\n", obo = " ", oao = "\n ", obc = "\n", oac = " ")
|
||||
self.options.brace_style = 'collapse-preserve-inline'
|
||||
bt('var a =\n{\na: 2\n}\n;\nvar a =\n{\na: 2\n}\n;', 'var a = {\n a: 2\n};\nvar a = {\n a: 2\n};')
|
||||
bt('//case 1\nif (a == 1)\n{}\n//case 2\nelse if (a == 2)\n{}', '//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}')
|
||||
bt('if(1)\n{\n2\n}\nelse\n{\n3\n}', 'if (1) {\n 2\n} else {\n 3\n}')
|
||||
bt('try\n{\na();\n}\ncatch(b)\n{\nc();\n}\ncatch(d)\n{}\nfinally\n{\ne();\n}', 'try {\n a();\n} catch (b) {\n c();\n} catch (d) {} finally {\n e();\n}')
|
||||
|
||||
# Brace style permutations - (ibo = "", iao = "", ibc = "", iac = "", obo = " ", oao = "\n ", obc = "\n", oac = " ")
|
||||
self.options.brace_style = 'collapse'
|
||||
bt('var a ={a: 2};\nvar a ={a: 2};', 'var a = {\n a: 2\n};\nvar a = {\n a: 2\n};')
|
||||
bt('//case 1\nif (a == 1){}\n//case 2\nelse if (a == 2){}', '//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}')
|
||||
bt('if(1){2}else{3}', 'if (1) {\n 2\n} else {\n 3\n}')
|
||||
bt('try{a();}catch(b){c();}catch(d){}finally{e();}', 'try {\n a();\n} catch (b) {\n c();\n} catch (d) {} finally {\n e();\n}')
|
||||
|
||||
# Brace style permutations - (ibo = "\n", iao = "\n", ibc = "\n", iac = "\n", obo = " ", oao = "\n ", obc = "\n", oac = " ")
|
||||
self.options.brace_style = 'collapse'
|
||||
bt('var a =\n{\na: 2\n}\n;\nvar a =\n{\na: 2\n}\n;', 'var a = {\n a: 2\n};\nvar a = {\n a: 2\n};')
|
||||
bt('//case 1\nif (a == 1)\n{}\n//case 2\nelse if (a == 2)\n{}', '//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}')
|
||||
bt('if(1)\n{\n2\n}\nelse\n{\n3\n}', 'if (1) {\n 2\n} else {\n 3\n}')
|
||||
bt('try\n{\na();\n}\ncatch(b)\n{\nc();\n}\ncatch(d)\n{}\nfinally\n{\ne();\n}', 'try {\n a();\n} catch (b) {\n c();\n} catch (d) {} finally {\n e();\n}')
|
||||
|
||||
# Comma-first option - (c0 = "\n, ", c1 = "\n , ", c2 = "\n , ", c3 = "\n , ")
|
||||
self.options.comma_first = true
|
||||
bt('{a:1, b:2}', '{\n a: 1\n , b: 2\n}')
|
||||
@ -1164,7 +1192,48 @@ class TestJSBeautifier(unittest.TestCase):
|
||||
' }\n' +
|
||||
'}.fn2()')
|
||||
|
||||
# Destructured and related
|
||||
self.options.brace_style = 'collapse-preserve-inline'
|
||||
|
||||
# Issue 382 - import destructured
|
||||
bt(
|
||||
'module "Even" {\n' +
|
||||
' import { odd, oddly } from "Odd";\n' +
|
||||
'}')
|
||||
|
||||
# Issue 511 - destrutured
|
||||
bt(
|
||||
'var { b, c } = require("../stores");\n' +
|
||||
'var { ProjectStore } = require("../stores");\n' +
|
||||
'\n' +
|
||||
'function takeThing({ prop }) {\n' +
|
||||
' console.log("inner prop", prop)\n' +
|
||||
'}')
|
||||
|
||||
# Issue 315 - Short objects
|
||||
bt(
|
||||
'var a = { b: { c: { d: e } } };')
|
||||
bt(
|
||||
'var a = {\n' +
|
||||
' b: {\n' +
|
||||
' c: { d: e }\n' +
|
||||
' c3: { d: e }\n' +
|
||||
' },\n' +
|
||||
' b2: { c: { d: e } }\n' +
|
||||
'};')
|
||||
|
||||
# Issue 370 - Short objects in array
|
||||
bt(
|
||||
'var methods = [\n' +
|
||||
' { name: "to" },\n' +
|
||||
' { name: "step" },\n' +
|
||||
' { name: "move" },\n' +
|
||||
' { name: "min" },\n' +
|
||||
' { name: "max" }\n' +
|
||||
'];')
|
||||
|
||||
# Old tests
|
||||
self.options.brace_style = 'collapse'
|
||||
bt('')
|
||||
test_fragment(' return .5')
|
||||
test_fragment(' return .5;\n a();')
|
||||
|
@ -63,6 +63,98 @@ exports.test_data = {
|
||||
{ fragment: true, input: ' \n\nreturn .5\n\n\n\n', output: ' return .5{{eof}}' },
|
||||
{ fragment: true, input: '\n', output: '{{eof}}' }
|
||||
],
|
||||
}, {
|
||||
name: "Brace style permutations",
|
||||
description: "",
|
||||
template: "< >",
|
||||
matrix: [
|
||||
// collapse-preserve-inline variations
|
||||
{
|
||||
options: [
|
||||
{ name: "brace_style", value: "'collapse-preserve-inline'" }
|
||||
],
|
||||
ibo: '',
|
||||
iao: '',
|
||||
ibc: '',
|
||||
iac: '',
|
||||
obo: ' ',
|
||||
oao: ' ',
|
||||
obc: ' ',
|
||||
oac: ' '
|
||||
},
|
||||
{
|
||||
options: [
|
||||
{ name: "brace_style", value: "'collapse-preserve-inline'" }
|
||||
],
|
||||
ibo: '\\n',
|
||||
iao: '\\n',
|
||||
ibc: '\\n',
|
||||
iac: '\\n',
|
||||
obo: ' ',
|
||||
oao: '\\n ',
|
||||
obc: '\\n',
|
||||
oac: ' '
|
||||
},
|
||||
|
||||
// collapse variations
|
||||
{
|
||||
options: [
|
||||
{ name: "brace_style", value: "'collapse'" }
|
||||
],
|
||||
ibo: '',
|
||||
iao: '',
|
||||
ibc: '',
|
||||
iac: '',
|
||||
obo: ' ',
|
||||
oao: '\\n ',
|
||||
obc: '\\n',
|
||||
oac: ' '
|
||||
},
|
||||
{
|
||||
options: [
|
||||
{ name: "brace_style", value: "'collapse'" }
|
||||
],
|
||||
ibo: '\\n',
|
||||
iao: '\\n',
|
||||
ibc: '\\n',
|
||||
iac: '\\n',
|
||||
obo: ' ',
|
||||
oao: '\\n ',
|
||||
obc: '\\n',
|
||||
oac: ' '
|
||||
},
|
||||
],
|
||||
tests: [
|
||||
{
|
||||
input: 'var a =<ibo>{<iao>a: 2<ibc>}<iac>;\nvar a =<ibo>{<iao>a: 2<ibc>}<iac>;',
|
||||
output: 'var a =<obo>{<oao>a: 2<obc>};\nvar a =<obo>{<oao>a: 2<obc>};'
|
||||
},
|
||||
// {
|
||||
// input: 'var a =<ibo>{<iao>a:<ibo>{<iao>a:<ibo>{<iao>a:2<ibc>}<iac><ibc>}<iac>}<iac>;\nvar a =<ibo>{<iao>a:<ibo>{<iao>a:<ibo>{<iao>a:2<ibc>}<iac><ibc>}<iac>}<iac>;',
|
||||
// output: 'var a =<obo>{<oao>a:<obo>{<oao>a:<obo>{<oao>a: 2<obc>}<oac><obc>}<oac><obc>};\nvar a =<obo>{<oao>a:<obo>{<oao>a:<obo>{<oao>a: 2<obc>}<oac><obc>}<oac><obc>};'
|
||||
// },
|
||||
{
|
||||
input: '//case 1\nif (a == 1)<ibo>{}\n//case 2\nelse if (a == 2)<ibo>{}',
|
||||
output: '//case 1\nif (a == 1)<obo>{}\n//case 2\nelse if (a == 2)<obo>{}'
|
||||
},
|
||||
{
|
||||
input: 'if(1)<ibo>{<iao>2<ibc>}<iac>else<ibo>{<iao>3<ibc>}',
|
||||
output: 'if (1)<obo>{<oao>2<obc>}<oac>else<obo>{<oao>3<obc>}'
|
||||
},
|
||||
{
|
||||
input:
|
||||
'try<ibo>{<iao>a();<ibc>}<iac>' +
|
||||
'catch(b)<ibo>{<iao>c();<ibc>}<iac>' +
|
||||
'catch(d)<ibo>{}<iac>' +
|
||||
'finally<ibo>{<iao>e();<ibc>}',
|
||||
output:
|
||||
// expected
|
||||
'try<obo>{<oao>a();<obc>}<oac>' +
|
||||
'catch (b)<obo>{<oao>c();<obc>}<oac>' +
|
||||
'catch (d)<obo>{}<oac>'+
|
||||
'finally<obo>{<oao>e();<obc>}'
|
||||
}
|
||||
],
|
||||
}, {
|
||||
name: "Comma-first option",
|
||||
description: "Put commas at the start of lines instead of the end",
|
||||
@ -1330,6 +1422,72 @@ exports.test_data = {
|
||||
]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
name: "Destructured and related",
|
||||
description: "Ensure specific bugs do not recur",
|
||||
options: [{ name: "brace_style", value: "'collapse-preserve-inline'" }],
|
||||
tests: [
|
||||
{
|
||||
comment: "Issue 382 - import destructured ",
|
||||
unchanged: [
|
||||
'module "Even" {',
|
||||
' import { odd, oddly } from "Odd";',
|
||||
'}' ]
|
||||
},
|
||||
{
|
||||
comment: "Issue 511 - destrutured ",
|
||||
unchanged: [
|
||||
'var { b, c } = require("../stores");',
|
||||
'var { ProjectStore } = require("../stores");',
|
||||
'',
|
||||
'function takeThing({ prop }) {',
|
||||
' console.log("inner prop", prop)',
|
||||
'}'
|
||||
]
|
||||
},
|
||||
{
|
||||
comment: "Issue 315 - Short objects ",
|
||||
unchanged: [
|
||||
'var a = { b: { c: { d: e } } };'
|
||||
]
|
||||
},
|
||||
{
|
||||
unchanged: [
|
||||
'var a = {',
|
||||
' b: {',
|
||||
' c: { d: e }',
|
||||
' c3: { d: e }',
|
||||
' },',
|
||||
' b2: { c: { d: e } }',
|
||||
'};'
|
||||
]
|
||||
},
|
||||
{
|
||||
comment: "Issue 370 - Short objects in array",
|
||||
unchanged: [
|
||||
'var methods = [',
|
||||
' { name: "to" },',
|
||||
' { name: "step" },',
|
||||
' { name: "move" },',
|
||||
' { name: "min" },',
|
||||
' { name: "max" }',
|
||||
'];'
|
||||
]
|
||||
},
|
||||
// {
|
||||
// comment: "Issue #338 - Short expressions ",
|
||||
// unchanged: [
|
||||
// 'if(someCondition) { return something; }',
|
||||
// 'if(someCondition) {',
|
||||
// ' return something;',
|
||||
// '}',
|
||||
// 'if(someCondition) { return something; }',
|
||||
// 'if(someCondition) {',
|
||||
// ' return something;',
|
||||
// '}'
|
||||
// ]
|
||||
// },
|
||||
]
|
||||
},
|
||||
|
||||
// =======================================================
|
||||
@ -1340,7 +1498,7 @@ exports.test_data = {
|
||||
{
|
||||
name: "Old tests",
|
||||
description: "Largely unorganized pile of tests",
|
||||
options: [],
|
||||
options: [{ name: "brace_style", value: "'collapse'" }],
|
||||
tests: [
|
||||
{ unchanged: '' },
|
||||
{ fragment: true, unchanged: ' return .5'},
|
||||
|
Loading…
Reference in New Issue
Block a user