module Language.Dickinson.Check.Duplicate ( checkDuplicates
) where
import Control.Applicative ((<|>))
import Data.Foldable (toList)
import Data.Foldable.Ext (foldMapAlternative)
import Data.Function (on)
import Data.List (groupBy, sortBy)
import Data.Maybe (mapMaybe)
import qualified Data.Text as T
import Language.Dickinson.Error
import Language.Dickinson.Type
checkNames :: [(a, T.Text)] -> Maybe (DickinsonWarning a)
checkNames :: forall a. [(a, Text)] -> Maybe (DickinsonWarning a)
checkNames [(a, Text)]
ns = forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Alternative f) =>
(a -> f b) -> t a -> f b
foldMapAlternative forall a. [(a, Text)] -> Maybe (DickinsonWarning a)
announce (forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (forall a. Eq a => a -> a -> Bool
(==) forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` forall a b. (a, b) -> b
snd) forall a b. (a -> b) -> a -> b
$ forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (forall a. Ord a => a -> a -> Ordering
compare forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` forall a b. (a, b) -> b
snd) [(a, Text)]
ns)
where announce :: [(a, Text)] -> Maybe (DickinsonWarning a)
announce ((a, Text)
_:(a
l, Text
y):[(a, Text)]
_) = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> Text -> DickinsonWarning a
DuplicateStr a
l Text
y
announce [(a, Text)]
_ = forall a. Maybe a
Nothing
checkDuplicates :: [Declaration a] -> Maybe (DickinsonWarning a)
checkDuplicates :: forall a. [Declaration a] -> Maybe (DickinsonWarning a)
checkDuplicates = forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Alternative f) =>
(a -> f b) -> t a -> f b
foldMapAlternative forall a. Declaration a -> Maybe (DickinsonWarning a)
checkDeclDuplicates
checkDeclDuplicates :: Declaration a -> Maybe (DickinsonWarning a)
checkDeclDuplicates :: forall a. Declaration a -> Maybe (DickinsonWarning a)
checkDeclDuplicates (Define a
_ Name a
_ Expression a
e) = forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates Expression a
e
checkDeclDuplicates TyDecl{} = forall a. Maybe a
Nothing
extrText :: Expression a -> Maybe (a, T.Text)
extrText :: forall a. Expression a -> Maybe (a, Text)
extrText (Literal a
l Text
t) = forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
l, Text
t)
extrText Expression a
_ = forall a. Maybe a
Nothing
collectText :: [(b, Expression a)] -> [(a, T.Text)]
collectText :: forall b a. [(b, Expression a)] -> [(a, Text)]
collectText = forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (forall a. Expression a -> Maybe (a, Text)
extrText forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd)
checkExprDuplicates :: Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates :: forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates Var{} = forall a. Maybe a
Nothing
checkExprDuplicates Literal{} = forall a. Maybe a
Nothing
checkExprDuplicates StrChunk{} = forall a. Maybe a
Nothing
checkExprDuplicates (Interp a
_ [Expression a]
es) = forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Alternative f) =>
(a -> f b) -> t a -> f b
foldMapAlternative forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates [Expression a]
es
checkExprDuplicates (MultiInterp a
_ [Expression a]
es) = forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Alternative f) =>
(a -> f b) -> t a -> f b
foldMapAlternative forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates [Expression a]
es
checkExprDuplicates (Concat a
_ [Expression a]
es) = forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Alternative f) =>
(a -> f b) -> t a -> f b
foldMapAlternative forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates [Expression a]
es
checkExprDuplicates (Tuple a
_ NonEmpty (Expression a)
es) = forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Alternative f) =>
(a -> f b) -> t a -> f b
foldMapAlternative forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates NonEmpty (Expression a)
es
checkExprDuplicates (Apply a
_ Expression a
e Expression a
e') = forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates Expression a
e forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates Expression a
e'
checkExprDuplicates (Choice a
_ NonEmpty (Double, Expression a)
brs) = forall a. [(a, Text)] -> Maybe (DickinsonWarning a)
checkNames (forall b a. [(b, Expression a)] -> [(a, Text)]
collectText forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty (Double, Expression a)
brs)
checkExprDuplicates (Let a
_ NonEmpty (Name a, Expression a)
brs Expression a
es) = forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Alternative f) =>
(a -> f b) -> t a -> f b
foldMapAlternative forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates (forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (Name a, Expression a)
brs) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates Expression a
es
checkExprDuplicates (Bind a
_ NonEmpty (Name a, Expression a)
brs Expression a
es) = forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Alternative f) =>
(a -> f b) -> t a -> f b
foldMapAlternative forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates (forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (Name a, Expression a)
brs) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates Expression a
es
checkExprDuplicates (Lambda a
_ Name a
_ DickinsonTy a
_ Expression a
e) = forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates Expression a
e
checkExprDuplicates (Match a
_ Expression a
e NonEmpty (Pattern a, Expression a)
brs) = forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates Expression a
e forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Alternative f) =>
(a -> f b) -> t a -> f b
foldMapAlternative (forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) NonEmpty (Pattern a, Expression a)
brs
checkExprDuplicates (Flatten a
_ Expression a
e) = forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates Expression a
e
checkExprDuplicates (Annot a
_ Expression a
e DickinsonTy a
_) = forall a. Expression a -> Maybe (DickinsonWarning a)
checkExprDuplicates Expression a
e
checkExprDuplicates Constructor{} = forall a. Maybe a
Nothing
checkExprDuplicates BuiltinFn{} = forall a. Maybe a
Nothing
checkExprDuplicates Random{} = forall a. Maybe a
Nothing