Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Break multiline parenthesized logical expressions #11103

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

alex12058
Copy link

@alex12058 alex12058 commented Jun 23, 2021

Description

This PR adds line breaks to multiline parenthesized logical expressions. I'm not 100% sure the changes in this PR are the best way to add line breaks to logical expressions as it imports needsParams into src/language-js/print/binaryish.js so it can check if the logcial expression will have params added.

// Input
const funnelSnapshotCard =
  (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) ||
  (
    report === COMPANY_OVERVIEW &&
    !ReportGK.xar_metrics_active_capitol_v2_company_metrics
  ) ? (
    <ReportMetricsFunnelSnapshotCard metrics={metrics} />
  ) : null;

// Prettier stable
const funnelSnapshotCard =
  (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) ||
  (report === COMPANY_OVERVIEW &&
    !ReportGK.xar_metrics_active_capitol_v2_company_metrics) ? (
    <ReportMetricsFunnelSnapshotCard metrics={metrics} />
  ) : null;

// This PR
const funnelSnapshotCard =
  (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) ||
  (
    report === COMPANY_OVERVIEW &&
    !ReportGK.xar_metrics_active_capitol_v2_company_metrics
  ) ? (
    <ReportMetricsFunnelSnapshotCard metrics={metrics} />
  ) : null;

Checklist

  • I’ve added tests to confirm my change works.
  • (If changing the API or CLI) I’ve documented the changes I’ve made (in the docs/ directory).
  • (If the change is user-facing) I’ve added my changes to changelog_unreleased/*/XXXX.md file following changelog_unreleased/TEMPLATE.md.
  • I’ve read the contributing guidelines.

Try the playground for this PR

Relates to #9574. Breaks and indents nested conditions if they are multiline.

@fisker
Copy link
Member

fisker commented Aug 8, 2021

I like this,

I havn't seen any tests on ?? operator, can you add some?

@alex12058
Copy link
Author

Sure. I added some basic tests in tests/format/js/logical_expressions/indent_multiline.js that includes tests for the ?? operator.

Copy link
Member

@fisker fisker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@fisker
Copy link
Member

fisker commented Oct 11, 2022

Wow, this prints this real-world case exactly as I expect. https://github.com/prettier/prettier/blob/main/src/language-js/print/angular.js#L68-L77

Prettier pr-11103
Playground link

--parser babel

Input:

{{
      const shouldNotPrintColon =
        isNgForOf(node, index, parentNode) ||
        (((index === 1 &&
          (node.key.name === "then" || node.key.name === "else")) ||
          (index === 2 &&
            node.key.name === "else" &&
            parentNode.body[index - 1].type ===
              "NGMicrosyntaxKeyedExpression" &&
            parentNode.body[index - 1].key.name === "then")) &&
          parentNode.body[0].type === "NGMicrosyntaxExpression");
}}

Output:

{
  {
    const shouldNotPrintColon =
      isNgForOf(node, index, parentNode) ||
      (
        (
          (
            index === 1 &&
            (node.key.name === "then" || node.key.name === "else")
          ) ||
          (
            index === 2 &&
            node.key.name === "else" &&
            parentNode.body[index - 1].type ===
              "NGMicrosyntaxKeyedExpression" &&
            parentNode.body[index - 1].key.name === "then"
          )
        ) &&
        parentNode.body[0].type === "NGMicrosyntaxExpression"
      );
  }
}

@fisker
Copy link
Member

fisker commented Oct 11, 2022

@thorn0 Can you review?

const extraRendererAttrs = ((
attrs.rendererAttrs &&
this.utils.safeParseJsonString(attrs.rendererAttrs)
) ||
Object.create(null)) as FieldService.RendererAttributes;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is so ugly, but out scope this PR

const extraRendererAttrs = (
    (
      attrs.rendererAttrs &&
      this.utils.safeParseJsonString(attrs.rendererAttrs)
    ) ||
    Object.create(null)
  ) as FieldService.RendererAttributes;

should be expected.

@thorn0
Copy link
Member

thorn0 commented Oct 11, 2022

@fisker This change leads to big diffs. Ask the rest of the team about it.

@fisker fisker requested a review from a team October 11, 2022 08:50
@kachkaev
Copy link
Member

kachkaev commented Oct 11, 2022

Could be OK in a new major version, especially together with #3806. Something like:

{
  {
    const shouldNotPrintColon =
      isNgForOf(node, index, parentNode)
      || (
          (
            (
              index === 1
              && (node.key.name === "then" || node.key.name === "else")
            )
            || (
                index === 2
                && node.key.name === "else"
                && parentNode.body[index - 1].type ===
                     "NGMicrosyntaxKeyedExpression"
                && parentNode.body[index - 1].key.name === "then"
              )
            )
          && parentNode.body[0].type === "NGMicrosyntaxExpression"
        );
  }
}

If these changes are combined, there’ll be only one instance of a large diff.

Copy link
Member

@fisker fisker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big 👍 for this change.

@kachkaev
Copy link
Member

This PR is against main branch, I guess it needs to be repointed to next.

@fisker
Copy link
Member

fisker commented Oct 11, 2022

It's fine to merge into main, we do format changes in minor releases. (We probably won't release 2.x though)

@thorn0
Copy link
Member

thorn0 commented Oct 12, 2022

The current formatting is okay as long as there is no lines starting with two or more parens. But #11103 (comment) is really a good example of how unreadable it can be. I wonder if it's possible to change only cases like that one. In the diffs I see a lot of expressions for which the current formatting is totally okay and this change doesn't look like an improvement. E.g.:

     if (
       hasDeselectedButton ||
-      (this.state.elementType !== "selection" &&
-        this.state.elementType !== "text")
+      (
+        this.state.elementType !== "selection" &&
+        this.state.elementType !== "text"
+      )
     ) {
       return;
     }

It'd be great to find a way not to touch simple expressions like that and use the proposed expanded formatting only where it's really needed.

@rattrayalex
Copy link
Collaborator

I haven't looked into this PR in depth, but in case it's useful, I wrote a simple algorithm to gauge expression complexity in another branch: https://github.com/rattrayalex/prettier/blob/postfix-ternaries/src/language-js/utils/index.js#L622-L647

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants