prettier 0.20.0 → 1.0.0.pre.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +118 -4
  3. data/CONTRIBUTING.md +8 -6
  4. data/README.md +67 -60
  5. data/node_modules/prettier/bin-prettier.js +12317 -50112
  6. data/node_modules/prettier/index.js +33352 -27419
  7. data/node_modules/prettier/third-party.js +5678 -7676
  8. data/package.json +4 -4
  9. data/src/embed.js +27 -8
  10. data/src/nodes.js +6 -2
  11. data/src/nodes/alias.js +65 -24
  12. data/src/nodes/aref.js +55 -0
  13. data/src/nodes/args.js +55 -47
  14. data/src/nodes/arrays.js +150 -137
  15. data/src/nodes/assign.js +32 -32
  16. data/src/nodes/blocks.js +8 -3
  17. data/src/nodes/calls.js +129 -70
  18. data/src/nodes/case.js +11 -7
  19. data/src/nodes/class.js +74 -0
  20. data/src/nodes/commands.js +36 -31
  21. data/src/nodes/conditionals.js +48 -46
  22. data/src/nodes/constants.js +39 -21
  23. data/src/nodes/flow.js +45 -17
  24. data/src/nodes/hashes.js +126 -112
  25. data/src/nodes/heredocs.js +34 -0
  26. data/src/nodes/hooks.js +36 -7
  27. data/src/nodes/ints.js +27 -20
  28. data/src/nodes/lambdas.js +69 -52
  29. data/src/nodes/loops.js +19 -29
  30. data/src/nodes/massign.js +87 -65
  31. data/src/nodes/methods.js +48 -73
  32. data/src/nodes/operators.js +70 -39
  33. data/src/nodes/params.js +26 -16
  34. data/src/nodes/patterns.js +108 -33
  35. data/src/nodes/regexp.js +38 -14
  36. data/src/nodes/rescue.js +72 -59
  37. data/src/nodes/statements.js +86 -44
  38. data/src/nodes/strings.js +94 -90
  39. data/src/nodes/super.js +35 -0
  40. data/src/nodes/undef.js +42 -0
  41. data/src/parser.js +71 -0
  42. data/src/parser.rb +2554 -0
  43. data/src/printer.js +90 -0
  44. data/src/ruby.js +20 -61
  45. data/src/toProc.js +4 -4
  46. data/src/utils.js +24 -88
  47. data/src/utils/inlineEnsureParens.js +42 -0
  48. data/src/utils/isEmptyStmts.js +7 -0
  49. data/src/utils/literalLineNoBreak.js +7 -0
  50. metadata +15 -20
  51. data/src/haml.js +0 -21
  52. data/src/haml/embed.js +0 -58
  53. data/src/haml/nodes/comment.js +0 -27
  54. data/src/haml/nodes/doctype.js +0 -32
  55. data/src/haml/nodes/filter.js +0 -16
  56. data/src/haml/nodes/hamlComment.js +0 -21
  57. data/src/haml/nodes/script.js +0 -29
  58. data/src/haml/nodes/silentScript.js +0 -59
  59. data/src/haml/nodes/tag.js +0 -157
  60. data/src/haml/parse.js +0 -18
  61. data/src/haml/parse.rb +0 -64
  62. data/src/haml/print.js +0 -38
  63. data/src/nodes/scopes.js +0 -61
  64. data/src/parse.js +0 -37
  65. data/src/print.js +0 -23
  66. data/src/ripper.rb +0 -811
