diff --git a/src/Elm/AST/Canonical.elm b/src/Elm/AST/Canonical.elm index 8e5c7242..3c1b566a 100644 --- a/src/Elm/AST/Canonical.elm +++ b/src/Elm/AST/Canonical.elm @@ -69,6 +69,7 @@ type Expr | Tuple LocatedExpr LocatedExpr | Tuple3 LocatedExpr LocatedExpr LocatedExpr | Record (Dict VarName (Binding LocatedExpr)) + | RecordAccessor VarName {-| Discard the [location metadata](Elm.Data.Located#Located). @@ -159,6 +160,9 @@ unwrap expr = (always (Binding.map unwrap)) bindings + RecordAccessor name -> + Unwrapped.RecordAccessor name + {-| Adds [**dummy** locations](Elm.Data.Located#dummyRegion) to the [Unwrapped.Expr](Elm.AST.Canonical.Unwrapped#Expr). -} @@ -248,3 +252,6 @@ fromUnwrapped expr = Dict.map (always (Binding.map fromUnwrapped)) bindings + + Unwrapped.RecordAccessor name -> + RecordAccessor name diff --git a/src/Elm/AST/Canonical/Unwrapped.elm b/src/Elm/AST/Canonical/Unwrapped.elm index 8b96c85e..6c775b1c 100644 --- a/src/Elm/AST/Canonical/Unwrapped.elm +++ b/src/Elm/AST/Canonical/Unwrapped.elm @@ -38,3 +38,4 @@ type Expr | Tuple Expr Expr | Tuple3 Expr Expr Expr | Record (Dict VarName (Binding Expr)) + | RecordAccessor VarName diff --git a/src/Elm/AST/Frontend.elm b/src/Elm/AST/Frontend.elm index b341d948..da0add87 100644 --- a/src/Elm/AST/Frontend.elm +++ b/src/Elm/AST/Frontend.elm @@ -67,6 +67,7 @@ type Expr | Tuple LocatedExpr LocatedExpr | Tuple3 LocatedExpr LocatedExpr LocatedExpr | Record (List (Binding LocatedExpr)) + | RecordAccessor VarName {-| A helper for the [Transform](/packages/Janiczek/transform/latest/) library. @@ -150,6 +151,9 @@ recurse f expr = Record bindings -> Record <| List.map (Binding.map f_) bindings + RecordAccessor _ -> + expr + {-| [Transform](/packages/Janiczek/transform/latest/Transform#transformAll) the expression using the provided function. @@ -256,3 +260,6 @@ unwrap expr = Record bindings -> Unwrapped.Record <| List.map (Binding.map unwrap) bindings + + RecordAccessor name -> + Unwrapped.RecordAccessor name diff --git a/src/Elm/AST/Frontend/Unwrapped.elm b/src/Elm/AST/Frontend/Unwrapped.elm index 9ba048b4..be22c3ae 100644 --- a/src/Elm/AST/Frontend/Unwrapped.elm +++ b/src/Elm/AST/Frontend/Unwrapped.elm @@ -36,3 +36,4 @@ type Expr | Tuple Expr Expr | Tuple3 Expr Expr Expr | Record (List (Binding Expr)) + | RecordAccessor VarName diff --git a/src/Elm/AST/Typed.elm b/src/Elm/AST/Typed.elm index 83c75a3a..99e09042 100644 --- a/src/Elm/AST/Typed.elm +++ b/src/Elm/AST/Typed.elm @@ -75,6 +75,7 @@ type Expr_ | Tuple LocatedExpr LocatedExpr | Tuple3 LocatedExpr LocatedExpr LocatedExpr | Record (Dict VarName (Binding LocatedExpr)) + | RecordAccessor VarName {-| A helper for the [Transform](/packages/Janiczek/transform/latest/) library. @@ -165,6 +166,9 @@ recurse fn locatedExpr = (always (Binding.map fn)) bindings ) + + RecordAccessor name -> + expr ) @@ -256,6 +260,9 @@ recursiveChildren fn locatedExpr = Record bindings -> List.concatMap (.body >> fn) (Dict.values bindings) + RecordAccessor _ -> + [] + mapExpr : (Expr_ -> Expr_) -> LocatedExpr -> LocatedExpr mapExpr fn locatedExpr = @@ -375,6 +382,9 @@ unwrap expr = Dict.map (always (Binding.map unwrap)) bindings + + RecordAccessor name -> + Unwrapped.RecordAccessor name , type_ ) @@ -463,4 +473,7 @@ dropTypes locatedExpr = Record bindings -> Canonical.Record <| Dict.map (always (Binding.map dropTypes)) bindings + + RecordAccessor name -> + Canonical.RecordAccessor name ) diff --git a/src/Elm/AST/Typed/Unwrapped.elm b/src/Elm/AST/Typed/Unwrapped.elm index d02eb369..95f24836 100644 --- a/src/Elm/AST/Typed/Unwrapped.elm +++ b/src/Elm/AST/Typed/Unwrapped.elm @@ -44,3 +44,4 @@ type Expr_ | Tuple Expr Expr | Tuple3 Expr Expr Expr | Record (Dict VarName (Binding Expr)) + | RecordAccessor VarName diff --git a/src/Elm/Data/Type.elm b/src/Elm/Data/Type.elm index 005ec00f..827813e0 100644 --- a/src/Elm/Data/Type.elm +++ b/src/Elm/Data/Type.elm @@ -24,6 +24,7 @@ type Type | Tuple Type Type | Tuple3 Type Type Type | Record (Dict VarName Type) + | ExtensibleRecord ( VarName, Type ) (Dict VarName Type) -- An extensible record has at least a binding | {- The actual definitions of type aliases and custom types are elsewhere (in the Declaration module), this is just a "pointer", "var". diff --git a/src/Elm/Data/Type/ToString.elm b/src/Elm/Data/Type/ToString.elm index f38771d8..f2924fbc 100644 --- a/src/Elm/Data/Type/ToString.elm +++ b/src/Elm/Data/Type/ToString.elm @@ -183,6 +183,26 @@ toString state type_ = else ( "{ " ++ bindingsStr ++ " }", state1 ) + ExtensibleRecord firstBinding otherBindings -> + let + ( bindingsStr, state1 ) = + List.foldr + (\param ( acc, state2 ) -> + let + ( string, state3 ) = + niceRecordBinding state2 param + in + ( string :: acc, state3 ) + ) + ( [], state ) + (firstBinding :: Dict.toList otherBindings) + |> Tuple.mapFirst (String.join ", ") + + ( newName, newState ) = + getFreeName state1 + in + ( "{ " ++ newName ++ " | " ++ bindingsStr ++ " }", newState ) + getName : State -> Int -> ( String, State ) getName ((State { counter, mapping }) as state) varId = @@ -203,6 +223,11 @@ getName ((State { counter, mapping }) as state) varId = ) +getFreeName : State -> ( String, State ) +getFreeName (State r) = + ( niceVarName r.counter, State { r | counter = r.counter + 1 } ) + + {-| Function to get from a number to a nice type variable name. It follows this sequence: @@ -322,3 +347,6 @@ shouldWrapParens type_ = Record _ -> False + + ExtensibleRecord _ _ -> + False diff --git a/src/Stage/Desugar.elm b/src/Stage/Desugar.elm index 66d9d2cf..1cbc020a 100644 --- a/src/Stage/Desugar.elm +++ b/src/Stage/Desugar.elm @@ -196,6 +196,9 @@ desugarExpr modules thisModule located = |> Canonical.Record ) + Frontend.RecordAccessor name -> + return <| Canonical.RecordAccessor name + -- HELPERS