prettier 1.2.0 → 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c97988d5dd7fe35aa5fd73777f31f8217809ea0eee189cab7ac70c266569857b
4
- data.tar.gz: 478c15e6cbd8d8efb16fc37e028afb8c88f3671aa77f36d3df0cd115b239c83a
3
+ metadata.gz: 3abef3acea4e49130ba81afdb9bc00e73277c69e0254a1087b2c5e47feb5b104
4
+ data.tar.gz: e851f061fc14352b7797ac0e2aca10c43f052b8bd19aa817473cfb6b75bde44c
5
5
  SHA512:
6
- metadata.gz: 38ae06510c4872ba7f4ede36dc6b5f4aae3c7183c9c48b4e515733074e9ce27d2ddb4b189c25600d1daf123b8f5eccbb8b12c953e5192a62e08a63cb9716298e
7
- data.tar.gz: 9456c53fe9ad823defb3d69fd4dd4504ee1e9d4af5d522fd8352141d61a5d975aa6043b62d78dd077f000258e400ee98fce8131ada5dac066021bb27e9f40de5
6
+ metadata.gz: 6fd8aba1071ff34709e7f3ad3ddd256cfbdc890ffb02fdef3d3567331a53d9b1974d02fd943ce03cab565822d750288bbe5582bc3c4a2d26bf0f170d2c3d15c6
7
+ data.tar.gz: 8e66f396c113f162fb6c8c747a60d45dd38a554c13cab3ac1ae12456ff15fc49d2945ce69c1db53d89f1f82a69d0b30017ebfdcd99fbb2cb2fbbc29c4dbf398b
@@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.2.1] - 2020-12-27
10
+
11
+ ### Changed
12
+
13
+ - [@kddeisz] - Handle single-line method definitions with parameters.
14
+ - [@kddeisz] - Handle hash and array patterns nested within find patterns.
15
+ - [@kddeisz] - Handle rightward assignment.
16
+ - [@kddeisz] - Handle find patterns with named boundaries.
17
+ - [@kddeisz] - Handle rightward assignment in conditionals.
18
+
9
19
  ## [1.2.0] - 2020-12-26
10
20
 
11
21
  ### Added
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prettier/plugin-ruby",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "prettier plugin for the Ruby programming language",
5
5
  "main": "src/ruby.js",