@@ -1,80 +1,55 @@
1
- const {
2
- align,
3
- concat,
4
- group,
5
- hardline,
6
- indent,
7
- join,
8
- line
9
- } = require("../prettier");
10
- const { first, literal } = require("../utils");
11
-
12
- const printMethod = (offset) => (path, opts, print) => {
13
- const [_name, params, body] = path.getValue().body.slice(offset);
14
- const declaration = ["def "];
15
-
16
- // In this case, we're printing a method that's defined as a singleton, so we
17
- // need to include the target and the operator
18
- if (offset > 0) {
19
- declaration.push(path.call(print, "body", 0), path.call(print, "body", 1));
20
- }
21
-
22
- // In case there are no parens but there are arguments
23
- const parens =
24
- params.type === "params" && params.body.some((paramType) => paramType);
25
-
26
- declaration.push(
27
- path.call(print, "body", offset),
28
- parens ? "(" : "",
29
- path.call(print, "body", offset + 1),
30
- parens ? ")" : ""
31
- );
1
+ const { concat, group, hardline, indent } = require("../prettier");
2
+ const { first } = require("../utils");
3
+
4
+ function printMethod(offset) {
5
+ return function printMethodWithOffset(path, opts, print) {
6
+ const [_name, params, body] = path.getValue().body.slice(offset);
7
+ const declaration = ["def "];
8
+
9
+ // In this case, we're printing a method that's defined as a singleton, so
10
+ // we need to include the target and the operator
11
+ if (offset > 0) {
12
+ declaration.push(
13
+ path.call(print, "body", 0),
14
+ path.call(print, "body", 1)
15
+ );
16
+ }
32
17
 
33
- // If the body is empty, we can replace with a ;
34
- const stmts = body.body[0].body;
35
- if (stmts.length === 1 && stmts[0].type === "void_stmt") {
36
- return group(concat(declaration.concat(["; end"])));
37
- }
18
+ // In case there are no parens but there are arguments
19
+ const parens =
20
+ params.type === "params" && params.body.some((paramType) => paramType);
21
+
22
+ declaration.push(
23
+ path.call(print, "body", offset),
24
+ parens ? "(" : "",
25
+ path.call(print, "body", offset + 1),
26
+ parens ? ")" : ""
27
+ );
28
+
29
+ // If the body is empty, we can replace with a ;
30
+ const stmts = body.body[0].body;
31
+
32
+ if (
33
+ !body.body.slice(1).some((node) => node) &&
34
+ stmts.length === 1 &&
35
+ stmts[0].type === "void_stmt" &&
36
+ !stmts[0].comments
37
+ ) {
38
+ return group(concat(declaration.concat(["; end"])));
39
+ }
38
40
 
39
- return group(
40
- concat([
41
- group(concat(declaration)),
42
- indent(concat([hardline, path.call(print, "body", offset + 2)])),
43
- group(concat([hardline, "end"]))
44
- ])
45
- );
46
- };
41
+ return group(
42
+ concat([
43
+ group(concat(declaration)),
44
+ indent(concat([hardline, path.call(print, "body", offset + 2)])),
45
+ group(concat([hardline, "end"]))
46
+ ])
47
+ );
48
+ };
49
+ }
47
50
 
48
51
  module.exports = {
49
52
  access_ctrl: first,
50
53
  def: printMethod(0),
51
- defs: printMethod(2),
52
- methref: (path, opts, print) => join(".:", path.map(print, "body")),
53
- super: (path, opts, print) => {
54
- const args = path.getValue().body[0];
55
-
56
- if (args.type === "arg_paren") {
57
- // In case there are explicitly no arguments but they are using parens,
58
- // we assume they are attempting to override the initializer and pass no
59
- // arguments up.
60
- if (args.body[0] === null) {
61
- return "super()";
62
- }
63
-
64
- return concat(["super", path.call(print, "body", 0)]);
65
- }
66
-
67
- return concat(["super ", join(", ", path.call(print, "body", 0))]);
68
- },
69
- undef: (path, opts, print) =>
70
- group(
71
- concat([
72
- "undef ",
73
- align(
74
- "undef ".length,
75
- join(concat([",", line]), path.map(print, "body", 0))
76
- )
77
- ])
78
- ),
79
- zsuper: literal("super")
54
+ defs: printMethod(2)
80
55
  };
@@ -1,52 +1,83 @@
1
1
  const { concat, group, indent, line, softline } = require("../prettier");
2
+ const { noIndent } = require("../utils");
2
3
 
