prettier 0.18.1 → 0.20.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.1",
3
+ "version": "0.20.1",
4
4
  "description": "prettier plugin for the Ruby programming language",
5
5
  "main": "src/ruby.js",
6
6
  "scripts": {
@@ -23,9 +23,11 @@
23
23
  },
24
24
  "devDependencies": {
25
25
  "all-contributors-cli": "^6.14.1",
26
- "eslint": "^6.8.0",
26
+ "eslint": "^7.8.1",
27
27
  "eslint-config-prettier": "^6.10.1",
28
- "jest": "^25.2.7"
28
+ "husky": "^4.2.5",
29
+ "jest": "^26.0.0",
30
+ "pretty-quick": "^3.0.0"
29
31
  },
30
32
  "eslintConfig": {
31
33
  "extends": [
@@ -53,6 +55,11 @@
53
55
  ],
54
56
  "testRegex": ".test.js$"
55
57
  },
58
+ "husky": {
59
+ "hooks": {
60
+ "pre-commit": "pretty-quick --staged"
61
+ }
62
+ },
56
63
  "prettier": {
57
64
  "trailingComma": "none"
58
65
  }
@@ -0,0 +1,71 @@
1
+ const {
2
+ concat,
3
+ indent,
4
+ literalline,
5
+ mapDoc,
6
+ markAsRoot,
7
+ stripTrailingHardline
8
+ } = require("./prettier");
9
+
10
+ const parsers = {
11
+ css: "css",
12
+ javascript: "babel",
13
+ js: "babel",
14
+ less: "less",
15
+ markdown: "markdown",
16
+ ruby: "ruby",
17
+ scss: "scss"
18
+ };
19
+
20
+ const replaceNewlines = (doc) =>
21
+ mapDoc(doc, (currentDoc) =>
22
+ typeof currentDoc === "string" && currentDoc.includes("\n")
23
+ ? concat(
24
+ currentDoc
25
+ .split(/(\n)/g)
26
+ .map((v, i) => (i % 2 === 0 ? v : literalline))
27
+ )
28
+ : currentDoc
29
+ );
30
+
31
+ const embed = (path, _print, textToDoc, _opts) => {
32
+ const node = path.getValue();
33
+
34
+ // Currently we only support embedded formatting on heredoc nodes
35
+ if (node.type !== "heredoc") {
36
+ return null;
37
+ }
38
+
39
+ // First, ensure that we don't have any interpolation
40
+ const { beging, body, ending } = node;
41
+ if (body.some((part) => part.type !== "@tstring_content")) {
42
+ return null;
43
+ }
44
+
45
+ // Next, find the parser associated with this heredoc (if there is one). For
46
+ // example, if you use <<~CSS, we'd hook it up to the css parser.
47
+ const parser = parsers[beging.slice(3).toLowerCase()];
48
+ if (!parser) {
49
+ return null;
50
+ }
51
+
52
+ // Get the content as if it were a source string, and then pass that content
53
+ // into the embedded parser. Get back the doc node.
54
+ const content = body.map((part) => part.body).join("");
55
+ const formatted = concat([
56
+ literalline,
57
+ replaceNewlines(stripTrailingHardline(textToDoc(content, { parser })))
58
+ ]);
59
+
60
+ // If we're using a squiggly heredoc, then we can properly handle indentation
61
+ // ourselves.
62
+ if (beging[2] === "~") {
63
+ return concat([beging, indent(markAsRoot(formatted)), literalline, ending]);
64
+ }
65
+
66
+ // Otherwise, we need to just assume it's formatted correctly and return the
67
+ // content as it is.
68
+ return markAsRoot(concat([beging, formatted, literalline, ending]));
69
+ };
70
+
71
+ module.exports = embed;
@@ -72,7 +72,7 @@ module.exports = {
72
72
  return blockNode;
73
73
  });
74
74
 
75
- const proc = blockNode && toProc(blockNode);
75
+ const proc = blockNode && toProc(path, opts, blockNode);
76
76
 
77
77
  // If we have a successful to_proc transformation, but we're part of an aref
78
78
  // node, that means it's something to the effect of
@@ -9,13 +9,17 @@ const {
9
9
  softline
10
10
  } = require("../prettier");
11
11
 
12
+ const preserveArraySubstrings = [" ", "\\"];
13
+
12
14
  const isStringArray = (args) =>
13
15
  args.body.every(
14
16
  (arg) =>
15
17
  arg.type === "string_literal" &&
16
18
  arg.body[0].body.length === 1 &&
17
19
  arg.body[0].body[0].type === "@tstring_content" &&
18
- !arg.body[0].body[0].body.includes(" ")
20
+ !preserveArraySubstrings.some((str) =>
21
+ arg.body[0].body[0].body.includes(str)
22
+ )
19
23
  );
20
24
 
21
25
  const isSymbolArray = (args) =>
@@ -1,4 +1,4 @@
1
- const { concat, group, indent, hardline, softline } = require("../prettier");
1
+ const { concat, group, indent, literalline, softline } = require("../prettier");
2
2
  const toProc = require("../toProc");
3
3
  const { concatBody, first, makeCall } = require("../utils");
4
4
 
@@ -42,7 +42,7 @@ module.exports = {
42
42
  heredoc.beging,
43
43
  printedOperator,
44
44
  printedMessage,
45
- hardline,
45
+ literalline,
46
46
  concat(path.map.apply(path, [print].concat(heredoc.content))),
47
47
  heredoc.ending
48
48
  ]);
@@ -76,7 +76,7 @@ module.exports = {
76
76
  },
77
77
  method_add_block: (path, opts, print) => {
78
78
  const [method, block] = path.getValue().body;
79
- const proc = toProc(block);
79
+ const proc = toProc(path, opts, block);
80
80
 
81
81
  if (proc && method.type === "call") {
82
82
  return group(
@@ -177,9 +177,10 @@ const canTernaryStmts = (stmts) => {
177
177
  // additional node must have only one statement, and that statement list must
178
178
  // pass the `canTernaryStmts` check.
179
179
  const canTernary = (path) => {
180
- const [_pred, stmts, addition] = path.getValue().body;
180
+ const [predicate, stmts, addition] = path.getValue().body;
181
181
 
182
182
  return (
183
+ !["assign", "opassign"].includes(predicate.type) &&
183
184
  addition &&
184
185
  addition.type === "else" &&
185
186
  [stmts, addition.body[0]].every(canTernaryStmts)
@@ -53,7 +53,11 @@ module.exports = {
53
53
  parts.push(" StandardError");
54
54
  }
55
55
 
56
- parts.push(indent(concat([hardline, path.call(print, "body", 2)])));
56
+ const rescueBody = path.call(print, "body", 2);
57
+
58
+ if (rescueBody.parts.length > 0) {
59
+ parts.push(indent(concat([hardline, rescueBody])));
60
+ }
57
61
 
58
62
  // This is the next clause on the `begin` statement, either another
59
63
  // `rescue`, and `ensure`, or an `else` clause.
@@ -1,11 +1,27 @@
1
1
  const { spawnSync } = require("child_process");
2
2
  const path = require("path");
3
3
 
4
+ // In order to properly parse ruby code, we need to tell the ruby process to
5
+ // parse using UTF-8. Unfortunately, the way that you accomplish this looks
6
+ // differently depending on your platform. This object below represents all of
7
+ // the possible values of process.platform per:
8
+ // https://nodejs.org/api/process.html#process_process_platform
9
+ const LANG = {
10
+ aix: "C.UTF-8",
11
+ darwin: "en_US.UTF-8",
12
+ freebsd: "C.UTF-8",
13
+ linux: "C.UTF-8",
14
+ openbsd: "C.UTF-8",
15
+ sunos: "C.UTF-8",
16
+ win32: ".UTF-8"
17
+ }[process.platform];
18
+
4
19
  module.exports = (text, _parsers, _opts) => {
5
20
  const child = spawnSync(
6
21
  "ruby",
7
22
  ["--disable-gems", path.join(__dirname, "./ripper.rb")],
8
23
  {
24
+ env: Object.assign({}, process.env, { LANG }),
9
25
  input: text,
10
26
  maxBuffer: 10 * 1024 * 1024 // 10MB
11
27
  }
@@ -3,10 +3,11 @@
3
3
  # We implement our own version checking here instead of using Gem::Version so
4
4
  # that we can use the --disable-gems flag.
5
5
  major, minor, * = RUBY_VERSION.split('.').map(&:to_i)
6
+
6
7
  if (major < 2) || ((major == 2) && (minor < 5))
7
8
  warn(
8
- "Ruby version #{current_version} not supported. " \
9
- "Please upgrade to #{required_version} or above."
9
+ "Ruby version #{RUBY_VERSION} not supported. " \
10
+ 'Please upgrade to 2.5.0 or above.'
10
11
  )
11
12
 
12
13
  exit 1
@@ -1,8 +1,7 @@
1
+ const embed = require("./embed");
1
2
  const parse = require("./parse");
2
3
  const print = require("./print");
3
4
 
4
- const haml = require("./haml");
5
-
6
5
  const pragmaPattern = /#\s*@(prettier|format)/;
7
6
  const hasPragma = (text) => pragmaPattern.test(text);
8
7
 
@@ -49,6 +48,7 @@ module.exports = {
49
48
  filenames: [
50
49
  ".irbrc",
51
50
  ".pryrc",
51
+ ".simplecov",
52
52
  "Appraisals",
53
53
  "Berksfile",
54
54
  "Brewfile",
@@ -74,11 +74,6 @@ module.exports = {
74
74
  interpreters: ["jruby", "macruby", "rake", "rbx", "ruby"],
75
75
  linguistLanguageId: 326,
76
76
  vscodeLanguageIds: ["ruby"]
77
- },
78
- {
79
- name: "HAML",
80
- parsers: ["haml"],
81
- extensions: [".haml"]
82
77
  }
83
78
  ],
84
79
  parsers: {
@@ -88,22 +83,12 @@ module.exports = {
88
83
  hasPragma,
89
84
  locStart,
90
85
  locEnd
91
- },
92
- haml: {
93
- parse: haml.parse,
94
- astFormat: "haml",
95
- hasPragma: haml.hasPragma,
96
- locStart: haml.locStart,
97
- locEnd: haml.locEnd
98
86
  }
99
87
  },
100
88
  printers: {
101
89
  ruby: {
90
+ embed,
102
91
  print
103
- },
104
- haml: {
105
- embed: haml.embed,
106
- print: haml.print
107
92
  }
108
93
  },
109
94
  options: {
@@ -141,6 +126,13 @@ module.exports = {
141
126
  default: true,
142
127
  description:
143
128
  "When double quotes are not necessary for interpolation, prefers the use of single quotes for string literals."
129
+ },
130
+ toProcTransform: {
131
+ type: "boolean",
132
+ category: "Global",
133
+ default: true,
134
+ description:
135
+ "When possible, convert blocks to the more concise Symbol#to_proc syntax."
144
136
  }
145
137
  },
146
138
  defaultOptions: {
@@ -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 = (node) => {
15
- if (!node) {
14
+ const toProc = (path, opts, node) => {
15
+ if (!node || !opts.toProcTransform) {
16
16
  return null;
17
17
  }
18
18
 
@@ -76,6 +76,33 @@ const toProc = (node) => {
76
76
  return null;
77
77
  }
78
78
 
79
+ // Ensure that we're not inside of a hash that is being passed to a key that
80
+ // corresponds to `:if` or `:unless` to avoid problems with callbacks with
81
+ // Rails. For more context, see:
82
+ // https://github.com/prettier/plugin-ruby/issues/449
83
+ let assocNode = null;
84
+
85
+ if (path.getValue().type === "method_add_block") {
86
+ assocNode = path.getParentNode();
87
+ } else if (path.getValue().type === "args") {
88
+ assocNode = path.getParentNode(2);
89
+ }
90
+
91
+ if (assocNode && assocNode.type === "assoc_new") {
92
+ const [key] = assocNode.body;
93
+
94
+ if (key.type === "@label" && ["if:", "unless:"].includes(key.body)) {
95
+ return null;
96
+ }
97
+
98
+ if (
99
+ key.type === "symbol_literal" &&
100
+ ["if", "unless"].includes(key.body[0].body[0].body)
101
+ ) {
102
+ return null;
103
+ }
104
+ }
105
+
79
106
  return `&:${method.body}`;
80
107
  };
81
108
 
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.18.1
4
+ version: 0.20.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Deisz
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-05 00:00:00.000000000 Z
11
+ date: 2020-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,8 +52,8 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '13.0'
55
- description:
56
- email:
55
+ description:
56
+ email:
57
57
  executables:
58
58
  - rbprettier
59
59
  extensions: []
@@ -72,18 +72,7 @@ files:
72
72
  - node_modules/prettier/index.js
73
73
  - node_modules/prettier/third-party.js
74
74
  - package.json
75
- - src/haml.js
76
- - src/haml/embed.js
77
- - src/haml/nodes/comment.js
78
- - src/haml/nodes/doctype.js
79
- - src/haml/nodes/filter.js
80
- - src/haml/nodes/hamlComment.js
81
- - src/haml/nodes/script.js
82
- - src/haml/nodes/silentScript.js
83
- - src/haml/nodes/tag.js
84
- - src/haml/parse.js
85
- - src/haml/parse.rb
86
- - src/haml/print.js
75
+ - src/embed.js
87
76
  - src/nodes.js
88
77
  - src/nodes/alias.js
89
78
  - src/nodes/args.js
@@ -123,7 +112,7 @@ homepage: https://github.com/prettier/plugin-ruby#readme
123
112
  licenses:
124
113
  - MIT
125
114
  metadata: {}
126
- post_install_message:
115
+ post_install_message:
127
116
  rdoc_options: []
128
117
  require_paths:
129
118
  - lib
@@ -138,8 +127,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
127
  - !ruby/object:Gem::Version
139
128
  version: '0'
140
129
  requirements: []
141
- rubygems_version: 3.1.2
142
- signing_key:
130
+ rubygems_version: 3.0.3
131
+ signing_key:
143
132
  specification_version: 4
144
133
  summary: prettier plugin for the Ruby programming language
145
134
  test_files: []
@@ -1,21 +0,0 @@
1
- const embed = require("./haml/embed");
2
- const parse = require("./haml/parse");
3
- const print = require("./haml/print");
4
-
5
- const pragmaPattern = /^\s*-#\s*@(prettier|format)/;
6
- const hasPragma = (text) => pragmaPattern.test(text);
7
-
8
- // These functions are just placeholders until we can actually perform this
9
- // properly. The functions are necessary otherwise the format with cursor
10
- // functions break.
11
- const locStart = (_node) => 0;
12
- const locEnd = (_node) => 0;
13
-
14
- module.exports = {
15
- embed,
16
- hasPragma,
17
- locStart,
18
- locEnd,
19
- parse,
20
- print
21
- };
@@ -1,58 +0,0 @@
1
- const {
2
- concat,
3
- hardline,
4
- indent,
5
- literalline,
6
- mapDoc,
7
- markAsRoot,
8
- stripTrailingHardline
9
- } = require("../prettier");
10
-
11
- const parsers = {
12
- css: "css",
13
- javascript: "babel",
14
- less: "less",
15
- markdown: "markdown",
16
- ruby: "ruby",
17
- scss: "scss"
18
- };
19
-
20
- const replaceNewlines = (doc) =>
21
- mapDoc(doc, (currentDoc) =>
22
- typeof currentDoc === "string" && currentDoc.includes("\n")
23
- ? concat(
24
- currentDoc
25
- .split(/(\n)/g)
26
- .map((v, i) => (i % 2 === 0 ? v : literalline))
27
- )
28
- : currentDoc
29
- );
30
-
31
- const embed = (path, print, textToDoc, _opts) => {
32
- const node = path.getValue();
33
- if (node.type !== "filter") {
34
- return null;
35
- }
36
-
37
- const parser = parsers[node.value.name];
38
- if (!parser) {
39
- return null;
40
- }
41
-
42
- return markAsRoot(
43
- concat([
44
- ":",
45
- node.value.name,
46
- indent(
47
- concat([
48
- hardline,
49
- replaceNewlines(
50
- stripTrailingHardline(textToDoc(node.value.text, { parser }))
51
- )
52
- ])
53
- )
54
- ])
55
- );
56
- };
57
-
58
- module.exports = embed;