prettier 0.20.0 → 1.0.0.pre.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -0,0 +1,90 @@
1
+ const { concat, trim } = require("./prettier");
2
+
3
+ const embed = require("./embed");
4
+ const nodes = require("./nodes");
5
+
6
+ // This is the generic node print function, used to convert any node in the AST
7
+ // into its equivalent Doc representation.
8
+ function printNode(path, opts, print) {
9
+ const { type, body } = path.getValue();
10
+
11
+ if (type in nodes) {
12
+ return nodes[type](path, opts, print);
13
+ }
14
+
15
+ if (type[0] === "@") {
16
+ return body;
17
+ }
18
+
19
+ const ast = JSON.stringify(body, null, 2);
20
+ throw new Error(`Unsupported node encountered: ${type}\n${ast}`);
21
+ }
22
+
23
+ const noComments = [
24
+ "args",
25
+ "args_add_block",
26
+ "args_add_star",
27
+ "mlhs",
28
+ "mlhs_add_post",
29
+ "mlhs_add_star"
30
+ ];
31
+
32
+ // Certain nodes are used more for organizational purposed than for actually
33
+ // displaying content, so we tell prettier that we don't want comments attached
34
+ // to them.
35
+ function canAttachComment(node) {
36
+ return !noComments.includes(node.type);
37
+ }
38
+
39
+ // This function tells prettier how to recurse down our AST so that it can find
40
+ // where it needs to attach the comments.
41
+ function getCommentChildNodes(node) {
42
+ switch (node.type) {
43
+ case "heredoc":
44
+ return [node.beging];
45
+ case "rescue":
46
+ return [].concat(node.body[0]).concat(node.body.slice(1));
47
+ case "aryptn":
48
+ return [node.body[0]]
49
+ .concat(node.body[1])
50
+ .concat(node.body[2])
51
+ .concat(node.body[3]);
52
+ case "hshptn": {
53
+ const pairs = node.body[1];
54
+ const values = pairs.reduce((left, right) => left.concat(right), []);
55
+
56
+ return [node.body[0]].concat(values).concat(node.body[2]);
57
+ }
58
+ default:
59
+ return node.body;
60
+ }
61
+ }
62
+
63
+ // This is the generic print function for any comment in the AST. It handles
64
+ // both regular comments that begin with a # and embdoc comments, which are
65
+ // surrounded by =begin..=end.
66
+ function printComment(path, _opts) {
67
+ const comment = path.getValue();
68
+
69
+ if (comment.type === "@comment") {
70
+ return `#${comment.value}`;
71
+ }
72
+
73
+ return concat([trim, comment.value]);
74
+ }
75
+
76
+ // To be honest I'm not 100% sure this function is actually necessary, but it
77
+ // *feels* like a block comment equivalent in JavaScript so I'm going to leave
78
+ // it in place for now.
79
+ function isBlockComment(comment) {
80
+ return comment.type === "@embdoc";
81
+ }
82
+
83
+ module.exports = {
84
+ embed,
85
+ print: printNode,
86
+ canAttachComment,
87
+ getCommentChildNodes,
88
+ printComment,
89
+ isBlockComment
90
+ };
@@ -1,14 +1,5 @@
1
- const embed = require("./embed");
2
- const parse = require("./parse");
3
- const print = require("./print");
4
-
5
- const haml = require("./haml");
6
-
7
- const pragmaPattern = /#\s*@(prettier|format)/;
8
- const hasPragma = (text) => pragmaPattern.test(text);
9
-
10
- const locStart = (node) => node.char_start;
11
- const locEnd = (node) => node.char_end;
1
+ const printer = require("./printer");
2
+ const parser = require("./parser");
12
3
 
