prettier 0.18.0 → 0.18.1

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prettier/plugin-ruby",
3
- "version": "0.18.0",
3
+ "version": "0.18.1",
4
4
  "description": "prettier plugin for the Ruby programming language",
5
5
  "main": "src/ruby.js",
6
6
  "scripts": {
@@ -22,17 +22,38 @@
22
22
  "prettier": ">=1.10"
23
23
  },
24
24
  "devDependencies": {
25
- "all-contributors-cli": "^6.12.0",
25
+ "all-contributors-cli": "^6.14.1",
26
26
  "eslint": "^6.8.0",
27
- "eslint-config-airbnb-base": "^14.0.0",
28
- "eslint-config-prettier": "^6.9.0",
29
- "eslint-plugin-import": "^2.20.0",
30
- "jest": "^25.1.0"
27
+ "eslint-config-prettier": "^6.10.1",
28
+ "jest": "^25.2.7"
29
+ },
30
+ "eslintConfig": {
31
+ "extends": [
32
+ "eslint:recommended",
33
+ "prettier"
34
+ ],
35
+ "env": {
36
+ "es6": true,
37
+ "jest": true,
38
+ "node": true
39
+ },
40
+ "rules": {
41
+ "no-unused-vars": [
42
+ "error",
43
+ {
44
+ "argsIgnorePattern": "^_",
45
+ "varsIgnorePattern": "^_"
46
+ }
47
+ ]
48
+ }
31
49
  },
32
50
  "jest": {
33
51
  "setupFilesAfterEnv": [
34
52
  "./test/js/setupTests.js"
35
53
  ],
36
54
  "testRegex": ".test.js$"
55
+ },
56
+ "prettier": {
57
+ "trailingComma": "none"
37
58
  }
38
59
  }
@@ -3,13 +3,13 @@ const parse = require("./haml/parse");
3
3
  const print = require("./haml/print");
4
4
 
5
5
  const pragmaPattern = /^\s*-#\s*@(prettier|format)/;
6
- const hasPragma = text => pragmaPattern.test(text);
6
+ const hasPragma = (text) => pragmaPattern.test(text);
7
7
 
8
8
  // These functions are just placeholders until we can actually perform this
9
9
  // properly. The functions are necessary otherwise the format with cursor
10
10
  // functions break.
11
- const locStart = _node => 0;
12
- const locEnd = _node => 0;
11
+ const locStart = (_node) => 0;
12
+ const locEnd = (_node) => 0;
13
13
 
