Repository: prettier/plugin-ruby (javascript)

Issue:
Splat operator on literal array with trailing comments can format to broken Ruby code
## Metadata

- Ruby version: 2.6.5
- `@prettier/plugin-ruby` or `prettier` gem version: 1.5.3
- Options:
  - [x] `rubyHashLabel`
  - [x] `rubyModifier`
  - [x] `rubySingleQuote`
  - [ ] `rubyToProc`
  - [ ] `trailingComma`

## Input

```ruby
expect(invoice.sorted_line_items).to eq([
  *line_items_without_author_email,
  line_items_with_author_email[2], # bar@example.com
  *line_items_with_author_email.first(2) # foo@example.com
])
```

## Current output

```ruby
expect(invoice.sorted_line_items).to eq(
  [
    *line_items_without_author_email,
    line_items_with_author_email[2], # bar@example.com
    line_items_with_author_email.first(2)* # foo@example.com
  ]
)
```

## Expected output

```ruby
expect(invoice.sorted_line_items).to eq(
  [
    *line_items_without_author_email,
    line_items_with_author_email[2], # bar@example.com
    *line_items_with_author_email.first(2) # foo@example.com
  ]
)
```

---

The output is broken Ruby. This seems related to the behavior of splat operator, like #835 and #812


Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
 
 ## [Unreleased]
 
+### Changed
+
+- [#835](https://github.com/prettier/plugin-ruby/issues/835) - valscion, kddeisz - Array splat operator should not get moved by leading comments.
+- [#836](https://github.com/prettier/plugin-ruby/issues/836) - valscion, kddeisz - Array splat operator should not get moved by trailing comments.
+
 ## [1.5.3] - 2021-02-28
 
 ### Changed
diff --git a/src/ruby/nodes/args.js b/src/ruby/nodes/args.js
--- a/src/ruby/nodes/args.js
+++ b/src/ruby/nodes/args.js
@@ -147,9 +147,16 @@ function printArgsAddStar(path, opts, print) {
     //       *values
     //     ]
     //
+    // or if we have an array like:
+    //
+    //     [
+    //       *values # comment
+    //     ]
+    //
     // then we need to make sure we don't accidentally prepend the operator
     // before the comment.
-    docs[1].parts[2] = concat(["*", docs[1].parts[2]]);
+    const index = node.body[1].comments.filter(({ leading }) => leading).length;
+    docs[1].parts[index] = concat(["*", docs[1].parts[index]]);
   } else {
     // If we don't have any comments, we can just prepend the operator
     docs[1] = concat(["*", docs[1]]);


Test patch:
diff --git a/test/js/ruby/nodes/method.test.js b/test/js/ruby/nodes/method.test.js
--- a/test/js/ruby/nodes/method.test.js
+++ b/test/js/ruby/nodes/method.test.js
@@ -249,6 +249,8 @@ describe("method", () => {
         const content = ruby(`
           foo(
             # comment
+            # another comment
+            # even more comment
             *values
           )
         `);
@@ -256,6 +258,19 @@ describe("method", () => {
         return expect(content).toMatchFormat();
       });
 
+      test("with trailing comments", () => {
+        const content = ruby(`
+          foo(
+            # comment
+            # another comment
+            *values # a trailing comment
+            # a whole other comment
+          )
+        `);
+
+        return expect(content).toMatchFormat();
+      });
+
       test("with block", () => expect("foo(*bar, &block)").toMatchFormat());
 
       test("with comments and block", () => {