elm-review/tests/NoLeftPizzaUtil.elm

122 lines
4.3 KiB
Elm

module NoLeftPizzaUtil exposing (expressionToString)
import Elm.Syntax.Expression as Expression exposing (Expression)
import Elm.Syntax.Node as Node exposing (Node)
import Elm.Syntax.Range exposing (Range)
import Elm.Writer as Writer
expressionToString : Range -> Expression -> String
expressionToString range expr =
Node.Node range expr
-- Writer expects a slightly different AST than parsing produces
-- TODO: log issue!
|> fixAst
|> Writer.writeExpression
|> Writer.write
-- To make things more parseable by our dear old elm-format, we indent all extra
-- lines so they appear to the right of where we're starting at
|> reindent range.start.column
fixAst : Node Expression -> Node Expression
fixAst ((Node.Node range expr) as node) =
case expr of
Expression.Application nodes ->
Node.Node range (Expression.Application (List.map fixAst nodes))
Expression.OperatorApplication op dir left right ->
Node.Node range
(Expression.OperatorApplication op dir (fixAst left) (fixAst right))
Expression.IfBlock cond trueBranch falseBranch ->
Node.Node range
(Expression.IfBlock (fixAst cond) (fixAst trueBranch) (fixAst falseBranch))
Expression.Negation inner ->
Node.Node range (Expression.Negation (fixAst inner))
Expression.TupledExpression nodes ->
Node.Node range (Expression.TupledExpression (List.map fixAst nodes))
Expression.ParenthesizedExpression inner ->
Node.Node range (Expression.ParenthesizedExpression (fixAst inner))
Expression.LetExpression { declarations, expression } ->
Node.Node range
(Expression.LetExpression
{ declarations = List.map fixLetDeclarationAst declarations
, expression = fixAst expression
}
)
Expression.CaseExpression { expression, cases } ->
Node.Node range
(Expression.CaseExpression
{ expression = fixAst expression
, cases = List.map fixCaseAst cases
}
)
Expression.LambdaExpression { args, expression } ->
Node.Node range
(Expression.LambdaExpression
{ args = args
, expression = fixAst expression
}
)
Expression.RecordExpr setters ->
Node.Node range
(Expression.RecordExpr (List.map fixSetterAst setters))
Expression.ListExpr nodes ->
Node.Node range (Expression.ListExpr (List.map fixAst nodes))
Expression.RecordAccess which field ->
Node.Node range (Expression.RecordAccess (fixAst which) field)
Expression.RecordAccessFunction field ->
-- Writer expects a record-access function to be `"foo"` whereas the parser produces `".foo"`
Node.Node range (Expression.RecordAccessFunction (String.dropLeft 1 field))
Expression.RecordUpdateExpression record setters ->
Node.Node range (Expression.RecordUpdateExpression record (List.map fixSetterAst setters))
_ ->
node
fixCaseAst : Expression.Case -> Expression.Case
fixCaseAst ( pat, node ) =
( pat, fixAst node )
fixLetDeclarationAst : Node Expression.LetDeclaration -> Node Expression.LetDeclaration
fixLetDeclarationAst (Node.Node range decl) =
case decl of
Expression.LetFunction ({ declaration } as f) ->
let
(Node.Node iRange iDecl) =
declaration
in
Node.Node range
(Expression.LetFunction
{ f
| declaration = Node.Node iRange { iDecl | expression = fixAst iDecl.expression }
}
)
Expression.LetDestructuring pat node ->
Node.Node range (Expression.LetDestructuring pat (fixAst node))
fixSetterAst : Node Expression.RecordSetter -> Node Expression.RecordSetter
fixSetterAst (Node.Node range ( name, node )) =
Node.Node range ( name, fixAst node )
reindent : Int -> String -> String
reindent amount =
String.lines >> String.join ("\n" ++ String.repeat (amount - 1) " ")