13
4
  /*
14
5
  * metadata mostly pulled from linguist and rubocop:
@@ -76,86 +67,54 @@ module.exports = {
76
67
  interpreters: ["jruby", "macruby", "rake", "rbx", "ruby"],
77
68
  linguistLanguageId: 326,
78
69
  vscodeLanguageIds: ["ruby"]
79
- },
80
- {
81
- name: "HAML",
82
- parsers: ["haml"],
83
- extensions: [".haml"],
84
- vscodeLanguageIds: ["haml"]
85
70
  }
86
71
  ],
87
72
  parsers: {
88
- ruby: {
89
- parse,
90
- astFormat: "ruby",
91
- hasPragma,
92
- locStart,
93
- locEnd
94
- },
95
- haml: {
96
- parse: haml.parse,
97
- astFormat: "haml",
98
- hasPragma: haml.hasPragma,
99
- locStart: haml.locStart,
100
- locEnd: haml.locEnd
101
- }
73
+ ruby: parser
102
74
  },
103
75
  printers: {
104
- ruby: {
105
- embed,
106
- print
107
- },
108
- haml: {
109
- embed: haml.embed,
110
- print: haml.print
111
- }
76
+ ruby: printer
112
77
  },
113
78
  options: {
114
- addTrailingCommas: {
79
+ rubyArrayLiteral: {
115
80
  type: "boolean",
116
- category: "Global",
117
- default: false,
118
- description:
119
- "Adds a trailing comma to array literals, hash literals, and method calls."
120
- },
121
- inlineConditionals: {
122
- type: "boolean",
123
- category: "Global",
81
+ category: "Ruby",
124
82
  default: true,
125
83
  description:
126
- "When it fits on one line, allows if and unless statements to use the modifier form."
84
+ "When possible, favor the use of string and symbol array literals."
127
85
  },
128
- inlineLoops: {
86
+ rubyHashLabel: {
129
87
  type: "boolean",
130
- category: "Global",
88
+ category: "Ruby",
131
89
  default: true,
132
90
  description:
133
- "When it fits on one line, allows while and until statements to use the modifier form."
91
+ "When possible, uses the shortened hash key syntax, as opposed to hash rockets."
134
92
  },
135
- preferHashLabels: {
93
+ rubyModifier: {
136
94
  type: "boolean",
137
- category: "Global",
95
+ category: "Ruby",
138
96
  default: true,
139
97
  description:
140
- "When possible, uses the shortened hash key syntax, as opposed to hash rockets."
98
+ "When it fits on one line, allows if, unless, while, and until statements to use the modifier form."
141
99
  },
142
- preferSingleQuotes: {
100
+ rubySingleQuote: {
143
101
  type: "boolean",
144
- category: "Global",
102
+ category: "Ruby",
145
103
  default: true,
146
104
  description:
147
105
  "When double quotes are not necessary for interpolation, prefers the use of single quotes for string literals."
148
106
  },
149
- toProcTransform: {
107
+ rubyToProc: {
150
108
  type: "boolean",
151
- category: "Global",
152
- default: true,
109
+ category: "Ruby",
110
+ default: false,
153
111
  description:
154
112
  "When possible, convert blocks to the more concise Symbol#to_proc syntax."
155
113
  }
156
114
  },
157
115
  defaultOptions: {
158
116
  printWidth: 80,
159
- tabWidth: 2
117
+ tabWidth: 2,
118
+ trailingComma: "none"
160
119
  }
161
120
  };
@@ -11,8 +11,8 @@ const isCall = (node) => ["::", "."].includes(node) || node.type === "@period";
11
11
  // [1, 2, 3].map(&:to_s)
12
12
  //
13
13
  // This works with `do` blocks as well.
14
- const toProc = (path, opts, node) => {
15
- if (!node || !opts.toProcTransform) {
14
+ const toProc = (path, node) => {
15
+ if (!node) {
16
16
  return null;
17
17
  }
18
18
 
@@ -57,9 +57,9 @@ const toProc = (path, opts, node) => {
57
57
  return null;
58
58
  }
59
59
 
60
- // Ensure that statement is a call
60
+ // Ensure that statement is a call and that it has no comments attached
61
61
  const [statement] = statements.body;
62
- if (statement.type !== "call") {
62
+ if (statement.type !== "call" || statement.comments) {
63
63
  return null;
64
64
  }
65
65
 
@@ -1,18 +1,13 @@
1
- const {
2
- breakParent,
3
- concat,
4
- hardline,
5
- lineSuffix,
6
- literalline
7
- } = require("./prettier");
8
-
9
- const concatBody = (path, opts, print) => concat(path.map(print, "body"));
1
+ const { concat } = require("./prettier");
2
+ const isEmptyStmts = require("./utils/isEmptyStmts");
3
+ const literalLineNoBreak = require("./utils/literalLineNoBreak");
10
4
 
11
5
  // If the node is a type of assignment or if the node is a paren and nested
12
6
  // inside that paren is a node that is a type of assignment.
13
7
  const containsAssignment = (node) =>
14
- ["assign", "massign"].includes(node.type) ||
15
- (node.type === "paren" && node.body[0].body.some(containsAssignment));
8
+ node &&
9
+ (["assign", "massign", "opassign"].includes(node.type) ||
10
+ (Array.isArray(node.body) && node.body.some(containsAssignment)));
16
11
 
17
12
  const docLength = (doc) => {
18
13
  if (doc.length) {
@@ -34,6 +29,8 @@ const empty = () => "";
34
29
 
35
30
  const first = (path, opts, print) => path.call(print, "body", 0);
36
31
 
32
+ const getTrailingComma = (opts) => ["all", "es5"].includes(opts.trailingComma);
33
+
37
34
  const hasAncestor = (path, types) => {
38
35
  let parent = 0;
39
36
  let parentNode = path.getParentNode();
@@ -52,45 +49,6 @@ const hasAncestor = (path, types) => {
52
49
 
53
50
  const literal = (value) => () => value;
54
51
 
55
- const makeArgs = (path, opts, print, argsIndex) => {
56
- let argNodes = path.getValue().body[argsIndex];
57
- const argPattern = [print, "body", argsIndex, "body"];
58
-
59
- if (argNodes.type === "args_add_block") {
60
- [argNodes] = argNodes.body;
61
- argPattern.push(0, "body");
62
- }
63
-
64
- const args = path.call(print, "body", argsIndex);
65
- const heredocs = [];
66
-
67
- argNodes.body.forEach((argNode, index) => {
68
- let pattern;
69
- let heredoc;
70
-
71
- if (argNode.type === "heredoc") {
72
- pattern = [index, "body"];
73
- heredoc = argNode;
74
- } else if (
75
- argNode.type === "string_literal" &&
76
- argNode.body[0].type === "heredoc"
77
- ) {
78
- pattern = [index, "body", 0, "body"];
79
- [heredoc] = argNode.body;
80
- } else {
81
- return;
82
- }
83
-
84
- const content = path.map.apply(path, argPattern.slice().concat(pattern));
85
- heredocs.push(
86
- concat([literalline].concat(content).concat([heredoc.ending]))
87
- );
88
- args[index] = heredoc.beging;
89
- });
90
-
91
- return { args, heredocs };
92
- };
93
-
94
52
  const makeCall = (path, opts, print) => {
95
53
  const operation = path.getValue().body[1];
96
54
 
@@ -101,57 +59,35 @@ const makeCall = (path, opts, print) => {
101
59
  return operation === "::" ? "." : path.call(print, "body", 1);
102
60
  };
103
61
 
104
- const makeList = (path, opts, print) => path.map(print, "body");
62
+ const noIndent = [
63
+ "array",
64
+ "hash",
65
+ "heredoc",
66
+ "if",
67
+ "method_add_block",
68
+ "xstring_literal"
69
+ ];
105
70
 
106
71
  const prefix = (value) => (path, opts, print) =>
107
72
  concat([value, path.call(print, "body", 0)]);
108
73
 
109
- const printComments = (printed, start, comments) => {
110
- let node = printed;
111
-
112
- comments.forEach((comment) => {
113
- if (comment.start < start) {
114
- node = concat([
115
- comment.break ? breakParent : "",
116
- comment.body,
117
- hardline,
118
- node
119
- ]);
120
- } else {
121
- node = concat([
122
- node,
123
- comment.break ? breakParent : "",
124
- lineSuffix(` ${comment.body}`)
125
- ]);
126
- }
127
- });
128
-
129
- return node;
130
- };
131
-
74
+ const skippable = ["array", "hash", "heredoc", "lambda", "regexp_literal"];
132
75
  const skipAssignIndent = (node) =>
133
- ["array", "hash", "heredoc", "lambda", "regexp_literal"].includes(
134
- node.type
135
- ) ||
136
- (node.type === "call" && skipAssignIndent(node.body[0])) ||
137
- (node.type === "string_literal" && node.body[0].type === "heredoc");
138
-
139
- const surround = (left, right) => (path, opts, print) =>
140
- concat([left, path.call(print, "body", 0), right]);
76
+ skippable.includes(node.type) ||
77
+ (node.type === "call" && skipAssignIndent(node.body[0]));
141
78
 
142
79
  module.exports = {
143
- concatBody,
144
80
  containsAssignment,
145
81
  docLength,
146
82
  empty,
147
83
  first,
84
+ getTrailingComma,
148
85
  hasAncestor,
86
+ isEmptyStmts,
149
87
  literal,
150
- makeArgs,
88
+ literalLineNoBreak,
151
89
  makeCall,
152
- makeList,
90
+ noIndent,
153
91
  prefix,
154
- printComments,
155
- skipAssignIndent,
156
- surround
92
+ skipAssignIndent
157
93
  };
@@ -0,0 +1,42 @@
1
+ const needsParens = ["args", "assign", "assoc_new", "massign", "opassign"];
2
+
3
+ // If you have a modifier statement (for instance an inline if statement or an
4
+ // inline while loop) there are times when you need to wrap the entire statement
5
+ // in parentheses. This occurs when you have something like:
6
+ //
7
+ // foo[:foo] =
8
+ // if bar?
9
+ // baz
10
+ // end
11
+ //
12
+ // Normally we would shorten this to an inline version, which would result in:
13
+ //
14
+ // foo[:foo] = baz if bar?
15
+ //
16
+ // but this actually has different semantic meaning. The first example will
17
+ // result in a nil being inserted into the hash for the :foo key, whereas the
18
+ // second example will result in an empty hash because the if statement applies
19
+ // to the entire assignment.
20
+ //
21
+ // We can fix this in a couple of ways. We can use the then keyword, as in:
22
+ //
23
+ // foo[:foo] = if bar? then baz end
24
+ //
25
+ // but I haven't actually seen this anywhere. We can also just leave it as is
26
+ // with the multi-line version, but for a short predicate and short value it
27
+ // looks pretty silly. The last option and the one I've selected here is to add
28
+ // parentheses on both sides of the expression, as in:
29
+ //
30
+ // foo[:foo] = (baz if bar?)
31
+ //
32
+ // This approach maintains the nice conciseness of the inline version, while
33
+ // keeping the correct semantic meaning.
34
+ const inlineEnsureParens = (path, parts) => {
35
+ if (needsParens.includes(path.getParentNode().type)) {
36
+ return ["("].concat(parts, ")");
37
+ }
38
+
39
+ return parts;
40
+ };
41
+
42
+ module.exports = inlineEnsureParens;
@@ -0,0 +1,7 @@
1
+ const isEmptyStmts = (node) =>
2
+ node &&
3
+ node.type === "stmts" &&
4
+ node.body.length === 1 &&
5
+ node.body[0].type === "void_stmt";
6
+
7
+ module.exports = isEmptyStmts;
@@ -0,0 +1,7 @@
1
+ const literalLineNoBreak = {
2
+ type: "line",
3
+ hard: true,
4
+ literal: true
5
+ };
6
+
7
+ module.exports = literalLineNoBreak;
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prettier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.0
4
+ version: 1.0.0.pre.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Deisz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-28 00:00:00.000000000 Z
11
+ date: 2020-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -73,31 +73,22 @@ files:
73
73
  - node_modules/prettier/third-party.js
74
74
  - package.json
75
75
  - src/embed.js
76
- - src/haml.js
77
- - src/haml/embed.js
78
- - src/haml/nodes/comment.js
79
- - src/haml/nodes/doctype.js
80
- - src/haml/nodes/filter.js
81
- - src/haml/nodes/hamlComment.js
82
- - src/haml/nodes/script.js
83
- - src/haml/nodes/silentScript.js
84
- - src/haml/nodes/tag.js
85
- - src/haml/parse.js
86
- - src/haml/parse.rb
87
- - src/haml/print.js
88
76
  - src/nodes.js
89
77
  - src/nodes/alias.js
78
+ - src/nodes/aref.js
90
79
  - src/nodes/args.js
91
80
  - src/nodes/arrays.js
92
81
  - src/nodes/assign.js
93
82
  - src/nodes/blocks.js
94
83
  - src/nodes/calls.js
95
84
  - src/nodes/case.js
85
+ - src/nodes/class.js
96
86
  - src/nodes/commands.js
97
87
  - src/nodes/conditionals.js
98
88
  - src/nodes/constants.js
99
89
  - src/nodes/flow.js
100
90
  - src/nodes/hashes.js
91
+ - src/nodes/heredocs.js
101
92
  - src/nodes/hooks.js
102
93
  - src/nodes/ints.js
103
94
  - src/nodes/lambdas.js
@@ -110,16 +101,20 @@ files:
110
101
  - src/nodes/regexp.js
111
102
  - src/nodes/rescue.js
112
103
  - src/nodes/return.js
113
- - src/nodes/scopes.js
114
104
  - src/nodes/statements.js
115
105
  - src/nodes/strings.js
116
- - src/parse.js
106
+ - src/nodes/super.js
107
+ - src/nodes/undef.js
108
+ - src/parser.js
109
+ - src/parser.rb
117
110
  - src/prettier.js
118
- - src/print.js
119
- - src/ripper.rb
111
+ - src/printer.js
120
112
  - src/ruby.js
121
113
  - src/toProc.js
122
114
  - src/utils.js
115
+ - src/utils/inlineEnsureParens.js
116
+ - src/utils/isEmptyStmts.js
117
+ - src/utils/literalLineNoBreak.js
123
118
  homepage: https://github.com/prettier/plugin-ruby#readme
124
119
  licenses:
125
120
  - MIT
@@ -135,9 +130,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
135
130
  version: '0'
136
131
  required_rubygems_version: !ruby/object:Gem::Requirement
137
132
  requirements:
138
- - - ">="
133
+ - - ">"
139
134
  - !ruby/object:Gem::Version
140
- version: '0'
135
+ version: 1.3.1
141
136
  requirements: []
142
137
  rubygems_version: 3.0.3
143
138
  signing_key: