prettier 1.6.1 → 2.0.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +316 -293
  3. data/CONTRIBUTING.md +6 -9
  4. data/LICENSE +1 -1
  5. data/README.md +11 -12
  6. data/dist/haml/embed.js +53 -0
  7. data/dist/haml/parser.js +31 -0
  8. data/{src → dist}/haml/parser.rb +0 -0
  9. data/dist/haml/printer.js +336 -0
  10. data/dist/parser/getInfo.js +17 -0
  11. data/{src → dist}/parser/netcat.js +1 -0
  12. data/dist/parser/parseSync.js +128 -0
  13. data/dist/parser/server.rb +140 -0
  14. data/dist/plugin.js +143 -0
  15. data/dist/prettier.js +15 -0
  16. data/dist/rbs/parser.js +34 -0
  17. data/{src → dist}/rbs/parser.rb +0 -0
  18. data/dist/rbs/printer.js +517 -0
  19. data/dist/ruby/embed.js +110 -0
  20. data/dist/ruby/nodes/alias.js +59 -0
  21. data/{src → dist}/ruby/nodes/aref.js +26 -35
  22. data/dist/ruby/nodes/args.js +165 -0
  23. data/dist/ruby/nodes/arrays.js +126 -0
  24. data/dist/ruby/nodes/assign.js +41 -0
  25. data/dist/ruby/nodes/blocks.js +68 -0
  26. data/dist/ruby/nodes/calls.js +220 -0
  27. data/dist/ruby/nodes/case.js +50 -0
  28. data/dist/ruby/nodes/class.js +54 -0
  29. data/dist/ruby/nodes/commands.js +124 -0
  30. data/dist/ruby/nodes/conditionals.js +242 -0
  31. data/dist/ruby/nodes/constants.js +38 -0
  32. data/dist/ruby/nodes/flow.js +66 -0
  33. data/dist/ruby/nodes/hashes.js +130 -0
  34. data/dist/ruby/nodes/heredocs.js +30 -0
  35. data/dist/ruby/nodes/hooks.js +35 -0
  36. data/dist/ruby/nodes/ints.js +27 -0
  37. data/dist/ruby/nodes/lambdas.js +69 -0
  38. data/dist/ruby/nodes/loops.js +73 -0
  39. data/dist/ruby/nodes/massign.js +73 -0
  40. data/dist/ruby/nodes/methods.js +70 -0
  41. data/dist/ruby/nodes/operators.js +70 -0
  42. data/dist/ruby/nodes/params.js +89 -0
  43. data/dist/ruby/nodes/patterns.js +109 -0
  44. data/dist/ruby/nodes/regexp.js +45 -0
  45. data/dist/ruby/nodes/rescue.js +82 -0
  46. data/dist/ruby/nodes/return.js +75 -0
  47. data/dist/ruby/nodes/statements.js +111 -0
  48. data/dist/ruby/nodes/strings.js +218 -0
  49. data/dist/ruby/nodes/super.js +30 -0
  50. data/dist/ruby/nodes/undef.js +26 -0
  51. data/dist/ruby/nodes.js +151 -0
  52. data/dist/ruby/parser.js +34 -0
  53. data/{src → dist}/ruby/parser.rb +1215 -252
  54. data/dist/ruby/printer.js +125 -0
  55. data/dist/ruby/toProc.js +93 -0
  56. data/dist/types/haml.js +4 -0
  57. data/dist/types/plugin.js +3 -0
  58. data/dist/types/rbs.js +4 -0
  59. data/dist/types/ruby.js +4 -0
  60. data/dist/types/utils.js +2 -0
  61. data/dist/types.js +30 -0
  62. data/dist/utils/containsAssignment.js +15 -0
  63. data/dist/utils/getTrailingComma.js +6 -0
  64. data/dist/utils/hasAncestor.js +15 -0
  65. data/{src → dist}/utils/inlineEnsureParens.js +16 -17
  66. data/dist/utils/isEmptyBodyStmt.js +10 -0
  67. data/dist/utils/isEmptyStmts.js +10 -0
  68. data/dist/utils/literal.js +8 -0
  69. data/dist/utils/literallineWithoutBreakParent.js +8 -0
  70. data/dist/utils/makeCall.js +13 -0
  71. data/dist/utils/noIndent.js +11 -0
  72. data/dist/utils/printEmptyCollection.js +44 -0
  73. data/dist/utils/skipAssignIndent.js +15 -0
  74. data/dist/utils.js +30 -0
  75. data/node_modules/prettier/bin-prettier.js +313 -190
  76. data/node_modules/prettier/doc.js +191 -323
  77. data/node_modules/prettier/index.js +2753 -3677
  78. data/node_modules/prettier/package.json +1 -1
  79. data/node_modules/prettier/parser-angular.js +13 -14
  80. data/node_modules/prettier/parser-babel.js +7 -7
  81. data/node_modules/prettier/parser-espree.js +7 -7
  82. data/node_modules/prettier/parser-flow.js +7 -7
  83. data/node_modules/prettier/parser-glimmer.js +1 -1
  84. data/node_modules/prettier/parser-graphql.js +1 -1
  85. data/node_modules/prettier/parser-html.js +17 -17
  86. data/node_modules/prettier/parser-markdown.js +9 -9
  87. data/node_modules/prettier/parser-meriyah.js +7 -7
  88. data/node_modules/prettier/parser-postcss.js +2 -2
  89. data/node_modules/prettier/parser-typescript.js +7 -7
  90. data/node_modules/prettier/parser-yaml.js +2 -2
  91. data/node_modules/prettier/third-party.js +143 -78
  92. data/package.json +26 -18
  93. metadata +74 -67
  94. data/src/haml/embed.js +0 -87
  95. data/src/haml/parser.js +0 -23
  96. data/src/haml/printer.js +0 -438
  97. data/src/parser/parseSync.js +0 -172
  98. data/src/parser/server.rb +0 -66
  99. data/src/plugin.js +0 -148
  100. data/src/prettier.js +0 -16
  101. data/src/rbs/parser.js +0 -37
  102. data/src/rbs/printer.js +0 -643
  103. data/src/ruby/embed.js +0 -142
  104. data/src/ruby/nodes/alias.js +0 -73
  105. data/src/ruby/nodes/args.js +0 -222
  106. data/src/ruby/nodes/arrays.js +0 -162
  107. data/src/ruby/nodes/assign.js +0 -47
  108. data/src/ruby/nodes/blocks.js +0 -90
  109. data/src/ruby/nodes/calls.js +0 -246
  110. data/src/ruby/nodes/case.js +0 -65
  111. data/src/ruby/nodes/class.js +0 -64
  112. data/src/ruby/nodes/commands.js +0 -131
  113. data/src/ruby/nodes/conditionals.js +0 -282
  114. data/src/ruby/nodes/constants.js +0 -43
  115. data/src/ruby/nodes/flow.js +0 -74
  116. data/src/ruby/nodes/hashes.js +0 -155
  117. data/src/ruby/nodes/heredocs.js +0 -36
  118. data/src/ruby/nodes/hooks.js +0 -34
  119. data/src/ruby/nodes/ints.js +0 -31
  120. data/src/ruby/nodes/lambdas.js +0 -76
  121. data/src/ruby/nodes/loops.js +0 -98
  122. data/src/ruby/nodes/massign.js +0 -98
  123. data/src/ruby/nodes/methods.js +0 -74
  124. data/src/ruby/nodes/operators.js +0 -83
  125. data/src/ruby/nodes/params.js +0 -106
  126. data/src/ruby/nodes/patterns.js +0 -157
  127. data/src/ruby/nodes/regexp.js +0 -56
  128. data/src/ruby/nodes/rescue.js +0 -101
  129. data/src/ruby/nodes/return.js +0 -94
  130. data/src/ruby/nodes/statements.js +0 -142
  131. data/src/ruby/nodes/strings.js +0 -272
  132. data/src/ruby/nodes/super.js +0 -35
  133. data/src/ruby/nodes/undef.js +0 -42
  134. data/src/ruby/nodes.js +0 -34
  135. data/src/ruby/parser.js +0 -37
  136. data/src/ruby/printer.js +0 -147
  137. data/src/ruby/toProc.js +0 -105
  138. data/src/utils/containsAssignment.js +0 -11
  139. data/src/utils/getTrailingComma.js +0 -5
  140. data/src/utils/hasAncestor.js +0 -17
  141. data/src/utils/isEmptyBodyStmt.js +0 -7
  142. data/src/utils/isEmptyStmts.js +0 -11
  143. data/src/utils/literal.js +0 -7
  144. data/src/utils/literallineWithoutBreakParent.js +0 -7
  145. data/src/utils/makeCall.js +0 -14
  146. data/src/utils/noIndent.js +0 -10
  147. data/src/utils/printEmptyCollection.js +0 -49
  148. data/src/utils/skipAssignIndent.js +0 -17
  149. data/src/utils.js +0 -13
@@ -1,56 +0,0 @@
1
- const { concat } = require("../../prettier");
2
- const { hasAncestor } = require("../../utils");
3
-
4
- function hasContent(node, pattern) {
5
- return node.body.some(
6
- (child) => child.type === "@tstring_content" && pattern.test(child.body)
7
- );
8
- }
9
-
10
- // If the first part of this regex is plain string content, we have a space
11
- // or an =, and we're contained within a command or command_call node, then we
12
- // want to use braces because otherwise we could end up with an ambiguous
13
- // operator, e.g. foo / bar/ or foo /=bar/
14
- function forwardSlashIsAmbiguous(path) {
15
- const node = path.getValue();
16
- const firstChildNode = node.body[0];
17
-
18
- return (
19
- firstChildNode &&
20
- firstChildNode.type === "@tstring_content" &&
21
- [" ", "="].includes(firstChildNode.body[0]) &&
22
- hasAncestor(path, ["command", "command_call"])
23
- );
24
- }
25
-
26
- // This function is responsible for printing out regexp_literal nodes. They can
27
- // either use the special %r literal syntax or they can use forward slashes. At
28
- // the end of either of those they can have modifiers like m or x that have
29
- // special meaning for the regex engine.
30
- //
31
- // We favor the use of forward slashes unless the regex contains a forward slash
32
- // itself. In that case we switch over to using %r with braces.
33
- function printRegexpLiteral(path, opts, print) {
34
- const node = path.getValue();
35
- const docs = path.map(print, "body");
36
-
37
- // We should use braces if using a forward slash would be ambiguous in the
38
- // current context or if there's a forward slash in the content of the regexp.
39
- const useBraces = forwardSlashIsAmbiguous(path) || hasContent(node, /\//);
40
-
41
- // If we should be using braces but we have braces in the body of the regexp,
42
- // then we're just going to resort to using whatever the original content was.
43
- if (useBraces && hasContent(node, /[{}]/)) {
44
- return concat([node.beging].concat(docs).concat(node.ending));
45
- }
46
-
47
- return concat(
48
- [useBraces ? "%r{" : "/"]
49
- .concat(docs)
50
- .concat(useBraces ? "}" : "/", node.ending.slice(1))
51
- );
52
- }
53
-
54
- module.exports = {
55
- regexp_literal: printRegexpLiteral
56
- };
@@ -1,101 +0,0 @@
1
- const {
2
- align,
3
- concat,
4
- group,
5
- hardline,
6
- indent,
7
- join,
8
- line
9
- } = require("../../prettier");
10
- const { literal } = require("../../utils");
11
-
12
- function printBegin(path, opts, print) {
13
- return concat([
14
- "begin",
15
- indent(concat([hardline, concat(path.map(print, "body"))])),
16
- hardline,
17
- "end"
18
- ]);
19
- }
20
-
21
- function printEnsure(path, opts, print) {
22
- return concat([
23
- path.call(print, "body", 0),
24
- indent(concat([hardline, path.call(print, "body", 1)]))
25
- ]);
26
- }
27
-
28
- function printRescue(path, opts, print) {
29
- const parts = ["rescue"];
30
-
31
- if (path.getValue().body[0]) {
32
- parts.push(align("rescue ".length, path.call(print, "body", 0)));
33
- } else {
34
- // If you don't specify an error to rescue in a `begin/rescue` block, then
35
- // implicitly you're rescuing from `StandardError`. In this case, we're
36
- // just going to explicitly add it.
37
- parts.push(" StandardError");
38
- }
39
-
40
- const bodystmt = path.call(print, "body", 1);
41
-
42
- if (bodystmt.parts.length > 0) {
43
- parts.push(indent(concat([hardline, bodystmt])));
44
- }
45
-
46
- // This is the next clause on the `begin` statement, either another
47
- // `rescue`, and `ensure`, or an `else` clause.
48
- if (path.getValue().body[2]) {
49
- parts.push(concat([hardline, path.call(print, "body", 2)]));
50
- }
51
-
52
- return group(concat(parts));
53
- }
54
-
55
- // This is a container node that we're adding into the AST that isn't present in
56
- // Ripper solely so that we have a nice place to attach inline comments.
57
- function printRescueEx(path, opts, print) {
58
- const [exception, variable] = path.getValue().body;
59
- const parts = [];
60
-
61
- if (exception) {
62
- let exceptionDoc = path.call(print, "body", 0);
63
-
64
- if (Array.isArray(exceptionDoc)) {
65
- const joiner = concat([",", line]);
66
- exceptionDoc = group(join(joiner, exceptionDoc));
67
- }
68
-
69
- parts.push(" ", exceptionDoc);
70
- }
71
-
72
- if (variable) {
73
- parts.push(" => ", path.call(print, "body", 1));
74
- }
75
-
76
- return group(concat(parts));
77
- }
78
-
79
- function printRescueMod(path, opts, print) {
80
- const [statementDoc, valueDoc] = path.map(print, "body");
81
-
82
- return concat([
83
- "begin",
84
- indent(concat([hardline, statementDoc])),
85
- hardline,
86
- "rescue StandardError",
87
- indent(concat([hardline, valueDoc])),
88
- hardline,
89
- "end"
90
- ]);
91
- }
92
-
93
- module.exports = {
94
- begin: printBegin,
95
- ensure: printEnsure,
96
- redo: literal("redo"),
97
- rescue: printRescue,
98
- rescue_ex: printRescueEx,
99
- rescue_mod: printRescueMod,
100
- retry: literal("retry")
101
- };
@@ -1,94 +0,0 @@
1
- const {
2
- concat,
3
- group,
4
- ifBreak,
5
- indent,
6
- line,
7
- join,
8
- softline
9
- } = require("../../prettier");
10
- const { literal } = require("../../utils");
11
-
12
- // You can't skip the parentheses if you have comments or certain operators with
13
- // lower precedence than the return keyword.
14
- const canSkipParens = (args) => {
15
- const stmts = args.body[0].body[0];
16
-
17
- // return(
18
- // # a
19
- // b
20
- // )
21
- if (stmts.comments) {
22
- return false;
23
- }
24
-
25
- const stmt = stmts.body[0];
26
-
27
- // return (a or b)
28
- if (stmt.type === "binary" && ["and", "or"].includes(stmt.body[1])) {
29
- return false;
30
- }
31
-
32
- // return (not a)
33
- if (stmt.type === "unary" && stmt.oper === "not") {
34
- return false;
35
- }
36
-
37
- return true;
38
- };
39
-
40
- const printReturn = (path, opts, print) => {
41
- let args = path.getValue().body[0].body[0];
42
- let steps = ["body", 0, "body", 0];
43
-
44
- if (args.body.length === 1) {
45
- // If the body of the return contains parens, then just skip directly to the
46
- // content of the parens so that we can skip printing parens if we don't
47
- // want them.
48
- if (args.body[0] && args.body[0].type === "paren" && canSkipParens(args)) {
49
- args = args.body[0].body[0];
50
- steps = steps.concat("body", 0, "body", 0);
51
- }
52
-
53
- // If we're returning an array literal that isn't a special array, single
54
- // element array, or an empty array, then we want to grab the arguments so
55
- // that we can print them out as if they were normal return arguments.
56
- if (
57
- args.body[0] &&
58
- args.body[0].type === "array" &&
59
- args.body[0].body[0] &&
60
- args.body[0].body[0].body.length > 1 &&
61
- ["args", "args_add_star"].includes(args.body[0].body[0].type)
62
- ) {
63
- steps = steps.concat("body", 0, "body", 0);
64
- }
65
- }
66
-
67
- // Now that we've established which actual node is the arguments to return,
68
- // we grab it out of the path by diving down the steps that we've set up.
69
- const parts = path.call.apply(path, [print].concat(steps));
70
-
71
- // If we got the value straight out of the parens, then `parts` would only
72
- // be a singular doc as opposed to an array.
73
- const value = Array.isArray(parts) ? join(concat([",", line]), parts) : parts;
74
-
75
- // We only get here if we have comments somewhere that would prevent us from
76
- // skipping the parentheses.
77
- if (args.body.length === 1 && args.body[0].type === "paren") {
78
- return concat(["return", value]);
79
- }
80
-
81
- return group(
82
- concat([
83
- "return",
84
- ifBreak(parts.length > 1 ? " [" : "(", " "),
85
- indent(concat([softline, value])),
86
- concat([softline, ifBreak(parts.length > 1 ? "]" : ")", "")])
87
- ])
88
- );
89
- };
90
-
91
- module.exports = {
92
- return: printReturn,
93
- return0: literal("return")
94
- };
@@ -1,142 +0,0 @@
1
- const {
2
- breakParent,
3
- concat,
4
- dedent,
5
- group,
6
- hardline,
7
- indent,
8
- join,
9
- line,
10
- literalline,
11
- softline,
12
- trim
13
- } = require("../../prettier");
14
-
15
- const { isEmptyStmts } = require("../../utils");
16
-
17
- function printBodyStmt(path, opts, print) {
18
- const [stmts, rescue, elseClause, ensure] = path.getValue().body;
19
- const parts = [];
20
-
21
- if (!isEmptyStmts(stmts)) {
22
- parts.push(path.call(print, "body", 0));
23
- }
24
-
25
- if (rescue) {
26
- parts.push(dedent(concat([hardline, path.call(print, "body", 1)])));
27
- }
28
-
29
- if (elseClause) {
30
- // Before Ruby 2.6, this piece of bodystmt was an explicit "else" node
31
- /* istanbul ignore next */
32
- const stmts =
33
- elseClause.type === "else"
34
- ? path.call(print, "body", 2, "body", 0)
35
- : path.call(print, "body", 2);
36
-
37
- parts.push(concat([dedent(concat([hardline, "else"])), hardline, stmts]));
38
- }
39
-
40
- if (ensure) {
41
- parts.push(dedent(concat([hardline, path.call(print, "body", 3)])));
42
- }
43
-
44
- return group(concat(parts));
45
- }
46
-
47
- const argNodeTypes = ["args", "args_add_star", "args_add_block"];
48
-
49
- function printParen(path, opts, print) {
50
- const contentNode = path.getValue().body[0];
51
-
52
- if (!contentNode) {
53
- return "()";
54
- }
55
-
56
- let contentDoc = path.call(print, "body", 0);
57
-
58
- // If the content is params, we're going to let it handle its own parentheses
59
- // so that it breaks nicely.
60
- if (contentNode.type === "params") {
61
- return contentDoc;
62
- }
63
-
64
- // If we have an arg type node as the contents, then it's going to return an
65
- // array, so we need to explicitly join that content here.
66
- if (argNodeTypes.includes(contentNode.type)) {
67
- contentDoc = join(concat([",", line]), contentDoc);
68
- }
69
-
70
- return group(
71
- concat(["(", indent(concat([softline, contentDoc])), softline, ")"])
72
- );
73
- }
74
-
75
- module.exports = {
76
- "@__end__": (path, _opts, _print) => {
77
- const { body } = path.getValue();
78
- return concat([trim, "__END__", literalline, body]);
79
- },
80
- "@comment"(path, opts, _print) {
81
- return opts.printer.printComment(path);
82
- },
83
- bodystmt: printBodyStmt,
84
- paren: printParen,
85
- program: (path, opts, print) =>
86
- concat([join(hardline, path.map(print, "body")), hardline]),
87
- stmts: (path, opts, print) => {
88
- const stmts = path.getValue().body;
89
-
90
- // This is a special case where we have only comments inside a statement
91
- // list. In this case we want to avoid doing any kind of line number
92
- // tracking and just print out the comments.
93
- if (
94
- stmts.length === 1 &&
95
- stmts[0].type === "void_stmt" &&
96
- stmts[0].comments
97
- ) {
98
- const comments = path.map(
99
- (commentPath) => {
100
- commentPath.getValue().printed = true;
101
- return opts.printer.printComment(commentPath);
102
- },
103
- "body",
104
- 0,
105
- "comments"
106
- );
107
-
108
- return concat([breakParent, join(hardline, comments)]);
109
- }
110
-
111
- const parts = [];
112
- let lineNo = null;
113
-
114
- stmts.forEach((stmt, index) => {
115
- if (stmt.type === "void_stmt") {
116
- return;
117
- }
118
-
119
- const printed = path.call(print, "body", index);
120
-
121
- if (lineNo === null) {
122
- parts.push(printed);
123
- } else if (
124
- stmt.sl - lineNo > 1 ||
125
- [stmt.type, stmts[index - 1].type].includes("access_ctrl")
126
- ) {
127
- parts.push(hardline, hardline, printed);
128
- } else if (
129
- stmt.sl !== lineNo ||
130
- path.getParentNode().type !== "string_embexpr"
131
- ) {
132
- parts.push(hardline, printed);
133
- } else {
134
- parts.push("; ", printed);
135
- }
136
-
137
- lineNo = stmt.el;
138
- });
139
-
140
- return concat(parts);
141
- }
142
- };
@@ -1,272 +0,0 @@
1
- const {
2
- concat,
3
- group,
4
- hardline,
5
- indent,
6
- literalline,
7
- removeLines,
8
- softline,
9
- join
10
- } = require("../../prettier");
11
-
12
- // If there is some part of this string that matches an escape sequence or that
13
- // contains the interpolation pattern ("#{"), then we are locked into whichever
14
- // quote the user chose. (If they chose single quotes, then double quoting
15
- // would activate the escape sequence, and if they chose double quotes, then
16
- // single quotes would deactivate it.)
17
- function isQuoteLocked(node) {
18
- return node.body.some(
19
- (part) =>
20
- part.type === "@tstring_content" &&
21
- (part.body.includes("#{") || part.body.includes("\\"))
22
- );
23
- }
24
-
25
- // A string is considered to be able to use single quotes if it contains only
26
- // plain string content and that content does not contain a single quote.
27
- function isSingleQuotable(node) {
28
- return node.body.every(
29
- (part) => part.type === "@tstring_content" && !part.body.includes("'")
30
- );
31
- }
32
-
33
- const quotePattern = new RegExp("\\\\([\\s\\S])|(['\"])", "g");
34
-
35
- function normalizeQuotes(content, enclosingQuote) {
36
- // Escape and unescape single and double quotes as needed to be able to
37
- // enclose `content` with `enclosingQuote`.
38
- return content.replace(quotePattern, (match, escaped, quote) => {
39
- if (quote === enclosingQuote) {
40
- return `\\${quote}`;
41
- }
42
-
43
- if (quote) {
44
- return quote;
45
- }
46
-
47
- return `\\${escaped}`;
48
- });
49
- }
50
-
51
- const quotePairs = {
52
- "(": ")",
53
- "[": "]",
54
- "{": "}",
55
- "<": ">"
56
- };
57
-
58
- function getClosingQuote(quote) {
59
- if (!quote.startsWith("%")) {
60
- return quote;
61
- }
62
-
63
- const boundary = /%[Qq]?(.)/.exec(quote)[1];
64
- if (boundary in quotePairs) {
65
- return quotePairs[boundary];
66
- }
67
-
68
- return boundary;
69
- }
70
-
71
- // Prints a @CHAR node. @CHAR nodes are special character strings that usually
72
- // are strings of length 1. If they're any longer than we'll try to apply the
73
- // correct quotes.
74
- function printChar(path, { rubySingleQuote }, _print) {
75
- const { body } = path.getValue();
76
-
77
- if (body.length !== 2) {
78
- return body;
79
- }
80
-
81
- const quote = rubySingleQuote ? "'" : '"';
82
- return concat([quote, body.slice(1), quote]);
83
- }
84
-
85
- function printPercentSDynaSymbol(path, opts, print) {
86
- const node = path.getValue();
87
- const parts = [];
88
-
89
- // Push on the quote, which includes the opening character.
90
- parts.push(node.quote);
91
-
92
- path.each((childPath) => {
93
- const childNode = childPath.getValue();
94
-
95
- if (childNode.type !== "@tstring_content") {
96
- // Here we are printing an embedded variable or expression.
97
- parts.push(print(childPath));
98
- } else {
99
- // Here we are printing plain string content.
100
- parts.push(join(literalline, childNode.body.split("\n")));
101
- }
102
- }, "body");
103
-
104
- // Push on the closing character, which is the opposite of the third
105
- // character from the opening.
106
- parts.push(quotePairs[node.quote[2]]);
107
-
108
- return concat(parts);
109
- }
110
-
111
- // We don't actually want to print %s symbols, as they're much more rarely seen
112
- // in the wild. But we're going to be forced into it if it's a multi-line symbol
113
- // or if the quoting would get super complicated.
114
- function shouldPrintPercentSDynaSymbol(node) {
115
- // We shouldn't print a %s dyna symbol if it was not already that way in the
116
- // original source.
117
- if (node.quote[0] !== "%") {
118
- return false;
119
- }
120
-
121
- // Here we're going to check if there is a closing character, a new line, or a
122
- // quote in the content of the dyna symbol. If there is, then quoting could
123
- // get weird, so just bail out and stick to the original bounds in the source.
124
- const closing = quotePairs[node.quote[2]];
125
-
126
- return node.body.some(
127
- (child) =>
128
- child.type === "@tstring_content" &&
129
- (child.body.includes("\n") ||
130
- child.body.includes(closing) ||
131
- child.body.includes("'") ||
132
- child.body.includes('"'))
133
- );
134
- }
135
-
136
- // Prints a dynamic symbol. Assumes there's a quote property attached to the
137
- // node that will tell us which quote to use when printing. We're just going to
138
- // use whatever quote was provided.
139
- //
140
- // In the case of a plain dyna symbol, node.quote will be either :" or :'
141
- // For %s dyna symbols, node.quote will be %s[, %s(, %s{, or %s<
142
- function printDynaSymbol(path, opts, print) {
143
- const node = path.getValue();
144
-
145
- if (shouldPrintPercentSDynaSymbol(node)) {
146
- return printPercentSDynaSymbol(path, opts, print);
147
- }
148
-
149
- const parts = [];
150
- let quote;
151
-
152
- if (isQuoteLocked(node)) {
153
- if (node.quote.startsWith("%")) {
154
- quote = opts.rubySingleQuote ? "'" : '"';
155
- } else if (node.quote.startsWith(":")) {
156
- quote = node.quote.slice(1);
157
- } else {
158
- quote = node.quote;
159
- }
160
- } else {
161
- quote = opts.rubySingleQuote && isSingleQuotable(node) ? "'" : '"';
162
- }
163
-
164
- parts.push(quote);
165
- path.each((childPath) => {
166
- const child = childPath.getValue();
167
-
168
- if (child.type !== "@tstring_content") {
169
- parts.push(print(childPath));
170
- } else {
171
- parts.push(
172
- join(literalline, normalizeQuotes(child.body, quote).split("\n"))
173
- );
174
- }
175
- }, "body");
176
-
177
- parts.push(quote);
178
-
179
- // If we're inside of an assoc_new node as the key, then it will handle
180
- // printing the : on its own since it could change sides.
181
- const parentNode = path.getParentNode();
182
- if (parentNode.type !== "assoc_new" || parentNode.body[0] !== node) {
183
- parts.unshift(":");
184
- }
185
-
186
- return concat(parts);
187
- }
188
-
189
- function printStringConcat(path, opts, print) {
190
- const [leftDoc, rightDoc] = path.map(print, "body");
191
-
192
- return group(concat([leftDoc, " \\", indent(concat([hardline, rightDoc]))]));
193
- }
194
-
195
- // Prints out an interpolated variable in the string by converting it into an
196
- // embedded expression.
197
- function printStringDVar(path, opts, print) {
198
- return concat(["#{", path.call(print, "body", 0), "}"]);
199
- }
200
-
201
- function printStringEmbExpr(path, opts, print) {
202
- const node = path.getValue();
203
- const parts = path.call(print, "body", 0);
204
-
205
- // If the contents of this embedded expression were originally on the same
206
- // line in the source, then we're going to leave them in place and assume
207
- // that's the way the developer wanted this expression represented.
208
- if (node.sl === node.el) {
209
- return concat(["#{", removeLines(parts), "}"]);
210
- }
211
-
212
- return group(
213
- concat(["#{", indent(concat([softline, parts])), concat([softline, "}"])])
214
- );
215
- }
216
-
217
- // Prints out a literal string. This function does its best to respect the
218
- // wishes of the user with regards to single versus double quotes, but if the
219
- // string contains any escape expressions then it will just keep the original
220
- // quotes.
221
- function printStringLiteral(path, { rubySingleQuote }, print) {
222
- const node = path.getValue();
223
-
224
- // If the string is empty, it will not have any parts, so just print out the
225
- // quotes corresponding to the config
226
- if (node.body.length === 0) {
227
- return rubySingleQuote ? "''" : '""';
228
- }
229
-
230
- // Determine the quote that should enclose the new string
231
- let quote;
232
- if (isQuoteLocked(node)) {
233
- quote = node.quote;
234
- } else {
235
- quote = rubySingleQuote && isSingleQuotable(node) ? "'" : '"';
236
- }
237
-
238
- const parts = node.body.map((part, index) => {
239
- if (part.type !== "@tstring_content") {
240
- // In this case, the part of the string is an embedded expression
241
- return path.call(print, "body", index);
242
- }
243
-
244
- // In this case, the part of the string is just regular string content
245
- return join(literalline, normalizeQuotes(part.body, quote).split("\n"));
246
- });
247
-
248
- return concat([quote].concat(parts).concat(getClosingQuote(quote)));
249
- }
250
-
251
- // Prints out a symbol literal. Its child will always be the ident that
252
- // represents the string content of the symbol.
253
- function printSymbolLiteral(path, opts, print) {
254
- return concat([":", path.call(print, "body", 0)]);
255
- }
256
-
257
- // Prints out an xstring literal. Its child is an array of string parts,
258
- // including plain string content and interpolated content.
259
- function printXStringLiteral(path, opts, print) {
260
- return concat(["`"].concat(path.map(print, "body")).concat("`"));
261
- }
262
-
263
- module.exports = {
264
- "@CHAR": printChar,
265
- dyna_symbol: printDynaSymbol,
266
- string_concat: printStringConcat,
267
- string_dvar: printStringDVar,
268
- string_embexpr: printStringEmbExpr,
269
- string_literal: printStringLiteral,
270
- symbol_literal: printSymbolLiteral,
271
- xstring_literal: printXStringLiteral
272
- };
@@ -1,35 +0,0 @@
1
- const { align, concat, group, join, line } = require("../../prettier");
2
- const { literal } = require("../../utils");
3
-
4
- function printSuper(path, opts, print) {
5
- const args = path.getValue().body[0];
6
-
7
- if (args.type === "arg_paren") {
8
- // In case there are explicitly no arguments but they are using parens,
9
- // we assume they are attempting to override the initializer and pass no
10
- // arguments up.
11
- if (args.body[0] === null) {
12
- return "super()";
13
- }
14
-
15
- return concat(["super", path.call(print, "body", 0)]);
16
- }
17
-
18
- const keyword = "super ";
19
- const argsDocs = path.call(print, "body", 0);
20
-
21
- return group(
22
- concat([
23
- keyword,
24
- align(keyword.length, group(join(concat([",", line]), argsDocs)))
25
- ])
26
- );
27
- }
28
-
29
- // Version of super without any parens or args.
30
- const printZSuper = literal("super");
31
-
32
- module.exports = {
33
- super: printSuper,
34
- zsuper: printZSuper
35
- };