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

WIP (add-parens-to-binary) #381

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions elm-format.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ library
ElmFormat.Filesystem
ElmFormat.FileStore
ElmFormat.Operation
ElmFormat.Render.GroupBinops
ElmFormat.Version
Flags
Messages.Formatter.Format
Expand Down
3 changes: 2 additions & 1 deletion src/ElmFormat/Render/Box.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Data.Maybe (fromMaybe, maybeToList)
import qualified Data.Text as Text
import qualified ElmFormat.Render.ElmStructure as ElmStructure
import qualified ElmFormat.Render.Markdown
import qualified ElmFormat.Render.GroupBinops as GroupBinops
import qualified ElmFormat.Version
import qualified Parse.Parse as Parse
import qualified Reporting.Annotation as RA
Expand Down Expand Up @@ -791,7 +792,7 @@ formatDefinition elmVersion name args comments expr =
body =
stack1 $ concat
[ map formatComment comments
, [ formatExpression elmVersion SyntaxSeparated expr ]
, [ formatExpression elmVersion SyntaxSeparated (GroupBinops.extractAnds expr) ] -- TODO: use extractAnds for all expressions
]
in
ElmStructure.definition "=" True
Expand Down
72 changes: 72 additions & 0 deletions src/ElmFormat/Render/GroupBinops.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
module ElmFormat.Render.GroupBinops (extractAnds) where

import AST.V0_16
import AST.Expression
import Reporting.Annotation
import qualified AST.Variable as Var
import qualified Reporting.Region as Region


-- TODO: handle Ors also
-- TODO: ensure it only groups comparison operators?
-- TODO: make it work for expression that aren't directly the body of a definition
extractAnds :: Expr -> Expr
extractAnds expr =
case expr of
A loc (Binops left ops multiline) ->
A loc $ done multiline $ foldl step (left, [], []) ops

_ ->
expr


type State = (Expr, [(Comments, Var.Ref, Comments, Expr)], [(Expr, Var.Ref)])

shiftReverse :: [(a, b)] -> a -> [(b, a)] -> (a, [(b, a)])
shiftReverse [] last acc = (last, acc)
shiftReverse ((prev, op):rest) last acc =
shiftReverse rest prev ((op, last) : acc)


step :: State -> (Comments, Var.Ref, Comments, Expr) -> State
step (left, inners, conditions) (pre, op, post, next) = -- TODO: Handle comments
case op of
Var.OpRef (SymbolIdentifier opSymbol) ->
if opSymbol == "&&" || opSymbol == "<|" then
( next, [], (Var.OpRef (SymbolIdentifier opSymbol), packageCondition left inners) : conditions )
else
( left, (pre, op, post, next) : inners, conditions )

_ ->
( left, (pre, op, post, next) : inners, conditions )


packageCondition :: Expr -> [(Comments, Var.Ref, Comments, Expr)] -> Expr
packageCondition left [] = left
packageCondition left inners =
noRegion $ Binops left (reverse inners) False


done :: Bool -> State -> Expr'
done multiline (left, inners, []) = (Binops left (reverse inners) multiline)
done multiline (left, inners, conditions) =
let
finalConditions =
reverse $ packageCondition left inners : conditions

buildOp right =
([], Var.OpRef (SymbolIdentifier "&&"), [], right)
in
case finalConditions of
first : r ->
(Binops first (fmap buildOp r) multiline)


nowhere :: Region.Position
nowhere =
Region.Position 0 0


noRegion :: a -> Located a
noRegion =
at nowhere nowhere
2 changes: 2 additions & 0 deletions tests/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ echo "# elm-format test suite"

checkWaysToRun

checkTransformation 0.18 AddParensForAndOr.elm

checkGood 0.16 Simple.elm
checkGood 0.16 AllSyntax/0.16/AllSyntax.elm
checkGoodAllSyntax 0.16 Module
Expand Down
43 changes: 43 additions & 0 deletions tests/test-files/transform/AddParensForAndOr.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@


addParensToAnd =
1 == 2 && 3 /= 4 && 5 < 6 && 7 > 8 && 9 <= 10 && 11 >= 12

addParensToAndWithComplexConditions =
1 == 2 + 3 && 4 /= 5 && 6 < 7 + 8 && 9 > 10 && 11 <= 12 && 13 >= 14 + 15

addParensToAndMultiline =
1
== 2 && 3 /= 4 && 5 < 6 && 7 > 8 && 9 <= 10 && 11 >= 12

makesGroupedExpressionsSingleLine =
1
==
2
+
7
*
5
-
6
+
-8
&&
3
/=
4


doesntAddParensAroundParens =
(1 == 2) && (3 /= 4) && 5/= 6 && (7 /= 8)

keepsNewLinesInExistingParens =
(1
== 2
+ 3 * 4 - 5 + 6) && 7 /= 8

doesntGroupPipes f =
f <| True && False

doesntGroupPipes2 f =
True && False |> f
38 changes: 38 additions & 0 deletions tests/test-files/transform/AddParensForAndOr.formatted.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module Main exposing (..)


addParensToAnd =
(1 == 2) && (3 /= 4) && (5 < 6) && (7 > 8) && (9 <= 10) && (11 >= 12)


addParensToAndWithComplexConditions =
(1 == 2 + 3) && (4 /= 5) && (6 < 7 + 8) && (9 > 10) && (11 <= 12) && (13 >= 14 + 15)


addParensToAndMultiline =
(1 == 2)
&& (3 /= 4)
&& (5 < 6)
&& (7 > 8)
&& (9 <= 10)
&& (11 >= 12)


makesGroupedExpressionsSingleLine =
(1 == 2 + 7 * 5 - 6 + -8)
&& (3 /= 4)


doesntAddParensAroundParens =
(1 == 2) && (3 /= 4) && (5 /= 6) && (7 /= 8)


keepsNewLinesInExistingParens =
(1
== 2
+ 3
* 4
- 5
+ 6
)
&& (7 /= 8)