3
- module.exports = {
4
- binary: (path, opts, print) => {
5
- const operator = path.getValue().body[1];
6
- const useNoSpace = operator === "**";
4
+ function printBinary(path, opts, print) {
5
+ const [_leftNode, operator, rightNode] = path.getValue().body;
6
+ const space = operator === "**" ? "" : " ";
7
7
 
8
+ if (noIndent.includes(rightNode.type)) {
8
9
  return group(
9
10
  concat([
10
11
  group(path.call(print, "body", 0)),
12
+ space,
13
+ operator,
14
+ space,
15
+ group(path.call(print, "body", 2))
16
+ ])
17
+ );
18
+ }
19
+
20
+ return group(
21
+ concat([
22
+ group(path.call(print, "body", 0)),
23
+ space,
24
+ group(
11
25
  indent(
12
26
  concat([
13
- useNoSpace ? "" : " ",
14
- group(
15
- concat([
16
- operator,
17
- useNoSpace ? softline : line,
18
- path.call(print, "body", 2)
19
- ])
20
- )
27
+ operator,
28
+ space === "" ? softline : line,
29
+ path.call(print, "body", 2)
21
30
  ])
22
31
  )
23
- ])
24
- );
25
- },
26
- dot2: (path, opts, print) =>
27
- concat([
28
- path.call(print, "body", 0),
29
- "..",
30
- path.getValue().body[1] ? path.call(print, "body", 1) : ""
31
- ]),
32
- dot3: (path, opts, print) =>
33
- concat([
34
- path.call(print, "body", 0),
35
- "...",
36
- path.getValue().body[1] ? path.call(print, "body", 1) : ""
37
- ]),
38
- unary: (path, opts, print) => {
39
- const oper = path.getValue().body[0];
40
- const doc = path.call(print, "body", 1);
41
-
42
- if (oper === "not") {
43
- // For the `not` operator, we're explicitly making the space character
44
- // another element in the `concat` because there are some circumstances
45
- // where we need to force parentheses (e.g., ternaries). In that case the
46
- // printer for those nodes can just take out the space and put in parens.
47
- return concat(["not", " ", doc]);
48
- }
32
+ )
33
+ ])
34
+ );
35
+ }
36
+
37
+ // dot2 nodes are used with ranges (or flip-flops). They can optionally drop
38
+ // their left side for beginless ranges or their right side for endless ranges.
39
+ function printDot2(path, opts, print) {
40
+ const [leftNode, rightNode] = path.getValue().body;
41
+
42
+ return concat([
43
+ leftNode ? path.call(print, "body", 0) : "",
44
+ "..",
45
+ rightNode ? path.call(print, "body", 1) : ""
46
+ ]);
47
+ }
48
+
49
+ // dot3 nodes are used with ranges (or flip-flops). They can optionally drop
50
+ // their left side for beginless ranges or their right side for endless ranges.
51
+ function printDot3(path, opts, print) {
52
+ const [leftNode, rightNode] = path.getValue().body;
53
+
54
+ return concat([
55
+ leftNode ? path.call(print, "body", 0) : "",
56
+ "...",
57
+ rightNode ? path.call(print, "body", 1) : ""
58
+ ]);
59
+ }
49
60
 
50
- return concat([oper[0], doc]);
61
+ function printUnary(path, opts, print) {
62
+ const node = path.getValue();
63
+ const contentsDoc = path.call(print, "body", 0);
64
+
65
+ if (node.oper === "not") {
66
+ // Here we defer to the original source, as it's kind of difficult to
67
+ // determine if we can actually remove the parentheses being used.
68
+ if (node.paren) {
69
+ return concat(["not", "(", contentsDoc, ")"]);
70
+ } else {
71
+ return concat(["not", " ", contentsDoc]);
72
+ }
51
73
  }
74
+
75
+ return concat([node.oper, contentsDoc]);
76
+ }
77
+
78
+ module.exports = {
79
+ binary: printBinary,
80
+ dot2: printDot2,
81
+ dot3: printDot3,
82
+ unary: printUnary
52
83
  };
