Skip to content

Commit

Permalink
Allow single-line case-expressions branches
Browse files Browse the repository at this point in the history
This implementation uses only the first case branch to decide if single-line branches is wanted.
This allows to easily go from multi-line to single-line, even with lots of branches.

Closes #507
  • Loading branch information
rlefevre committed Nov 17, 2019
1 parent 3b2a0fd commit 163199f
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 35 deletions.
2 changes: 1 addition & 1 deletion parser/src/AST/Expression.hs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ data Expr'
| Lambda [(Comments, Pattern.Pattern)] Comments Expr Bool
| If IfClause [(Comments, IfClause)] (Comments, Expr)
| Let [LetDeclaration] Comments Expr
| Case (Commented Expr, Bool) [(Commented Pattern.Pattern, (Comments, Expr))]
| Case (Commented Expr, Multiline) [(Commented Pattern.Pattern, (Comments, Expr))] Multiline

-- for type checking and code gen only
| GLShader String
Expand Down
2 changes: 1 addition & 1 deletion parser/src/AST/Json.hs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ instance ToJSON Expr where
, ("body", showJSON body)
]

Case (Commented _ subject _, _) branches ->
Case (Commented _ subject _, _) branches _ ->
makeObj
[ type_ "CaseExpression"
, ( "subject", showJSON subject )
Expand Down
8 changes: 4 additions & 4 deletions parser/src/Parse/Expression.hs
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ caseExpr elmVersion =
(e, multilineSubject) <- trackNewline $ (\(pre, e, post) -> Commented pre e post) <$> padded (expr elmVersion)
reserved elmVersion "of"
firstPatternComments <- whitespace
result <- cases firstPatternComments
return $ E.Case (e, multilineToBool multilineSubject) result
(result, multiline) <- cases firstPatternComments
return $ E.Case (e, multilineSubject) result multiline
where
case_ preComments =
do
Expand All @@ -254,9 +254,9 @@ caseExpr elmVersion =
cases preComments =
withPos $
do
r1 <- case_ preComments
(r1, multiline) <- trackNewline (case_ preComments)
r <- many $ case_ []
return $ r1:r
return (r1:r, multiline)



Expand Down
6 changes: 3 additions & 3 deletions src/AST/MapExpr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ instance MapExpr a => MapExpr [a] where
mapExpr f list = fmap (mapExpr f) list


instance MapExpr a => MapExpr (a, Bool) where
instance MapExpr a => MapExpr (a, Multiline) where
mapExpr f (a, b) = (mapExpr f a, b)


Expand Down Expand Up @@ -85,8 +85,8 @@ instance MapExpr Expr' where
If (mapExpr f c1) (mapExpr f elseIfs) (mapExpr f els)
Let decls pre body ->
Let (mapExpr f decls) pre body
Case cond branches ->
Case (mapExpr f cond) (mapExpr f branches)
Case cond branches multiline ->
Case (mapExpr f cond) (mapExpr f branches) multiline
GLShader _ -> expr


Expand Down
47 changes: 28 additions & 19 deletions src/ElmFormat/Render/Box.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1493,51 +1493,60 @@ formatExpression' elmVersion importInfo context aexpr =
]
|> expressionParens AmbiguousEnd context -- TODO: not tested

