prettier 0.18.1 → 0.20.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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;