module SyntaxTrees.Scala.PackageDef where

import Data.List                 (intercalate)
import SyntaxTrees.Scala.Common  (Package, Var, VarOp)
import SyntaxTrees.Scala.DataDef (InternalDef)
import SyntaxTrees.Scala.Type    (TypeVar)
import Utils.String


data PackageDef
  = PackageDef
      { PackageDef -> Package
name    :: Package
      , PackageDef -> [PackageImport]
imports :: [PackageImport]
      , PackageDef -> [InternalDef]
defs    :: [InternalDef]
      }

data PackageImport
  = PackageImport
      { PackageImport -> Package
package   :: Package
      , PackageImport -> Maybe Package
alias     :: Maybe Package
      , PackageImport -> Maybe PackageImportDef
importDef :: Maybe PackageImportDef
      }

data PackageImportDef
  = FullImport
  | MembersImport [PackageMember]
  | FullObjectImport TypeVar
  | FilteredObjectImport TypeVar [PackageMember]

data PackageMember
  = VarMember Var
  | VarOpMember VarOp
  | DataMember TypeVar


instance Show PackageDef where
  show :: PackageDef -> String
show (PackageDef Package
x [PackageImport]
y [InternalDef]
z) =
    [String] -> String
joinLines [String
"package" String -> ShowS
+++ forall a. Show a => a -> String
show Package
x,
               forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" (forall a. Show a => a -> String
show forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [PackageImport]
y),
               [String] -> String
joinLines (forall a. Show a => a -> String
show forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [InternalDef]
z)]

instance Show PackageImport where
  show :: PackageImport -> String
show (PackageImport Package
x Maybe Package
y Maybe PackageImportDef
z) =
    [String] -> String
joinWords [String
"import",
               forall a. Show a => a -> String
show Package
x,
               String
"as" forall a. Show a => String -> Maybe a -> String
`joinMaybe` Maybe Package
y]
    forall a. [a] -> [a] -> [a]
++ String
"." forall a. Show a => String -> Maybe a -> String
`joinMaybe` Maybe PackageImportDef
z

instance Show PackageImportDef where
  show :: PackageImportDef -> String
show PackageImportDef
FullImport                   = String
"_"
  show (MembersImport [PackageMember
x])          = forall a. Show a => a -> String
show PackageMember
x
  show (MembersImport [PackageMember]
x)            = forall a. Show a => [a] -> String
wrapCurlyCsv [PackageMember]
x
  show (FullObjectImport TypeVar
x)         = forall a. Show a => a -> String
show TypeVar
x forall a. [a] -> [a] -> [a]
++ String
"." forall a. [a] -> [a] -> [a]
++ String
"_"
  show (FilteredObjectImport TypeVar
x [PackageMember
y]) = forall a. Show a => a -> String
show TypeVar
x forall a. [a] -> [a] -> [a]
++ String
"." forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show PackageMember
y
  show (FilteredObjectImport TypeVar
x [PackageMember]
y)   = forall a. Show a => a -> String
show TypeVar
x forall a. [a] -> [a] -> [a]
++ String
"." forall a. [a] -> [a] -> [a]
++ forall a. Show a => [a] -> String
wrapCurlyCsv [PackageMember]
y

instance Show PackageMember where
  show :: PackageMember -> String
show (VarMember Var
x)   = forall a. Show a => a -> String
show Var
x
  show (VarOpMember VarOp
x) = forall a. Show a => a -> String
show VarOp
x
  show (DataMember TypeVar
x)  = forall a. Show a => a -> String
show TypeVar
x