module Conversions.ToScala.DataDef where

import qualified SyntaxTrees.Haskell.DataDef as H
import qualified SyntaxTrees.Scala.Common    as S
import qualified SyntaxTrees.Scala.DataDef   as S
import qualified SyntaxTrees.Scala.Type      as S

import Conversions.ToScala.Common  (autoIds, class', ctor, var)
import Conversions.ToScala.Type    (anyKindedType, type', typeCtor, typeParam)
import SyntaxTrees.Haskell.DataDef (derivingClasses)


typeDef :: H.TypeDef -> S.TypeDef
typeDef :: TypeDef -> TypeDef
typeDef (H.TypeDef TypeCtor
x [TypeParam]
y AnyKindedType
z) =
  TypeCtor -> [TypeParam] -> Type -> TypeDef
S.TypeDef (TypeCtor -> TypeCtor
typeCtor TypeCtor
x) (TypeParam -> TypeParam
typeParam forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [TypeParam]
y) (AnyKindedType -> Type
anyKindedType AnyKindedType
z)


newtypeDef :: H.NewTypeDef -> S.OpaqueTypeDef
newtypeDef :: NewTypeDef -> OpaqueTypeDef
newtypeDef (H.NewTypeDef TypeCtor
x [TypeParam]
y Ctor
_  FieldDef
z [DerivingClause]
t) =
  TypeCtor -> [TypeParam] -> Type -> [TypeClass] -> OpaqueTypeDef
S.OpaqueTypeDef (TypeCtor -> TypeCtor
typeCtor TypeCtor
x) (TypeParam -> TypeParam
typeParam forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [TypeParam]
y)
                  ((.type') forall a b. (a -> b) -> a -> b
$ FieldDef -> ArgField
fieldDef FieldDef
z)
                  (Class -> TypeClass
class' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((forall a b. (a, b) -> b
snd <$>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. DerivingClause -> [(DerivingStrategy, Class)]
derivingClasses) [DerivingClause]
t)


dataDef :: H.DataDef -> S.EnumDef
dataDef :: DataDef -> EnumDef
dataDef (H.DataDef TypeCtor
x [TypeParam]
y [DataCtorDef]
z [DerivingClause]
t) =
  [Modifier]
-> TypeCtor
-> [TypeParam]
-> [ArgList]
-> [UsingArgList]
-> [TypeClass]
-> [EnumCaseDef]
-> EnumDef
S.EnumDef [] (TypeCtor -> TypeCtor
typeCtor TypeCtor
x) (TypeParam -> TypeParam
typeParam forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [TypeParam]
y) [] []
               (Class -> TypeClass
class' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((forall a b. (a, b) -> b
snd <$>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. DerivingClause -> [(DerivingStrategy, Class)]
derivingClasses) [DerivingClause]
t)
               (DataCtorDef -> EnumCaseDef
dataCtorDef forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [DataCtorDef]
z)


dataCtorDef :: H.DataCtorDef -> S.EnumCaseDef
dataCtorDef :: DataCtorDef -> EnumCaseDef
dataCtorDef (H.NamedFieldsCtor Ctor
x [NamedFieldDef]
y) = Ctor
-> [ArgList]
-> [UsingArgList]
-> [Type]
-> [InternalFnDef]
-> EnumCaseDef
S.EnumCaseDef (Ctor -> Ctor
ctor Ctor
x)
        [[ArgField] -> ArgList
S.ArgList forall a b. (a -> b) -> a -> b
$ NamedFieldDef -> ArgField
namedFieldDef forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [NamedFieldDef]
y] [] [] []
dataCtorDef (H.UnNamedFieldsCtor Ctor
x [UnNamedFieldDef]
y) = Ctor
-> [ArgList]
-> [UsingArgList]
-> [Type]
-> [InternalFnDef]
-> EnumCaseDef
S.EnumCaseDef (Ctor -> Ctor
ctor Ctor
x)
        [[ArgField] -> ArgList
S.ArgList forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry String -> UnNamedFieldDef -> ArgField
unNamedFieldDef forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a b. [a] -> [b] -> [(a, b)]
zip [String]
autoIds [UnNamedFieldDef]
y] [] [] []


fieldDef :: H.FieldDef -> S.ArgField
fieldDef :: FieldDef -> ArgField
fieldDef (H.NamedField NamedFieldDef
x)   = NamedFieldDef -> ArgField
namedFieldDef NamedFieldDef
x
fieldDef (H.UnNamedField UnNamedFieldDef
x) = String -> UnNamedFieldDef -> ArgField
unNamedFieldDef String
"value" UnNamedFieldDef
x


namedFieldDef :: H.NamedFieldDef -> S.ArgField
namedFieldDef :: NamedFieldDef -> ArgField
namedFieldDef (H.NamedFieldDef Var
x Type
y) = [Modifier] -> Var -> Type -> ArgField
S.ArgField [] (Var -> Var
var Var
x) (Type -> Type
type' Type
y)

unNamedFieldDef :: String -> H.UnNamedFieldDef -> S.ArgField
unNamedFieldDef :: String -> UnNamedFieldDef -> ArgField
unNamedFieldDef String
x (H.UnNamedFieldDef Type
y) = [Modifier] -> Var -> Type -> ArgField
S.ArgField [] (String -> Var
S.Var String
x) (Type -> Type
type' Type
y)