packages feed

kempe-0.1.1.1: src/Kempe/Check/TopLevel.hs

module Kempe.Check.TopLevel ( topLevelCheck
                            , Warning
                            ) where

import           Control.Applicative ((<|>))
import           Data.Foldable       (toList)
import           Data.Foldable.Ext
import           Data.List           (group, sort)
import           Data.Maybe          (mapMaybe)
import           Kempe.AST
import           Kempe.Error.Warning
import           Kempe.Name

topLevelCheck :: Declarations a c a -> Maybe (Warning a)
topLevelCheck ds =
        checkNames (collectNames ds)
    <|> checkNames (collectCons ds)

-- | Just checks function names and type names. Doesn't check constructors.
collectNames :: Declarations a c a -> [Name a]
collectNames = mapMaybe collectDeclNames where
    collectDeclNames (FunDecl _ n _ _ _)   = Just n
    collectDeclNames (ExtFnDecl _ n _ _ _) = Just n
    collectDeclNames Export{}              = Nothing
    collectDeclNames (TyDecl _ tn _ _)     = Just tn

collectCons :: Declarations a c b-> [Name b]
collectCons = concatMap collectDeclNames where
    collectDeclNames (TyDecl _ _ _ ls) = toList (fst <$> ls)
    collectDeclNames _                 = []

checkNames :: [Name a] -> Maybe (Warning a)
checkNames ns = foldMapAlternative announce (group $ sort ns) -- maybe could be better idk
    where announce (_:y:_) = Just $ NameClash (loc y) y
          announce _       = Nothing