prettier 1.2.2 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +64 -1
  3. data/CONTRIBUTING.md +2 -2
  4. data/README.md +22 -94
  5. data/node_modules/prettier/index.js +54 -54
  6. data/package.json +2 -3
  7. data/rubocop.yml +26 -0
  8. data/src/haml/embed.js +87 -0
  9. data/src/haml/nodes/comment.js +27 -0
  10. data/src/haml/nodes/doctype.js +34 -0
  11. data/src/haml/nodes/filter.js +16 -0
  12. data/src/haml/nodes/hamlComment.js +21 -0
  13. data/src/haml/nodes/plain.js +6 -0
  14. data/src/haml/nodes/root.js +8 -0
  15. data/src/haml/nodes/script.js +33 -0
  16. data/src/haml/nodes/silentScript.js +59 -0
  17. data/src/haml/nodes/tag.js +193 -0
  18. data/src/haml/parser.js +22 -0
  19. data/src/haml/parser.rb +138 -0
  20. data/src/haml/printer.js +28 -0
  21. data/src/parser/getLang.js +32 -0
  22. data/src/parser/getNetcat.js +50 -0
  23. data/src/parser/netcat.js +15 -0
  24. data/src/parser/parseSync.js +33 -0
  25. data/src/parser/requestParse.js +74 -0
  26. data/src/parser/server.rb +61 -0
  27. data/src/{ruby.js → plugin.js} +25 -4
  28. data/src/prettier.js +1 -0
  29. data/src/rbs/parser.js +39 -0
  30. data/src/rbs/parser.rb +88 -0
  31. data/src/rbs/printer.js +605 -0
  32. data/src/{embed.js → ruby/embed.js} +6 -2
  33. data/src/{nodes.js → ruby/nodes.js} +0 -0
  34. data/src/{nodes → ruby/nodes}/alias.js +1 -1
  35. data/src/{nodes → ruby/nodes}/aref.js +8 -1
  36. data/src/{nodes → ruby/nodes}/args.js +2 -2
  37. data/src/{nodes → ruby/nodes}/arrays.js +2 -3
  38. data/src/{nodes → ruby/nodes}/assign.js +7 -3
  39. data/src/ruby/nodes/blocks.js +90 -0
  40. data/src/{nodes → ruby/nodes}/calls.js +20 -47
  41. data/src/{nodes → ruby/nodes}/case.js +1 -1
  42. data/src/{nodes → ruby/nodes}/class.js +1 -1
  43. data/src/ruby/nodes/commands.js +131 -0
  44. data/src/{nodes → ruby/nodes}/conditionals.js +3 -3
  45. data/src/{nodes → ruby/nodes}/constants.js +2 -2
  46. data/src/{nodes → ruby/nodes}/flow.js +2 -2
  47. data/src/{nodes → ruby/nodes}/hashes.js +32 -10
  48. data/src/{nodes → ruby/nodes}/heredocs.js +2 -2
  49. data/src/ruby/nodes/hooks.js +34 -0
  50. data/src/{nodes → ruby/nodes}/ints.js +0 -0
  51. data/src/{nodes → ruby/nodes}/lambdas.js +2 -2
  52. data/src/{nodes → ruby/nodes}/loops.js +10 -7
  53. data/src/{nodes → ruby/nodes}/massign.js +8 -1
  54. data/src/{nodes → ruby/nodes}/methods.js +10 -9
  55. data/src/{nodes → ruby/nodes}/operators.js +2 -2
  56. data/src/{nodes → ruby/nodes}/params.js +31 -16
  57. data/src/{nodes → ruby/nodes}/patterns.js +17 -6
  58. data/src/{nodes → ruby/nodes}/regexp.js +2 -2
  59. data/src/{nodes → ruby/nodes}/rescue.js +34 -27
  60. data/src/{nodes → ruby/nodes}/return.js +21 -10
  61. data/src/{nodes → ruby/nodes}/statements.js +9 -9
  62. data/src/{nodes → ruby/nodes}/strings.js +28 -36
  63. data/src/{nodes → ruby/nodes}/super.js +2 -2
  64. data/src/{nodes → ruby/nodes}/undef.js +1 -1
  65. data/src/ruby/parser.js +39 -0
  66. data/src/{parser.rb → ruby/parser.rb} +498 -529
  67. data/src/{printer.js → ruby/printer.js} +1 -3
  68. data/src/{toProc.js → ruby/toProc.js} +4 -8
  69. data/src/utils.js +10 -93
  70. data/src/utils/containsAssignment.js +11 -0
  71. data/src/utils/getTrailingComma.js +5 -0
  72. data/src/utils/hasAncestor.js +17 -0
  73. data/src/utils/literal.js +7 -0
  74. data/src/utils/makeCall.js +14 -0
  75. data/src/utils/noIndent.js +11 -0
  76. data/src/utils/skipAssignIndent.js +10 -0
  77. metadata +71 -41
  78. data/src/nodes/blocks.js +0 -85
  79. data/src/nodes/commands.js +0 -91
  80. data/src/nodes/hooks.js +0 -44
  81. data/src/parser.js +0 -86
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@prettier/plugin-ruby",
3
- "version": "1.2.2",
3
+ "version": "1.4.0",
4
4
  "description": "prettier plugin for the Ruby programming language",
5
- "main": "src/ruby.js",
5
+ "main": "src/plugin.js",
6
6
  "scripts": {
7
7
  "check-format": "prettier --check '**/*'",
8
8
  "lint": "eslint --cache .",
@@ -22,7 +22,6 @@
22
22
  "prettier": ">=1.10"
23
23
  },
24
24
  "devDependencies": {
25
- "all-contributors-cli": "^6.14.1",
26
25
  "eslint": "^7.8.1",
27
26
  "eslint-config-prettier": "^7.0.0",
28
27
  "husky": "^4.3.5",
@@ -0,0 +1,26 @@
1
+ # Disabling all Layout/* rules, as they're unnecessary when the user is using
2
+ # prettier to handle all of the formatting.
3
+
4
+ Layout:
5
+ Enabled: false
6
+
7
+ # Disabling all of the following options because they could conflict with a
8
+ # prettier configuration setting.
9
+
10
+ Style/MultilineIfModifier: # rubyModifier
11
+ Enabled: false
12
+
13
+ Style/SymbolArray: # rubyArrayLiteral
14
+ Enabled: false
15
+
16
+ Style/WordArray: # rubyArrayLiteral
17
+ Enabled: false
18
+
19
+ Style/TrailingCommaInArguments: # trailingComma
20
+ Enabled: false
21
+
22
+ Style/TrailingCommaInArrayLiteral: # trailingComma
23
+ Enabled: false
24
+
25
+ Style/TrailingCommaInHashLiteral: # trailingComma
26
+ Enabled: false
@@ -0,0 +1,87 @@
1
+ const {
2
+ concat,
3
+ hardline,
4
+ indent,
5
+ literalline,
6
+ markAsRoot,
7
+ mapDoc,
8
+ stripTrailingHardline
9
+ } = require("../prettier");
10
+
11
+ // Get the name of the parser that is represented by the given element node,
12
+ // return null if a matching parser cannot be found
13
+ function getParser(name, opts) {
14
+ let parser = name;
15
+
16
+ // We don't want to deal with some weird recursive parser situation, so we
17
+ // need to explicitly call out the HAML parser here and just return null
18
+ if (parser === "haml") {
19
+ return null;
20
+ }
21
+
22
+ // In HAML the name of the JS filter is :javascript, whereas in prettier the
23
+ // name of the JS parser is babel. Here we explicitly handle that conversion.
24
+ if (parser === "javascript") {
25
+ parser = "babel";
26
+ }
27
+
28
+ // If there is a plugin that has a parser that matches the name of this
29
+ // element, then we're going to assume that's correct for embedding and go
30
+ // ahead and switch to that parser
31
+ if (
32
+ opts.plugins.some(
33
+ (plugin) =>
34
+ plugin.parsers &&
35
+ Object.prototype.hasOwnProperty.call(plugin.parsers, parser)
36
+ )
37
+ ) {
38
+ return parser;
39
+ }
40
+
41
+ return null;
42
+ }
43
+
44
+ // This function is in here because it handles embedded parser values. I don't
45
+ // have a test that exercises it because I'm not sure for which parser it is
46
+ // necessary, but since it's in prettier core I'm keeping it here.
47
+ /* istanbul ignore next */
48
+ function replaceNewlines(doc) {
49
+ return mapDoc(doc, (currentDoc) =>
50
+ typeof currentDoc === "string" && currentDoc.includes("\n")
51
+ ? concat(
52
+ currentDoc
53
+ .split(/(\n)/g)
54
+ .map((v, i) => (i % 2 === 0 ? v : literalline))
55
+ )
56
+ : currentDoc
57
+ );
58
+ }
59
+
60
+ function embed(path, _print, textToDoc, opts) {
61
+ const node = path.getValue();
62
+ if (node.type !== "filter") {
63
+ return null;
64
+ }
65
+
66
+ const parser = getParser(node.value.name, opts);
67
+ if (!parser) {
68
+ return null;
69
+ }
70
+
71
+ return markAsRoot(
72
+ concat([
73
+ ":",
74
+ node.value.name,
75
+ indent(
76
+ concat([
77
+ hardline,
78
+ replaceNewlines(
79
+ stripTrailingHardline(textToDoc(node.value.text, { parser }))
80
+ )
81
+ ])
82
+ )
83
+ ])
84
+ );
85
+ }
86
+
87
+ module.exports = embed;
@@ -0,0 +1,27 @@
1
+ const { concat, group, hardline, indent, join } = require("../../prettier");
2
+
3
+ // https://haml.info/docs/yardoc/file.REFERENCE.html#html-comments-
4
+ function comment(path, _opts, print) {
5
+ const { children, value } = path.getValue();
6
+ const parts = ["/"];
7
+
8
+ if (value.revealed) {
9
+ parts.push("!");
10
+ }
11
+
12
+ if (value.conditional) {
13
+ parts.push(value.conditional);
14
+ } else if (value.text) {
15
+ parts.push(" ", value.text);
16
+ }
17
+
18
+ if (children.length > 0) {
19
+ parts.push(
20
+ indent(concat([hardline, join(hardline, path.map(print, "children"))]))
21
+ );
22
+ }
23
+
24
+ return group(concat(parts));
25
+ }
26
+
27
+ module.exports = comment;
@@ -0,0 +1,34 @@
1
+ const { join } = require("../../prettier");
2
+
3
+ const types = {
4
+ basic: "Basic",
5
+ frameset: "Frameset",
6
+ mobile: "Mobile",
7
+ rdfa: "RDFa",
8
+ strict: "Strict",
9
+ xml: "XML"
10
+ };
11
+
12
+ const versions = ["1.1", "5"];
13
+
14
+ // https://haml.info/docs/yardoc/file.REFERENCE.html#doctype-
15
+ function doctype(path, _opts, _print) {
16
+ const { value } = path.getValue();
17
+ const parts = ["!!!"];
18
+
19
+ if (value.type in types) {
20
+ parts.push(types[value.type]);
21
+ } else if (versions.includes(value.version)) {
22
+ parts.push(value.version);
23
+ } else {
24
+ parts.push(value.type);
25
+ }
26
+
27
+ if (value.encoding) {
28
+ parts.push(value.encoding);
29
+ }
30
+
31
+ return join(" ", parts);
32
+ }
33
+
34
+ module.exports = doctype;
@@ -0,0 +1,16 @@
1
+ const { concat, group, hardline, indent, join } = require("../../prettier");
2
+
3
+ // https://haml.info/docs/yardoc/file.REFERENCE.html#filters
4
+ function filter(path, _opts, _print) {
5
+ const { value } = path.getValue();
6
+
7
+ return group(
8
+ concat([
9
+ ":",
10
+ value.name,
11
+ indent(concat([hardline, join(hardline, value.text.trim().split("\n"))]))
12
+ ])
13
+ );
14
+ }
15
+
16
+ module.exports = filter;
@@ -0,0 +1,21 @@
1
+ const { concat, hardline, indent, join } = require("../../prettier");
2
+
3
+ // https://haml.info/docs/yardoc/file.REFERENCE.html#haml-comments--
4
+ function hamlComment(path, opts, _print) {
5
+ const node = path.getValue();
6
+ const parts = ["-#"];
7
+
8
+ if (node.value.text) {
9
+ if (opts.originalText.split("\n")[node.line - 1].trim() === "-#") {
10
+ const lines = node.value.text.trim().split("\n");
11
+
12
+ parts.push(indent(concat([hardline, join(hardline, lines)])));
13
+ } else {
14
+ parts.push(" ", node.value.text.trim());
15
+ }
16
+ }
17
+
18
+ return concat(parts);
19
+ }
20
+
21
+ module.exports = hamlComment;
@@ -0,0 +1,6 @@
1
+ // https://haml.info/docs/yardoc/file.REFERENCE.html#plain-text
2
+ function plain(path, _opts, _print) {
3
+ return path.getValue().value.text;
4
+ }
5
+
6
+ module.exports = plain;
@@ -0,0 +1,8 @@
1
+ const { concat, hardline, join } = require("../../prettier");
2
+
3
+ // The root node in the AST
4
+ function root(path, _opts, print) {
5
+ return concat([join(hardline, path.map(print, "children")), hardline]);
6
+ }
7
+
8
+ module.exports = root;
@@ -0,0 +1,33 @@
1
+ const { concat, group, hardline, indent, join } = require("../../prettier");
2
+
3
+ // https://haml.info/docs/yardoc/file.REFERENCE.html#inserting_ruby
4
+ function script(path, opts, print) {
5
+ const { children, value } = path.getValue();
6
+ const parts = [];
7
+
8
+ if (value.escape_html) {
9
+ parts.unshift("&");
10
+ }
11
+
12
+ if (value.preserve) {
13
+ parts.push("~");
14
+ } else if (!value.interpolate) {
15
+ parts.push("=");
16
+ }
17
+
18
+ if (value.escape_html && !value.preserve && value.interpolate) {
19
+ parts.push(" ", value.text.trim().slice(1, -1));
20
+ } else {
21
+ parts.push(" ", value.text.trim());
22
+ }
23
+
24
+ if (children.length > 0) {
25
+ parts.push(
26
+ indent(concat([hardline, join(hardline, path.map(print, "children"))]))
27
+ );
28
+ }
29
+
30
+ return group(concat(parts));
31
+ }
32
+
33
+ module.exports = script;
@@ -0,0 +1,59 @@
1
+ const { concat, group, hardline, indent, join } = require("../../prettier");
2
+
3
+ function findKeywordIndices(children, keywords) {
4
+ const indices = [];
5
+
6
+ children.forEach((child, index) => {
7
+ if (child.type !== "silent_script") {
8
+ return;
9
+ }
10
+
11
+ if (keywords.includes(child.value.keyword)) {
12
+ indices.push(index);
13
+ }
14
+ });
15
+
16
+ return indices;
17
+ }
18
+
19
+ // https://haml.info/docs/yardoc/file.REFERENCE.html#running-ruby--
20
+ function silentScript(path, _opts, print) {
21
+ const { children, value } = path.getValue();
22
+ const parts = [`- ${value.text.trim()}`];
23
+
24
+ if (children.length > 0) {
25
+ const scripts = path.map(print, "children");
26
+
27
+ if (value.keyword === "case") {
28
+ const keywordIndices = findKeywordIndices(children, ["when", "else"]);
29
+
30
+ parts.push(
31
+ concat(
32
+ scripts.map((script, index) => {
33
+ const concated = concat([hardline, script]);
34
+
35
+ return keywordIndices.includes(index) ? concated : indent(concated);
36
+ })
37
+ )
38
+ );
39
+ } else if (["if", "unless"].includes(value.keyword)) {
40
+ const keywordIndices = findKeywordIndices(children, ["elsif", "else"]);
41
+
42
+ parts.push(
43
+ concat(
44
+ scripts.map((script, index) => {
45
+ const concated = concat([hardline, script]);
46
+
47
+ return keywordIndices.includes(index) ? concated : indent(concated);
48
+ })
49
+ )
50
+ );
51
+ } else {
52
+ parts.push(indent(concat([hardline, join(hardline, scripts)])));
53
+ }
54
+ }
55
+
56
+ return group(concat(parts));
57
+ }
58
+
59
+ module.exports = silentScript;
@@ -0,0 +1,193 @@
1
+ const {
2
+ align,
3
+ concat,
4
+ fill,
5
+ group,
6
+ hardline,
7
+ ifBreak,
8
+ indent,
9
+ join,
10
+ line,
11
+ softline
12
+ } = require("../../prettier");
13
+
14
+ function getDynamicAttributes(header, attributes) {
15
+ const pairs = attributes
16
+ .slice(1, -2)
17
+ .split(",")
18
+ .map((pair) => pair.slice(1).split('" => '));
19
+
20
+ const parts = [concat([pairs[0][0], "=", pairs[0][1]])];
21
+ pairs.slice(1).forEach((pair) => {
22
+ parts.push(line, concat([pair[0], "=", pair[1]]));
23
+ });
24
+
25
+ return group(concat(["(", align(header + 1, fill(parts)), ")"]));
26
+ }
27
+
28
+ function getHashValue(value, opts) {
29
+ if (typeof value !== "string") {
30
+ return value.toString();
31
+ }
32
+
33
+ // This is a very special syntax created by the parser to let us know that
34
+ // this should be printed literally instead of as a string.
35
+ if (value.startsWith("&")) {
36
+ return value.slice(1);
37
+ }
38
+
39
+ const quote = opts.rubySingleQuote ? "'" : '"';
40
+ return `${quote}${value}${quote}`;
41
+ }
42
+
43
+ function getHashKey(key, opts) {
44
+ let quoted = key;
45
+ const joiner = opts.rubyHashLabel ? ":" : " =>";
46
+
47
+ if (key.includes(":") || key.includes("-")) {
48
+ const quote = opts.rubySingleQuote ? "'" : '"';
49
+ quoted = `${quote}${key}${quote}`;
50
+ }
51
+
52
+ return `${opts.rubyHashLabel ? "" : ":"}${quoted}${joiner}`;
53
+ }
54
+
55
+ function getKeyValuePair(key, value, opts) {
56
+ return `${getHashKey(key, opts)} ${getHashValue(value, opts)}`;
57
+ }
58
+
59
+ function getStaticAttributes(header, attributes, opts) {
60
+ const keys = Object.keys(attributes).filter(
61
+ (name) => !["class", "id"].includes(name)
62
+ );
63
+
64
+ const parts = [getKeyValuePair(keys[0], attributes[keys[0]], opts)];
65
+
66
+ keys.slice(1).forEach((key) => {
67
+ parts.push(",", line, getKeyValuePair(key, attributes[key], opts));
68
+ });
69
+
70
+ return group(concat(["{", align(header + 1, fill(parts)), "}"]));
71
+ }
72
+
73
+ function getAttributesObject(object, opts, level = 0) {
74
+ if (typeof object !== "object") {
75
+ return getHashValue(object, opts);
76
+ }
77
+
78
+ const boundary = level === 0 ? softline : line;
79
+ const parts = Object.keys(object).map((key) =>
80
+ concat([
81
+ getHashKey(key, opts),
82
+ " ",
83
+ getAttributesObject(object[key], opts, level + 1)
84
+ ])
85
+ );
86
+
87
+ return group(
88
+ concat([
89
+ "{",
90
+ indent(group(concat([boundary, join(concat([",", line]), parts)]))),
91
+ boundary,
92
+ "}"
93
+ ])
94
+ );
95
+ }
96
+
97
+ function getHeader(value, opts) {
98
+ const { attributes } = value;
99
+ const parts = [];
100
+
101
+ if (value.name !== "div") {
102
+ parts.push(`%${value.name}`);
103
+ }
104
+
105
+ if (attributes.class) {
106
+ parts.push(`.${attributes.class.replace(/ /g, ".")}`);
107
+ }
108
+
109
+ if (attributes.id) {
110
+ parts.push(`#${attributes.id}`);
111
+ }
112
+
113
+ if (value.dynamic_attributes.new) {
114
+ parts.push(
115
+ getDynamicAttributes(parts.join("").length, value.dynamic_attributes.new)
116
+ );
117
+ }
118
+
119
+ if (
120
+ Object.keys(attributes).some((name) => name !== "class" && name !== "id")
121
+ ) {
122
+ parts.push(getStaticAttributes(parts.join("").length, attributes, opts));
123
+ }
124
+
125
+ if (value.dynamic_attributes.old) {
126
+ if (parts.length === 0) {
127
+ parts.push("%div");
128
+ }
129
+
130
+ if (typeof value.dynamic_attributes.old === "string") {
131
+ parts.push(value.dynamic_attributes.old);
132
+ } else {
133
+ parts.push(getAttributesObject(value.dynamic_attributes.old, opts));
134
+ }
135
+ }
136
+
137
+ if (value.object_ref) {
138
+ if (parts.length === 0) {
139
+ parts.push("%div");
140
+ }
141
+ parts.push(value.object_ref);
142
+ }
143
+
144
+ if (value.nuke_outer_whitespace) {
145
+ parts.push(">");
146
+ }
147
+
148
+ if (value.nuke_inner_whitespace) {
149
+ parts.push("<");
150
+ }
151
+
152
+ if (value.self_closing) {
153
+ parts.push("/");
154
+ }
155
+
156
+ if (value.value) {
157
+ const prefix = value.parse ? "= " : ifBreak("", " ");
158
+
159
+ return group(
160
+ concat([
161
+ group(concat(parts)),
162
+ indent(concat([softline, prefix, value.value]))
163
+ ])
164
+ );
165
+ }
166
+
167
+ // In case none of the other if statements have matched and we're printing a
168
+ // div, we need to explicitly add it back into the array.
169
+ if (parts.length === 0 && value.name === "div") {
170
+ parts.push("%div");
171
+ }
172
+
173
+ return group(concat(parts));
174
+ }
175
+
176
+ // https://haml.info/docs/yardoc/file.REFERENCE.html#element-name-
177
+ function tag(path, opts, print) {
178
+ const { children, value } = path.getValue();
179
+ const header = getHeader(value, opts);
180
+
181
+ if (children.length === 0) {
182
+ return header;
183
+ }
184
+
185
+ return group(
186
+ concat([
187
+ header,
188
+ indent(concat([hardline, join(hardline, path.map(print, "children"))]))
189
+ ])
190
+ );
191
+ }
192
+
193
+ module.exports = tag;