AST.Expression.Case (subject,multiline) clauses ->
AST.Expression.Case (subject, multilineSubject) clauses multilineClauses ->
let
opening =
case
( multiline
( multilineSubject
, formatCommentedExpression elmVersion importInfo SyntaxSeparated subject
)
of
(False, SingleLine subject') ->
line $ row
[ keyword "case"
, space
, subject'
, space
, keyword "of"
]
(AST.JoinAll, SingleLine subject') ->
line $ row [ keyword "case" , space , subject' , space , keyword "of" ]
(_, subject') ->
stack1
[ line $ keyword "case"
, indent subject'
, line $ keyword "of"
]

clause (pat, expr) =
(multiline, clauses') =
List.mapAccumR
(\mline (pat, expr) ->
case formatHeadCommentedStack (formatExpression elmVersion importInfo SyntaxSeparated) expr of
body@(SingleLine _) ->
(mline, (pat, body))
body ->
(AST.SplitAll, (pat, body))
)
multilineClauses
clauses

clause multiline' (pat, body) =
case
( pat
( multiline'
, pat
, (formatPattern elmVersion False $ (\(AST.Commented _ x _) -> x) pat)
|> negativeCasePatternWorkaround pat
, formatCommentedStack (formatPattern elmVersion False) pat
|> negativeCasePatternWorkaround pat
, formatHeadCommentedStack (formatExpression elmVersion importInfo SyntaxSeparated) expr
, body
)
of
(_, _, SingleLine pat', body') ->
(AST.JoinAll, _, _, SingleLine pat', SingleLine body') ->
line $ row [pat', space, keyword "->", space, body']
(_, _, _, SingleLine pat', body') ->
stack1
[ line $ row [ pat', space, keyword "->"]
, indent body'
]
(AST.Commented pre _ [], SingleLine pat', _, body') ->
(_, AST.Commented pre _ [], SingleLine pat', _, body') ->
stack1 $
(map formatComment pre)
++ [ line $ row [ pat', space, keyword "->"]
, indent body'
]
(_, _, pat', body') ->
(_, _, _, pat', body') ->
stack1 $
[ pat'
, line $ keyword "->"
Expand All @@ -1546,9 +1555,9 @@ formatExpression' elmVersion importInfo context aexpr =
in
opening
|> andThen
(clauses
|> map clause
|> List.intersperse blankLine
(clauses'
|> map (clause multiline)
|> (if AST.isMultiline multiline then List.intersperse blankLine else id)
|> map indent
)
|> expressionParens AmbiguousEnd context -- TODO: not tested
Expand Down
10 changes: 5 additions & 5 deletions tests/Parse/ExpressionTest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,11 @@ tests =
]

, testGroup "case statement"
[ example "" "case 9 of\n 1->10\n _->20" $ at 1 1 3 7 (Case (Commented [] (at 1 6 1 7 (Literal (IntNum 9 DecimalInt))) [],False) [(Commented [] (at 2 2 2 3 (P.Literal (IntNum 1 DecimalInt))) [],([],at 2 5 2 7 (Literal (IntNum 10 DecimalInt)))),(Commented [] (at 3 2 3 3 Anything) [],([],at 3 5 3 7 (Literal (IntNum 20 DecimalInt))))])
, example "no newline after 'of'" "case 9 of 1->10\n _->20" $ at 1 1 2 16 (Case (Commented [] (at 1 6 1 7 (Literal (IntNum 9 DecimalInt))) [],False) [(Commented [] (at 1 11 1 12 (P.Literal (IntNum 1 DecimalInt))) [],([],at 1 14 1 16 (Literal (IntNum 10 DecimalInt)))),(Commented [] (at 2 11 2 12 Anything) [],([],at 2 14 2 16 (Literal (IntNum 20 DecimalInt))))])
, example "whitespace" "case 9 of\n 1 -> 10\n _ -> 20" $ at 1 1 3 9 (Case (Commented [] (at 1 6 1 7 (Literal (IntNum 9 DecimalInt))) [],False) [(Commented [] (at 2 2 2 3 (P.Literal (IntNum 1 DecimalInt))) [],([],at 2 7 2 9 (Literal (IntNum 10 DecimalInt)))),(Commented [] (at 3 2 3 3 Anything) [],([],at 3 7 3 9 (Literal (IntNum 20 DecimalInt))))])
, example "comments" "case{-A-}9{-B-}of{-C-}\n{-D-}1{-E-}->{-F-}10{-G-}\n{-H-}_{-I-}->{-J-}20" $ at 1 1 3 21 (Case (Commented [BlockComment ["A"]] (at 1 10 1 11 (Literal (IntNum 9 DecimalInt))) [BlockComment ["B"]],False) [(Commented [BlockComment ["C"],BlockComment ["D"]] (at 2 6 2 7 (P.Literal (IntNum 1 DecimalInt))) [BlockComment ["E"]],([BlockComment ["F"]],at 2 19 2 21 (Literal (IntNum 10 DecimalInt)))),(Commented [BlockComment ["G"],BlockComment ["H"]] (at 3 6 3 7 Anything) [BlockComment ["I"]],([BlockComment ["J"]],at 3 19 3 21 (Literal (IntNum 20 DecimalInt))))])
, example "newlines" "case\n 9\n of\n 1\n ->\n 10\n _\n ->\n 20" $ at 1 1 9 4 (Case (Commented [] (at 2 2 2 3 (Literal (IntNum 9 DecimalInt))) [],True) [(Commented [] (at 4 2 4 3 (P.Literal (IntNum 1 DecimalInt))) [],([],at 6 2 6 4 (Literal (IntNum 10 DecimalInt)))),(Commented [] (at 7 2 7 3 Anything) [],([],at 9 2 9 4 (Literal (IntNum 20 DecimalInt))))])
[ example "" "case 9 of\n 1->10\n _->20" $ at 1 1 3 7 (Case (Commented [] (at 1 6 1 7 (Literal (IntNum 9 DecimalInt))) [],JoinAll) [(Commented [] (at 2 2 2 3 (P.Literal (IntNum 1 DecimalInt))) [],([],at 2 5 2 7 (Literal (IntNum 10 DecimalInt)))),(Commented [] (at 3 2 3 3 Anything) [],([],at 3 5 3 7 (Literal (IntNum 20 DecimalInt))))] JoinAll)
, example "no newline after 'of'" "case 9 of 1->10\n _->20" $ at 1 1 2 16 (Case (Commented [] (at 1 6 1 7 (Literal (IntNum 9 DecimalInt))) [],JoinAll) [(Commented [] (at 1 11 1 12 (P.Literal (IntNum 1 DecimalInt))) [],([],at 1 14 1 16 (Literal (IntNum 10 DecimalInt)))),(Commented [] (at 2 11 2 12 Anything) [],([],at 2 14 2 16 (Literal (IntNum 20 DecimalInt))))] JoinAll)
, example "whitespace" "case 9 of\n 1 -> 10\n _ -> 20" $ at 1 1 3 9 (Case (Commented [] (at 1 6 1 7 (Literal (IntNum 9 DecimalInt))) [],JoinAll) [(Commented [] (at 2 2 2 3 (P.Literal (IntNum 1 DecimalInt))) [],([],at 2 7 2 9 (Literal (IntNum 10 DecimalInt)))),(Commented [] (at 3 2 3 3 Anything) [],([],at 3 7 3 9 (Literal (IntNum 20 DecimalInt))))] JoinAll)
, example "comments" "case{-A-}9{-B-}of{-C-}\n{-D-}1{-E-}->{-F-}10{-G-}\n{-H-}_{-I-}->{-J-}20" $ at 1 1 3 21 (Case (Commented [BlockComment ["A"]] (at 1 10 1 11 (Literal (IntNum 9 DecimalInt))) [BlockComment ["B"]],JoinAll) [(Commented [BlockComment ["C"],BlockComment ["D"]] (at 2 6 2 7 (P.Literal (IntNum 1 DecimalInt))) [BlockComment ["E"]],([BlockComment ["F"]],at 2 19 2 21 (Literal (IntNum 10 DecimalInt)))),(Commented [BlockComment ["G"],BlockComment ["H"]] (at 3 6 3 7 Anything) [BlockComment ["I"]],([BlockComment ["J"]],at 3 19 3 21 (Literal (IntNum 20 DecimalInt))))] JoinAll)
, example "newlines" "case\n 9\n of\n 1\n ->\n 10\n _\n ->\n 20" $ at 1 1 9 4 (Case (Commented [] (at 2 2 2 3 (Literal (IntNum 9 DecimalInt))) [],SplitAll) [(Commented [] (at 4 2 4 3 (P.Literal (IntNum 1 DecimalInt))) [],([],at 6 2 6 4 (Literal (IntNum 10 DecimalInt)))),(Commented [] (at 7 2 7 3 Anything) [],([],at 9 2 9 4 (Literal (IntNum 20 DecimalInt))))] SplitAll)
, testCase "should not consume trailing whitespace" $
assertParse (expr Elm_0_19>> string "\nX") "case 9 of\n 1->10\n _->20\nX" $ "\nX"
, testGroup "clauses must start at the same column"
Expand Down
14 changes: 12 additions & 2 deletions tests/test-files/good/Elm-0.19/AllSyntax/Expressions.elm
Original file line number Diff line number Diff line change
Expand Up @@ -339,14 +339,24 @@ letStatement =
caseStatement =
let
a =
case Just 1 of
Just x -> x
_ -> 2

b =
case Just 1 of
Just x ->
x

_ ->
2

b =
c =
case {- A -} Just 1 {- B -} of
Just x -> x
_ -> 2

d =
case {- M -} Just 1 {- N -} of
{- O -}
Just x
Expand All @@ -362,7 +372,7 @@ caseStatement =
{- T -}
2

c =
e =
case
--M
Just 1
Expand Down

0 comments on commit 163199f

Please sign in to comment.