6
6
  "scripts": {
@@ -32,11 +32,7 @@ function printOpAssign(path, opts, print) {
32
32
  }
33
33
 
34
34
  function printVarField(path, opts, print) {
35
- if (path.getValue().body) {
36
- return path.call(print, "body", 0);
37
- }
38
-
39
- return "*";
35
+ return path.getValue().body ? path.call(print, "body", 0) : "";
40
36
  }
41
37
 
42
38
  module.exports = {
@@ -8,54 +8,58 @@ const {
8
8
  line
9
9
  } = require("../prettier");
10
10
 
11
- module.exports = {
12
- case: (path, opts, print) => {
13
- const statement = ["case"];
14
-
15
- // You don't need to explicitly have something to test against in a case
16
- // statement (without it it effectively becomes an if/elsif chain).
17
- if (path.getValue().body[0]) {
18
- statement.push(" ", path.call(print, "body", 0));
19
- }
20
-
21
- return concat(
22
- statement.concat([hardline, path.call(print, "body", 1), hardline, "end"])
23
- );
24
- },
25
- when: (path, opts, print) => {
26
- const [_preds, _stmts, addition] = path.getValue().body;
27
-
28
- // The `fill` builder command expects an array of docs alternating with
29
- // line breaks. This is so it can loop through and determine where to break.
30
- const preds = fill(
31
- path.call(print, "body", 0).reduce((accum, pred, index) => {
32
- if (index === 0) {
33
- return [pred];
34
- }
35
-
36
- // Pull off the last element and make it concat with a comma so that
37
- // we can maintain alternating lines and docs.
38
- return accum
39
- .slice(0, -1)
40
- .concat([concat([accum[accum.length - 1], ","]), line, pred]);
41
- }, null)
42
- );
43
-
44
- const stmts = path.call(print, "body", 1);
45
- const parts = [concat(["when ", align("when ".length, preds)])];
46
-
47
- // It's possible in a when to just have empty void statements, in which case
48
- // we would skip adding the body.
49
- if (!stmts.parts.every((part) => !part)) {
50
- parts.push(indent(concat([hardline, stmts])));
51
- }
52
-
53
- // This is the next clause on the case statement, either another `when` or
54
- // an `else` clause.
55
- if (addition) {
56
- parts.push(hardline, path.call(print, "body", 2));
57
- }
58
-
59
- return group(concat(parts));
11
+ function printCase(path, opts, print) {
12
+ const statement = ["case"];
13
+
14
+ // You don't need to explicitly have something to test against in a case
15
+ // statement (without it it effectively becomes an if/elsif chain).
16
+ if (path.getValue().body[0]) {
17
+ statement.push(" ", path.call(print, "body", 0));
18
+ }
19
+
20
+ return concat(
21
+ statement.concat([hardline, path.call(print, "body", 1), hardline, "end"])
22
+ );
23
+ }
24
+
25
+ function printWhen(path, opts, print) {
26
+ const [_preds, _stmts, addition] = path.getValue().body;
27
+
28
+ // The `fill` builder command expects an array of docs alternating with
29
+ // line breaks. This is so it can loop through and determine where to break.
30
+ const preds = fill(
31
+ path.call(print, "body", 0).reduce((accum, pred, index) => {
32
+ if (index === 0) {
33
+ return [pred];
34
+ }
35
+
36
+ // Pull off the last element and make it concat with a comma so that
37
+ // we can maintain alternating lines and docs.
38
+ return accum
39
+ .slice(0, -1)
40
+ .concat([concat([accum[accum.length - 1], ","]), line, pred]);
41
+ }, null)
42
+ );
43
+
44
+ const stmts = path.call(print, "body", 1);
45
+ const parts = [concat(["when ", align("when ".length, preds)])];
46
+
47
+ // It's possible in a when to just have empty void statements, in which case
48
+ // we would skip adding the body.
49
+ if (!stmts.parts.every((part) => !part)) {
50
+ parts.push(indent(concat([hardline, stmts])));
51
+ }
52
+
53
+ // This is the next clause on the case statement, either another `when` or
54
+ // an `else` clause.
55
+ if (addition) {
56
+ parts.push(hardline, path.call(print, "body", 2));
60
57
  }
58
+
59
+ return group(concat(parts));
60
+ }
61
+
62
+ module.exports = {
63
+ case: printCase,
64
+ when: printWhen
61
65
  };
@@ -16,8 +16,7 @@ function printMethod(offset) {
16
16
  }
17
17
 
18
18
  // In case there are no parens but there are arguments
19
- const parens =
20
- params.type === "params" && params.body.some((paramType) => paramType);
19
+ const parens = params.type === "params" && params.body.some((type) => type);
21
20
 
22
21
  declaration.push(
23
22
  path.call(print, "body", offset),
@@ -49,10 +48,27 @@ function printMethod(offset) {
49
48
  }
50
49
 
51
50
  function printSingleLineMethod(path, opts, print) {
52
- const [nameDoc, stmtDoc] = path.map(print, "body");
51
+ let paramsNode = path.getValue().body[1];
52
+ let paramsDoc = "";
53
+
54
+ if (paramsNode) {
55
+ if (paramsNode.body[0].type === "params") {
56
+ paramsNode = paramsNode.body[0];
57
+ }
58
+
59
+ if (paramsNode.type === "params" && paramsNode.body.some((type) => type)) {
60
+ paramsDoc = path.call(print, "body", 1);
61
+ }
62
+ }
53
63
 
54
64
  return group(
55
- concat(["def ", nameDoc, " =", indent(group(concat([line, stmtDoc])))])
65
+ concat([
66
+ "def ",
67
+ path.call(print, "body", 0),
68
+ paramsDoc,
69
+ " =",
70
+ indent(group(concat([line, path.call(print, "body", 2)])))
71
+ ])
56
72
  );
57
73
  }
58
74
 
@@ -1,5 +1,7 @@
1
1
  const { concat, group, hardline, indent, join, line } = require("../prettier");
2
2
 
3
+ const patterns = ["aryptn", "binary", "fndptn", "hshptn", "rassign"];
4
+
3
5
  function printPatternArg(path, opts, print) {
4
6
  // Pinning is a really special syntax in pattern matching that's not really
5
7
  // all that well supported in ripper. Here we're just going to the original
@@ -34,10 +36,7 @@ function printAryPtn(path, opts, print) {
34
36
 
35
37
  args = group(join(concat([",", line]), args));
36
38
 
37
- if (
38
- constant ||
39
- ["aryptn", "binary", "hshptn"].includes(path.getParentNode().type)
40
- ) {
39
+ if (constant || patterns.includes(path.getParentNode().type)) {
41
40
  args = concat(["[", args, "]"]);
42
41
  }
43
42
 
@@ -51,9 +50,9 @@ function printAryPtn(path, opts, print) {
51
50
  function printFndPtn(path, opts, print) {
52
51
  const [constant] = path.getValue().body;
53
52
 
54
- let args = [path.call(print, "body", 1)]
53
+ let args = [concat(["*", path.call(print, "body", 1)])]
55
54
  .concat(path.map(print, "body", 2))
56
- .concat(path.call(print, "body", 3));
55
+ .concat(concat(["*", path.call(print, "body", 3)]));
57
56
 
58
57
  args = concat(["[", group(join(concat([",", line]), args)), "]"]);
59
58
 
@@ -96,10 +95,8 @@ function printHshPtn(path, opts, print) {
96
95
 
97
96
  if (constant) {
98
97
  args = concat(["[", args, "]"]);
99
- } else if (
100
- ["aryptn", "binary", "hshptn"].includes(path.getParentNode().type)
101
- ) {
102
- args = concat(["{", args, "}"]);
98
+ } else if (patterns.includes(path.getParentNode().type)) {
99
+ args = concat(["{ ", args, " }"]);
103
100
  }
104
101
 
105
102
  if (constant) {
@@ -127,9 +124,23 @@ function printIn(path, opts, print) {
127
124
  return group(concat(parts));
128
125
  }
129
126
 
127
+ function printRAssign(path, opts, print) {
128
+ const { keyword } = path.getValue();
129
+ const [leftDoc, rightDoc] = path.map(print, "body");
130
+
131
+ return group(
132
+ concat([
133
+ leftDoc,
134
+ keyword ? " in" : " =>",
135
+ group(indent(concat([line, rightDoc])))
136
+ ])
137
+ );
138
+ }
139
+
130
140
  module.exports = {
131
141
  aryptn: printAryPtn,
132
142
  fndptn: printFndPtn,
133
143
  hshptn: printHshPtn,
134
- in: printIn
144
+ in: printIn,
145
+ rassign: printRAssign
135
146
  };
@@ -63,14 +63,14 @@ class Prettier::Parser < Ripper
63
63
  # would happen to be the innermost keyword). Then the outer one would only be
64
64
  # able to grab the first one. In this way all of the scanner events act as
65
65
  # their own stack.
66
- def find_scanner_event(type, body = :any)
66
+ def find_scanner_event(type, body = :any, consume: true)
67
67
  index =
68
68
  scanner_events.rindex do |scanner_event|
69
69
  scanner_event[:type] == type &&
70
70
  (body == :any || (scanner_event[:body] == body))
71
71
  end
72
72
 
73
- scanner_events.delete_at(index)
73
+ consume ? scanner_events.delete_at(index) : (index && scanner_events[index])
74
74
  end
75
75
 
76
76
  # Scanner events occur when the lexer hits a new token, like a keyword or an
@@ -675,8 +675,15 @@ class Prettier::Parser < Ripper
675
675
  # It accepts as arguments the switch of the case and the consequent
676
676
  # clause.
677
677
  def on_case(switch, consequent)
678
- find_scanner_event(:@kw, 'case').merge!(
679
- type: :case,
678
+ beging =
679
+ if event = find_scanner_event(:@kw, 'case', consume: false)
680
+ scanner_events.delete(event).merge!(type: :case)
681
+ else
682
+ keyword = find_scanner_event(:@kw, 'in', consume: false)
683
+ switch.merge(type: :rassign, keyword: keyword)
684
+ end
685
+
686
+ beging.merge!(
680
687
  body: [switch, consequent],
681
688
  end: consequent[:end],
682
689
  char_end: consequent[:char_end]
@@ -832,12 +839,12 @@ class Prettier::Parser < Ripper
832
839
  # and normal method definitions.
833
840
  beging = find_scanner_event(:@kw, 'def')
834
841
 
835
- # If there is not a params node, then we have a single-line method
836
- unless params
842
+ # If we don't have a bodystmt node, then we have a single-line method
843
+ if bodystmt[:type] != :bodystmt
837
844
  return(
838
845
  {
839
846
  type: :defsl,
840
- body: [ident, bodystmt],
847
+ body: [ident, params, bodystmt],
841
848
  start: beging[:start],
842
849
  char_start: beging[:char_start],
843
850
  end: bodystmt[:end],
@@ -1006,7 +1013,7 @@ class Prettier::Parser < Ripper
1006
1013
  #
1007
1014
  # which would be the same symbol as above.
1008
1015
  def on_dyna_symbol(string)
1009
- if scanner_events.any? { |event| event[:type] == :@symbeg }
1016
+ if find_scanner_event(:@symbeg, consume: false)
1010
1017
  # A normal dynamic symbol
1011
1018
  beging = find_scanner_event(:@symbeg)
1012
1019
  ending = find_scanner_event(:@tstring_end)
@@ -1345,8 +1352,12 @@ class Prettier::Parser < Ripper
1345
1352
  end
1346
1353
 
1347
1354
  # in is a parser event that represents using the in keyword within the
1348
- # Ruby 2.7+ pattern matching syntax.
1355
+ # Ruby 2.7+ pattern matching syntax. Alternatively in Ruby 3+ it is also used
1356
+ # to handle rightward assignment for pattern matching.
1349
1357
  def on_in(pattern, stmts, consequent)
1358
+ # Here we have a rightward assignment
1359
+ return pattern unless stmts
1360
+
1350
1361
  beging = find_scanner_event(:@kw, 'in')
1351
1362
  ending = consequent || find_scanner_event(:@kw, 'end')
1352
1363
 
@@ -1384,8 +1395,8 @@ class Prettier::Parser < Ripper
1384
1395
  def on_lambda(params, stmts)
1385
1396
  beging = find_scanner_event(:@tlambda)
1386
1397
 
1387
- if scanner_events.any? { |event| event[:type] == :@tlambeg }
1388
- opening = find_scanner_event(:@tlambeg)
1398
+ if event = find_scanner_event(:@tlambeg, consume: false)
1399
+ opening = scanner_events.delete(event)
1389
1400
  closing = find_scanner_event(:@rbrace)
1390
1401
  else
1391
1402
  opening = find_scanner_event(:@kw, 'do')
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: 1.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Deisz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-26 00:00:00.000000000 Z
11
+ date: 2020-12-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: