Repository: biomejs/biome (language: rust)

Issue:
`bracketSameLine` not respected if comment before last parameter
### Environment information

```bash
CLI:
  Version:                      1.9.4
  Color support:                true

Platform:
  CPU Architecture:             aarch64
  OS:                           macos

Environment:
  BIOME_LOG_PATH:               unset
  BIOME_LOG_PREFIX_NAME:        unset
  BIOME_CONFIG_PATH:            unset
  NO_COLOR:                     unset
  TERM:                         "xterm-256color"
  JS_RUNTIME_VERSION:           "v21.2.0"
  JS_RUNTIME_NAME:              "node"
  NODE_PACKAGE_MANAGER:         "yarn/4.5.3"

Biome Configuration:
  Status:                       Loaded successfully
  Formatter disabled:           false
  Linter disabled:              false
  Organize imports disabled:    false
  VCS disabled:                 true

Formatter:
  Format with errors:           false
  Indent style:                 Space
  Indent width:                 4
  Line ending:                  Lf
  Line width:                   120
  Attribute position:           Auto
  Bracket spacing:              BracketSpacing(true)
  Ignore:                       []
  Include:                      []

JavaScript Formatter:
  Enabled:                      false
  JSX quote style:              Double
  Quote properties:             AsNeeded
  Trailing commas:              All
  Semicolons:                   Always
  Arrow parentheses:            Always
  Bracket spacing:              unset
  Bracket same line:            true
  Quote style:                  Double
  Indent style:                 unset
  Indent width:                 unset
  Line ending:                  unset
  Line width:                   unset
  Attribute position:           unset

JSON Formatter:
  Enabled:                      true
  Indent style:                 unset
  Indent width:                 unset
  Line ending:                  unset
  Line width:                   unset
  Trailing Commas:              unset

CSS Formatter:
  Enabled:                      true
  Indent style:                 unset
  Indent width:                 unset
  Line ending:                  unset
  Line width:                   unset
  Quote style:                  Double

GraphQL Formatter:
  Enabled:                      false
  Indent style:                 unset
  Indent width:                 unset
  Line ending:                  unset
  Line width:                   unset
  Bracket spacing:              unset
  Quote style:                  unset

Workspace:
  Open Documents:               0
```


### Configuration

```JSON
{
    "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
    "formatter": {
        "enabled": true,
        "formatWithErrors": false,
        "indentStyle": "space",
        "indentWidth": 4,
        "lineEnding": "lf",
        "lineWidth": 120
    },
    "javascript": {
        "formatter": {
            "bracketSameLine": true
        }
    }
}
```


### Playground link

https://biomejs.dev/playground/?indentStyle=space&indentWidth=4&bracketSameLine=true&code=ZgB1AG4AYwB0AGkAbwBuACAAdABlAHMAdAAoACkAIAB7AAoAIAAgAHIAZQB0AHUAcgBuACAAPABTAG8AbQBlAHQAaABpAG4AZwAKACAAIAAgACAAIAAgACAAIAAgACAAIABzAG8AbQBlAHQAaABpAG4AZwA9ACIAMQAiAAoAIAAgACAAIAAgACAAIAAgACAAIAAgAHMAbwBtAGUAdABoAGkAbgBnADIAPQAiADEAIgAKACAAIAAgACAAIAAgACAAIAAgACAAIABzAG8AbQBlAHQAaABpAG4AZwAzAD0AIgAxACIACgAgACAAIAAgACAAIAAgACAAIAAgACAAcwBvAG0AZQB0AGgAaQBuAGcANAA9ACIAMQAiAAoAIAAgACAAIAAgACAAIAAgACAAIAAgAHMAbwBtAGUAdABoAGkAbgBnADUAPQAiADEAIgAKACAAIAAgACAAIAAgACAAIAAgACAAIABzAG8AbQBlAHQAaABpAG4AZwA2AD0AIgAxACIACgAgACAAIAAgACAAIAAgACAAIAAgACAALwAvACAAQwBvAG0AbQBlAG4AdAAKACAAIAAgACAAIAAgACAAIAAgACAAIABlAGwAcwBlAD0AIgAyACIAPgAKACAAIAAgACAAQwBvAG4AdABlAG4AdAAKACAAIAA8AC8AUwBvAG0AZQB0AGgAaQBuAGcAPgAKAH0ACgAKAGYAdQBuAGMAdABpAG8AbgAgAHQAZQBzAHQAMgAoACkAIAB7AAoAIAAgAHIAZQB0AHUAcgBuACAAPABTAG8AbQBlAHQAaABpAG4AZwAKACAAIAAgACAAIAAgACAAIAAgACAAIABzAG8AbQBlAHQAaABpAG4AZwA9ACIAMQAiAAoAIAAgACAAIAAgACAAIAAgACAAIAAgAHMAbwBtAGUAdABoAGkAbgBnADIAPQAiADEAIgAKACAAIAAgACAAIAAgACAAIAAgACAAIABzAG8AbQBlAHQAaABpAG4AZwAzAD0AIgAxACIACgAgACAAIAAgACAAIAAgACAAIAAgACAAcwBvAG0AZQB0AGgAaQBuAGcANAA9ACIAMQAiAAoAIAAgACAAIAAgACAAIAAgACAAIAAgAHMAbwBtAGUAdABoAGkAbgBnADUAPQAiADEAIgAKACAAIAAgACAAIAAgACAAIAAgACAAIABzAG8AbQBlAHQAaABpAG4AZwA2AD0AIgAxACIACgAgACAAIAAgACAAIAAgACAAIAAgACAAZQBsAHMAZQA9ACIAMgAiAD4ACgAgACAAIAAgAEMAbwBuAHQAZQBuAHQACgAgACAAPAAvAFMAbwBtAGUAdABoAGkAbgBnAD4ACgB9AA%3D%3D

### Code of Conduct

- [X] I agree to follow Biome's Code of Conduct


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 34ef8f6c34bc..3e6ad3e3c32c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -89,6 +89,8 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b
 
 - `noDuplicateProperties` now throws lint errors properly when we use `@supports` (fix [#4756](https://github.com/biomejs/biome/issues/4756)) Contributed by @mehm8128
 
+- Fix [#4719](https://github.com/biomejs/biome/issues/4719), `bracketSameLine` now performs as expected when a comment is placed before the last JSX attribute. Contributed by @bushuai
+
 ### JavaScript APIs
 
 ### Linter
diff --git a/crates/biome_js_formatter/src/jsx/tag/opening_element.rs b/crates/biome_js_formatter/src/jsx/tag/opening_element.rs
index 704b075a1ac3..7116f685521e 100644
--- a/crates/biome_js_formatter/src/jsx/tag/opening_element.rs
+++ b/crates/biome_js_formatter/src/jsx/tag/opening_element.rs
@@ -152,6 +152,9 @@ impl AnyJsxOpeningElement {
     fn compute_layout(&self, comments: &JsComments) -> SyntaxResult<OpeningElementLayout> {
         let attributes = self.attributes();
         let name = self.name()?;
+        let last_attribute_has_comments = self.attributes().last().map_or(false, |attribute| {
+            comments.has_trailing_comments(attribute.syntax())
+        });
 
         let name_has_comments = comments.has_comments(name.syntax())
             || self
@@ -171,7 +174,7 @@ impl AnyJsxOpeningElement {
         } else {
             OpeningElementLayout::IndentAttributes {
                 name_has_comments,
-                last_attribute_has_comments: has_last_attribute_comments(self, comments),
+                last_attribute_has_comments,
             }
         };
 
@@ -249,18 +252,3 @@ fn as_string_literal_attribute_value(attribute: &AnyJsxAttribute) -> Option<JsxS
         JsxSpreadAttribute(_) => None,
     }
 }
-
-fn has_last_attribute_comments(element: &AnyJsxOpeningElement, comments: &JsComments) -> bool {
-    let has_comments_on_last_attribute = element
-        .attributes()
-        .last()
-        .map_or(false, |attribute| comments.has_comments(attribute.syntax()));
-
-    let last_attribute_has_comments = element
-        .syntax()
-        .tokens()
-        .map(|token| token.text().contains('>') && token.has_leading_comments())
-        .any(|has_comment| has_comment);
-
-    has_comments_on_last_attribute || last_attribute_has_comments
-}


Test patch:
diff --git a/crates/biome_js_formatter/tests/specs/jsx/bracket_same_line/bracket_same_line.jsx b/crates/biome_js_formatter/tests/specs/jsx/bracket_same_line/bracket_same_line.jsx
index 4e4b54d3dfbe..487af6eddda5 100644
--- a/crates/biome_js_formatter/tests/specs/jsx/bracket_same_line/bracket_same_line.jsx
+++ b/crates/biome_js_formatter/tests/specs/jsx/bracket_same_line/bracket_same_line.jsx
@@ -29,5 +29,15 @@ const a = <div></div>;
 	Hi
 </Foo>;
 
+<Foo
+	className={style}
+	reallyLongAttributeName1={longComplexValue}
+	reallyLongAttributeName2={anotherLongValue}
+	// comment
+	reallyLongAttributeName3={yetAnotherLongValue}
+>
+	Hi
+</Foo>;
+
 <div className="hi" />;
 <div className="hi"></div>;
diff --git a/crates/biome_js_formatter/tests/specs/jsx/bracket_same_line/bracket_same_line.jsx.snap b/crates/biome_js_formatter/tests/specs/jsx/bracket_same_line/bracket_same_line.jsx.snap
index 6bad9dc34313..c14e5699ca7c 100644
--- a/crates/biome_js_formatter/tests/specs/jsx/bracket_same_line/bracket_same_line.jsx.snap
+++ b/crates/biome_js_formatter/tests/specs/jsx/bracket_same_line/bracket_same_line.jsx.snap
@@ -1,6 +1,5 @@
 ---
 source: crates/biome_formatter_test/src/snapshot_builder.rs
-assertion_line: 212
 info: jsx/bracket_same_line/bracket_same_line.jsx
 ---
 # Input
@@ -37,6 +36,16 @@ const a = <div></div>;
 	Hi
 </Foo>;
 
+<Foo
+	className={style}
+	reallyLongAttributeName1={longComplexValue}
+	reallyLongAttributeName2={anotherLongValue}
+	// comment
+	reallyLongAttributeName3={yetAnotherLongValue}
+>
+	Hi
+</Foo>;
+
 <div className="hi" />;
 <div className="hi"></div>;
 
@@ -97,6 +106,16 @@ const a = <div></div>;
 	Hi
 </Foo>;
 
+<Foo
+	className={style}
+	reallyLongAttributeName1={longComplexValue}
+	reallyLongAttributeName2={anotherLongValue}
+	// comment
+	reallyLongAttributeName3={yetAnotherLongValue}
+>
+	Hi
+</Foo>;
+
 <div className="hi" />;
 <div className="hi"></div>;
 ```
@@ -150,6 +169,15 @@ const a = <div></div>;
 	Hi
 </Foo>;
 
+<Foo
+	className={style}
+	reallyLongAttributeName1={longComplexValue}
+	reallyLongAttributeName2={anotherLongValue}
+	// comment
+	reallyLongAttributeName3={yetAnotherLongValue}>
+	Hi
+</Foo>;
+
 <div className="hi" />;
 <div className="hi"></div>;
 ```