14
14
  module.exports = {
15
15
  embed,
@@ -17,8 +17,8 @@ const parsers = {
17
17
  scss: "scss"
18
18
  };
19
19
 
20
- const replaceNewlines = doc =>
21
- mapDoc(doc, currentDoc =>
20
+ const replaceNewlines = (doc) =>
21
+ mapDoc(doc, (currentDoc) =>
22
22
  typeof currentDoc === "string" && currentDoc.includes("\n")
23
23
  ? concat(
24
24
  currentDoc
@@ -4,6 +4,7 @@ const {
4
4
  fill,
5
5
  group,
6
6
  hardline,
7
+ ifBreak,
7
8
  indent,
8
9
  join,
9
10
  line,
@@ -14,10 +15,10 @@ const getDynamicAttributes = (header, attributes) => {
14
15
  const pairs = attributes
15
16
  .slice(1, -2)
16
17
  .split(",")
17
- .map(pair => pair.slice(1).split('" => '));
18
+ .map((pair) => pair.slice(1).split('" => '));
18
19
  const parts = [concat([pairs[0][0], "=", pairs[0][1]])];
19
20
 
20
- pairs.slice(1).forEach(pair => {
21
+ pairs.slice(1).forEach((pair) => {
21
22
  parts.push(line, concat([pair[0], "=", pair[1]]));
22
23
  });
23
24
 
@@ -49,13 +50,13 @@ const getHashLabel = (key, value, opts) => {
49
50
 
50
51
  const getStaticAttributes = (header, attributes, opts) => {
51
52
  const keys = Object.keys(attributes).filter(
52
- name => !["class", "id"].includes(name)
53
+ (name) => !["class", "id"].includes(name)
53
54
  );
54
55
 
55
56
  const getKeyValuePair = opts.preferHashLabels ? getHashLabel : getHashRocket;
56
57
  const parts = [getKeyValuePair(keys[0], attributes[keys[0]], opts)];
57
58
 
58
- keys.slice(1).forEach(key => {
59
+ keys.slice(1).forEach((key) => {
59
60
  parts.push(",", line, getKeyValuePair(key, attributes[key], opts));
60
61
  });
61
62
 
@@ -84,11 +85,16 @@ const getHeader = (value, opts) => {
84
85
  );
85
86
  }
86
87
 
87
- if (Object.keys(attributes).some(name => name !== "class" && name !== "id")) {
88
+ if (
89
+ Object.keys(attributes).some((name) => name !== "class" && name !== "id")
90
+ ) {
88
91
  parts.push(getStaticAttributes(parts.join("").length, attributes, opts));
89
92
  }
90
93
 
91
94
  if (value.dynamic_attributes.old) {
95
+ if (parts.length === 0) {
96
+ parts.push("%div");
97
+ }
92
98
  parts.push(value.dynamic_attributes.old);
93
99
  }
94
100
 
@@ -112,12 +118,12 @@ const getHeader = (value, opts) => {
112
118
  }
113
119
 
114
120
  if (value.value) {
115
- const prefix = value.parse ? "=" : "";
121
+ const prefix = value.parse ? "= " : ifBreak("", " ");
116
122
 
117
123
  return group(
118
124
  concat([
119
125
  group(concat(parts)),
120
- indent(concat([softline, `${prefix} ${value.value}`]))
126
+ indent(concat([softline, prefix, value.value]))
121
127
  ])
122
128
  );
123
129
  }
@@ -1,7 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'json'
4
-
5
3
  require 'bundler/setup' if ENV['CI']
6
4
  require 'haml'
7
5
 
@@ -48,18 +46,17 @@ class Haml::Parser::ParseNode
48
46
  raise ArgumentError, "Unsupported type: #{type}"
49
47
  end
50
48
  end
51
-
52
- def self.to_json(template)
53
- parser = Haml::Parser.new({})
54
- JSON.fast_generate(parser.call(template).as_json)
55
- end
56
49
  end
57
50
 
58
51
  # If this is the main file we're executing, then most likely this is being
59
52
  # executed from the haml.js spawn. In that case, read the ruby source from
60
53
  # stdin and report back the AST over stdout.
61
-
62
54
  if $0 == __FILE__
55
+ # Don't explicitly require JSON if there is already as JSON loaded, as this
56
+ # can lead to all kinds of trouble where one version of it was already
57
+ # "activated" by rubygems.
58
+ require 'json' unless defined?(JSON)
59
+
63
60
  parser = Haml::Parser.new({})
64
61
  template = $stdin.read
65
62
 
@@ -1,7 +1,7 @@
1
1
  const { concat, join } = require("../prettier");
2
2
 
3
- const usingSymbols = path => {
4
- const [left, right] = path.getValue().body.map(node => node.body[0].type);
3
+ const usingSymbols = (path) => {
4
+ const [left, right] = path.getValue().body.map((node) => node.body[0].type);
5
5
  return left === "symbol" && right === "symbol";
6
6
  };
7
7
 
@@ -62,7 +62,7 @@ module.exports = {
62
62
  // method_add_block node, and if they are that that node has a block
63
63
  // associated with it. If it does, we're going to attempt to transform it
64
64
  // into the to_proc shorthand and add it to the list of arguments.
65
- [1, 2, 3].find(parent => {
65
+ [1, 2, 3].find((parent) => {
66
66
  const parentNode = path.getParentNode(parent);
67
67
  blockNode =
68
68
  parentNode &&
@@ -9,19 +9,19 @@ const {
9
9
  softline
10
10
  } = require("../prettier");
11
11
 
12
- const isStringArray = args =>
12
+ const isStringArray = (args) =>
13
13
  args.body.every(
14
- arg =>
14
+ (arg) =>
15
15
  arg.type === "string_literal" &&
16
16
  arg.body[0].body.length === 1 &&
17
17
  arg.body[0].body[0].type === "@tstring_content" &&
18
18
  !arg.body[0].body[0].body.includes(" ")
19
19
  );
20
20
 
21
- const isSymbolArray = args =>
22
- args.body.every(arg => arg.type === "symbol_literal");
21
+ const isSymbolArray = (args) =>
22
+ args.body.every((arg) => arg.type === "symbol_literal");
23
23
 
24
- const makeArray = start => (path, opts, print) =>
24
+ const makeArray = (start) => (path, opts, print) =>
25
25
  [start].concat(path.map(print, "body"));
26
26
 
27
27
  const getSpecialArrayParts = (path, print, args) =>
@@ -44,7 +44,7 @@ const printAref = (path, opts, print) =>
44
44
  ])
45
45
  );
46
46
 
47
- const printSpecialArray = parts =>
47
+ const printSpecialArray = (parts) =>
48
48
  group(
49
49
  concat([
50
50
  parts[0],
@@ -10,7 +10,7 @@ const {
10
10
  } = require("../prettier");
11
11
  const { empty, hasAncestor } = require("../utils");
12
12
 
13
- const printBlock = (path, opts, print) => {
13
+ const printBlock = (braces) => (path, opts, print) => {
14
14
  const [variables, statements] = path.getValue().body;
15
15
  const stmts =
16
16
  statements.type === "stmts" ? statements.body : statements.body[0].body;
@@ -25,7 +25,7 @@ const printBlock = (path, opts, print) => {
25
25
  // as opposed to the current node (because of the difference in operator
26
26
  // precedence). Instead, we still use a multi-line format but switch to using
27
27
  // braces instead.
28
- const useBraces = hasAncestor(path, ["command", "command_call"]);
28
+ const useBraces = braces && hasAncestor(path, ["command", "command_call"]);
29
29
 
30
30
  const doBlock = concat([
31
31
  useBraces ? " {" : " do",
@@ -38,7 +38,7 @@ const printBlock = (path, opts, print) => {
38
38
  // comment.
39
39
  if (
40
40
  stmts.length > 1 &&
41
- stmts.filter(stmt => stmt.type !== "@comment").length === 1
41
+ stmts.filter((stmt) => stmt.type !== "@comment").length === 1
42
42
  ) {
43
43
  return concat([breakParent, doBlock]);
44
44
  }
@@ -74,7 +74,7 @@ module.exports = {
74
74
  parts.push("| ");
75
75
  return concat(parts);
76
76
  },
77
- brace_block: printBlock,
78
- do_block: printBlock,
77
+ brace_block: printBlock(true),
78
+ do_block: printBlock(false),
79
79
  excessed_comma: empty
80
80
  };
@@ -1,29 +1,64 @@
1
- const { concat, group, indent, softline } = require("../prettier");
1
+ const { concat, group, indent, hardline, softline } = require("../prettier");
2
2
  const toProc = require("../toProc");
3
3
  const { concatBody, first, makeCall } = require("../utils");
4
4
 
5
5
  const noIndent = ["array", "hash", "if", "method_add_block", "xstring_literal"];
6
6
 
7
+ const getHeredoc = (path, print, node) => {
8
+ if (node.type === "heredoc") {
9
+ const { beging, ending } = node;
10
+ return { beging, ending, content: ["body", 0, "body"] };
11
+ }
12
+
13
+ if (node.type === "string_literal" && node.body[0].type === "heredoc") {
14
+ const { beging, ending } = node.body[0];
15
+ return { beging, ending, content: ["body", 0, "body", 0, "body"] };
16
+ }
17
+
18
+ return null;
19
+ };
20
+
7
21
  module.exports = {
8
22
  call: (path, opts, print) => {
9
- const receiver = path.call(print, "body", 0);
10
- const operator = makeCall(path, opts, print);
11
- let name = path.getValue().body[2];
23
+ const [receiverNode, _operatorNode, messageNode] = path.getValue().body;
24
+
25
+ const printedReceiver = path.call(print, "body", 0);
26
+ const printedOperator = makeCall(path, opts, print);
12
27
 
13
28
  // You can call lambdas with a special syntax that looks like func.(*args).
14
29
  // In this case, "call" is returned for the 3rd child node.
15
- if (name !== "call") {
16
- name = path.call(print, "body", 2);
30
+ const printedMessage =
31
+ messageNode === "call" ? messageNode : path.call(print, "body", 2);
32
+
33
+ // If we have a heredoc as a receiver, then we need to move the operator and
34
+ // the message up to start of the heredoc declaration, as in:
35
+ //
36
+ // <<~TEXT.strip
37
+ // content
38
+ // TEXT
39
+ const heredoc = getHeredoc(path, print, receiverNode);
40
+ if (heredoc) {
41
+ return concat([
42
+ heredoc.beging,
43
+ printedOperator,
44
+ printedMessage,
45
+ hardline,
46
+ concat(path.map.apply(path, [print].concat(heredoc.content))),
47
+ heredoc.ending
48
+ ]);
17
49
  }
18
50
 
19
51
  // For certain left sides of the call nodes, we want to attach directly to
20
52
  // the } or end.
21
- if (noIndent.includes(path.getValue().body[0].type)) {
22
- return concat([receiver, operator, name]);
53
+ if (noIndent.includes(receiverNode.type)) {
54
+ return concat([printedReceiver, printedOperator, printedMessage]);
23
55
  }
24
56
 
25
57
  return group(
26
- concat([receiver, group(indent(concat([softline, operator, name])))])
58
+ concat([
59
+ printedReceiver,
60
+ group(indent(concat([softline, printedOperator, printedMessage])))
61
+ ])
27
62
  );
28
63
  },
29
64
  fcall: concatBody,
@@ -42,7 +42,7 @@ module.exports = {
42
42
 
43
43
  // It's possible in a when to just have empty void statements, in which case
44
44
  // we would skip adding the body.
45
- if (!stmts.parts.every(part => !part)) {
45
+ if (!stmts.parts.every((part) => !part)) {
46
46
  parts.push(indent(concat([hardline, stmts])));
47
47
  }
48
48
 
@@ -1,7 +1,7 @@
1
1
  const { align, concat, group, ifBreak, join, line } = require("../prettier");
2
2
  const { docLength, makeArgs, makeCall } = require("../utils");
3
3
 
4
- const hasDef = node =>
4
+ const hasDef = (node) =>
5
5
  node.body[1].type === "args_add_block" &&
6
6
  node.body[1].body[0].type === "args" &&
7
7
  node.body[1].body[0].body[0] &&
@@ -20,7 +20,7 @@ const hasDef = node =>
20
20
  //
21
21
  // In this case the arguments are aligned to the left side as opposed to being
22
22
  // aligned with the `receive` call.
23
- const skipArgsAlign = path =>
23
+ const skipArgsAlign = (path) =>
24
24
  ["to", "not_to"].includes(path.getValue().body[2].body);
25
25
 
26
26
  module.exports = {
@@ -23,7 +23,7 @@ const printWithAddition = (keyword, path, print, { breaking = false } = {}) =>
23
23
  // For the unary `not` operator, we need to explicitly add parentheses to it in
24
24
  // order for it to be valid from within a ternary. Otherwise if the clause of
25
25
  // the ternary isn't a unary `not`, we can just pass it along.
26
- const printTernaryClause = clause => {
26
+ const printTernaryClause = (clause) => {
27
27
  if (clause.type === "concat") {
28
28
  const [part] = clause.parts;
29
29
 
@@ -78,7 +78,7 @@ const printTernary = (path, _opts, print) => {
78
78
  // Prints an `if_mod` or `unless_mod` node. Because it was previously in the
79
79
  // modifier form, we're guaranteed to not have an additional node, so we can
80
80
  // just work with the predicate and the body.
81
- const printSingle = keyword => (path, { inlineConditionals }, print) => {
81
+ const printSingle = (keyword) => (path, { inlineConditionals }, print) => {
82
82
  const multiline = concat([
83
83
  `${keyword} `,
84
84
  align(keyword.length + 1, path.call(print, "body", 0)),
@@ -88,7 +88,8 @@ const printSingle = keyword => (path, { inlineConditionals }, print) => {
88
88
 
89
89
  const [_predicate, stmts] = path.getValue().body;
90
90
  const hasComments =
91
- stmts.type === "stmts" && stmts.body.some(stmt => stmt.type === "@comment");
91
+ stmts.type === "stmts" &&
92
+ stmts.body.some((stmt) => stmt.type === "@comment");
92
93
 
93
94
  if (!inlineConditionals || hasComments) {
94
95
  return multiline;
@@ -152,7 +153,7 @@ const noTernary = [
152
153
  // Certain expressions cannot be reduced to a ternary without adding parens
153
154
  // around them. In this case we say they cannot be ternaried and default instead
154
155
  // to breaking them into multiple lines.
155
- const canTernaryStmts = stmts => {
156
+ const canTernaryStmts = (stmts) => {
156
157
  if (stmts.body.length !== 1) {
157
158
  return false;
158
159
  }
@@ -175,7 +176,7 @@ const canTernaryStmts = stmts => {
175
176
  // is of the "else" type. Both the body of the main node and the body of the
176
177
  // additional node must have only one statement, and that statement list must
177
178
  // pass the `canTernaryStmts` check.
178
- const canTernary = path => {
179
+ const canTernary = (path) => {
179
180
  const [_pred, stmts, addition] = path.getValue().body;
180
181
 
181
182
  return (
@@ -186,7 +187,7 @@ const canTernary = path => {
186
187
  };
187
188
 
188
189
  // A normalized print function for both `if` and `unless` nodes.
189
- const printConditional = keyword => (path, { inlineConditionals }, print) => {
190
+ const printConditional = (keyword) => (path, { inlineConditionals }, print) => {
190
191
  if (canTernary(path)) {
191
192
  let ternaryParts = [path.call(print, "body", 0), " ? "].concat(
192
193
  printTernaryClauses(
@@ -12,7 +12,7 @@ const { prefix, skipAssignIndent } = require("../utils");
12
12
  const nodeDive = (node, steps) => {
13
13
  let current = node;
14
14
 
15
- steps.forEach(step => {
15
+ steps.forEach((step) => {
16
16
  current = current[step];
17
17
  });
18
18
 
@@ -29,7 +29,7 @@ const nodeDive = (node, steps) => {
29
29
  //
30
30
  // This function represents that check, as it determines if it can convert the
31
31
  // symbol node into a hash label.
32
- const isValidHashLabel = symbolLiteral => {
32
+ const isValidHashLabel = (symbolLiteral) => {
33
33
  const label = symbolLiteral.body[0].body[0].body;
34
34
  return label.match(/^[_A-Za-z]/) && !label.endsWith("=");
35
35
  };
@@ -1,6 +1,6 @@
1
1
  const { concat, group, indent, line } = require("../prettier");
2
2
 
3
- const printHook = name => (path, opts, print) =>
3
+ const printHook = (name) => (path, opts, print) =>
4
4
  group(
5
5
  concat([
6
6
  `${name} {`,