@@ -1,12 +1,15 @@
1
- const { concat, group, join, line } = require("../prettier");
1
+ const { concat, group, join, indent, line, softline } = require("../prettier");
2
2
  const { literal } = require("../utils");
3
3
 
4
- const printGenericRestParam = (symbol) => (path, opts, print) =>
5
- path.getValue().body[0]
6
- ? concat([symbol, path.call(print, "body", 0)])
7
- : symbol;
4
+ function printRestParam(symbol) {
5
+ return function printRestParamWithSymbol(path, opts, print) {
6
+ return path.getValue().body[0]
7
+ ? concat([symbol, path.call(print, "body", 0)])
8
+ : symbol;
9
+ };
10
+ }
8
11
 
9
- const printParams = (path, opts, print) => {
12
+ function printParams(path, opts, print) {
10
13
  const [
11
14
  reqs,
12
15
  optls,
@@ -61,6 +64,8 @@ const printParams = (path, opts, print) => {
61
64
  parts.push(path.call(print, "body", 6));
62
65
  }
63
66
 
67
+ const contents = [join(concat([",", line]), parts)];
68
+
64
69
  // You can put an extra comma at the end of block args between pipes to
65
70
  // change what it does. Below is the difference:
66
71
  //
@@ -70,19 +75,24 @@ const printParams = (path, opts, print) => {
70
75
  // In ruby 2.5, the excessed comma is indicated by having a 0 in the rest
71
76
  // param position. In ruby 2.6+ it's indicated by having an "excessed_comma"
72
77
  // node in the rest position. Seems odd, but it's true.
73
- const comma = rest === 0 || (rest && rest.type === "excessed_comma");
78
+ if (rest === 0 || (rest && rest.type === "excessed_comma")) {
79
+ contents.push(",");
80
+ }
74
81
 
75
- return group(concat([join(concat([",", line]), parts), comma ? "," : ""]));
76
- };
82
+ // If the parent node is a paren then we skipped printing the parentheses so
83
+ // that we could handle them here and get nicer formatting.
84
+ if (["lambda", "paren"].includes(path.getParentNode().type)) {
85
+ return group(
86
+ concat(["(", indent(concat([softline].concat(contents))), softline, ")"])
87
+ );
88
+ }
77
89
 
78
- const paramError = () => {
79
- throw new Error("formal argument cannot be a global variable");
80
- };
90
+ return group(concat(contents));
91
+ }
81
92
 
82
93
  module.exports = {
83
94
  args_forward: literal("..."),
84
- kwrest_param: printGenericRestParam("**"),
85
- rest_param: printGenericRestParam("*"),
86
- params: printParams,
87
- param_error: paramError
95
+ kwrest_param: printRestParam("**"),
96
+ rest_param: printRestParam("*"),
97
+ params: printParams
88
98
  };
@@ -1,43 +1,118 @@
1
1
  const { concat, group, hardline, indent, join, line } = require("../prettier");
2
2
 
3
- module.exports = {
4
- aryptn: (path, opts, print) => {
5
- const [constant, preargs, splatarg, postargs] = path.getValue().body;
6
- let args = [];
3
+ function printPatternArg(path, opts, print) {
4
+ // Pinning is a really special syntax in pattern matching that's not really
5
+ // all that well supported in ripper. Here we're just going to the original
6
+ // source to see if the variable is pinned.
7
+ if (
8
+ opts.originalText &&
9
+ opts.originalText[opts.locStart(path.getValue()) - 1] === "^"
10
+ ) {
11
+ return concat(["^", path.call(print)]);
12
+ }
7
13
 
8
- if (preargs) {
9
- args = args.concat(path.map(print, "body", 1));
10
- }
14
+ return path.call(print);
15
+ }
11
16
 
12
- if (splatarg) {
13
- args.push(concat(["*", path.call(print, "body", 2)]));
14
- }
17
+ function printAryPtn(path, opts, print) {
18
+ const [constant, preargs, splatarg, postargs] = path.getValue().body;
19
+ let args = [];
15
20
 
16
- if (postargs) {
17
- args = args.concat(path.map(print, "body", 3));
18
- }
21
+ if (preargs) {
22
+ args = args.concat(
23
+ path.map((argPath) => printPatternArg(argPath, opts, print), "body", 1)
24
+ );
25
+ }
19
26
 
20
- args = group(join(concat([",", line]), args));
27
+ if (splatarg) {
28
+ args.push(concat(["*", path.call(print, "body", 2)]));
29
+ }
21
30
 
22
- if (constant || path.getParentNode().type === "binary") {
23
- args = concat(["[", args, "]"]);
24
- }
31
+ if (postargs) {
32
+ args = args.concat(path.map(print, "body", 3));
33
+ }
25
34
 
26
- if (constant) {
27
- return concat([path.call(print, "body", 0), args]);
28
- }
35
+ args = group(join(concat([",", line]), args));
29
36
 
30
- return args;
31
- },
32
- hshptn: () => {
33
- throw new Error(
34
- "Hash pattern not currently supported (https://bugs.ruby-lang.org/issues/16008)"
35
- );
36
- },
37
- in: (path, opts, print) =>
38
- concat([
39
- "in ",
40
- path.call(print, "body", 0),
41
- indent(concat([hardline, path.call(print, "body", 1)]))
42
- ])
37
+ if (
38
+ constant ||
39
+ ["aryptn", "binary", "hshptn"].includes(path.getParentNode().type)
40
+ ) {
41
+ args = concat(["[", args, "]"]);
42
+ }
43
+
44
+ if (constant) {
45
+ return concat([path.call(print, "body", 0), args]);
46
+ }
47
+
48
+ return args;
49
+ }
50
+
51
+ function printHshPtn(path, opts, print) {
52
+ const [constant, keyValuePairs, keyValueRest] = path.getValue().body;
53
+ let args = [];
54
+
55
+ if (keyValuePairs) {
56
+ const printPair = (pairPath) => {
57
+ const parts = [pairPath.call(print, 0)];
58
+
59
+ if (pairPath.getValue()[1]) {
60
+ parts.push(
61
+ " ",
62
+ pairPath.call(
63
+ (pairValuePath) => printPatternArg(pairValuePath, opts, print),
64
+ 1
65
+ )
66
+ );
67
+ }
68
+
69
+ return concat(parts);
70
+ };
71
+
72
+ args = args.concat(path.map(printPair, "body", 1));
73
+ }
74
+
75
+ if (keyValueRest) {
76
+ args.push(concat(["**", path.call(print, "body", 2)]));
77
+ }
78
+
79
+ args = group(join(concat([",", line]), args));
80
+
81
+ if (constant) {
82
+ args = concat(["[", args, "]"]);
83
+ } else if (
84
+ ["aryptn", "binary", "hshptn"].includes(path.getParentNode().type)
85
+ ) {
86
+ args = concat(["{", args, "}"]);
87
+ }
88
+
89
+ if (constant) {
90
+ return concat([path.call(print, "body", 0), args]);
91
+ }
92
+
93
+ return args;
94
+ }
95
+
96
+ function printIn(path, opts, print) {
97
+ const parts = [
98
+ "in ",
99
+ path.call(
100
+ (valuePath) => printPatternArg(valuePath, opts, print),
101
+ "body",
102
+ 0
103
+ ),
104
+ indent(concat([hardline, path.call(print, "body", 1)]))
105
+ ];
106
+
107
+ if (path.getValue().body[2]) {
108
+ parts.push(hardline, path.call(print, "body", 2));
109
+ }
110
+
111
+ return group(concat(parts));
112
+ }
113
+
114
+ module.exports = {
115
+ aryptn: printAryPtn,
116
+ hshptn: printHshPtn,
117
+ in: printIn
43
118
  };