{-# language DeriveAnyClass #-} {-# language DeriveGeneric #-} {-# language DerivingStrategies #-} {-# language GeneralizedNewtypeDeriving #-} {-# language OverloadedStrings #-} {-# language ViewPatterns #-} module Language.Elm.Name where import Data.Bifunctor import qualified Data.Char as Char import Data.Hashable import Data.String import Data.Text (Text) import qualified Data.Text as Text import GHC.Generics (Generic) type Module = [Text] newtype Local = Local Text deriving stock (Local -> Local -> Bool (Local -> Local -> Bool) -> (Local -> Local -> Bool) -> Eq Local forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: Local -> Local -> Bool == :: Local -> Local -> Bool $c/= :: Local -> Local -> Bool /= :: Local -> Local -> Bool Eq, Eq Local Eq Local => (Local -> Local -> Ordering) -> (Local -> Local -> Bool) -> (Local -> Local -> Bool) -> (Local -> Local -> Bool) -> (Local -> Local -> Bool) -> (Local -> Local -> Local) -> (Local -> Local -> Local) -> Ord Local Local -> Local -> Bool Local -> Local -> Ordering Local -> Local -> Local forall a. Eq a => (a -> a -> Ordering) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> a) -> (a -> a -> a) -> Ord a $ccompare :: Local -> Local -> Ordering compare :: Local -> Local -> Ordering $c< :: Local -> Local -> Bool < :: Local -> Local -> Bool $c<= :: Local -> Local -> Bool <= :: Local -> Local -> Bool $c> :: Local -> Local -> Bool > :: Local -> Local -> Bool $c>= :: Local -> Local -> Bool >= :: Local -> Local -> Bool $cmax :: Local -> Local -> Local max :: Local -> Local -> Local $cmin :: Local -> Local -> Local min :: Local -> Local -> Local Ord, Int -> Local -> ShowS [Local] -> ShowS Local -> String (Int -> Local -> ShowS) -> (Local -> String) -> ([Local] -> ShowS) -> Show Local forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a $cshowsPrec :: Int -> Local -> ShowS showsPrec :: Int -> Local -> ShowS $cshow :: Local -> String show :: Local -> String $cshowList :: [Local] -> ShowS showList :: [Local] -> ShowS Show, (forall x. Local -> Rep Local x) -> (forall x. Rep Local x -> Local) -> Generic Local forall x. Rep Local x -> Local forall x. Local -> Rep Local x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cfrom :: forall x. Local -> Rep Local x from :: forall x. Local -> Rep Local x $cto :: forall x. Rep Local x -> Local to :: forall x. Rep Local x -> Local Generic) deriving newtype (String -> Local (String -> Local) -> IsString Local forall a. (String -> a) -> IsString a $cfromString :: String -> Local fromString :: String -> Local IsString) deriving anyclass (Eq Local Eq Local => (Int -> Local -> Int) -> (Local -> Int) -> Hashable Local Int -> Local -> Int Local -> Int forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a $chashWithSalt :: Int -> Local -> Int hashWithSalt :: Int -> Local -> Int $chash :: Local -> Int hash :: Local -> Int Hashable) data Qualified = Qualified Module Text deriving (Qualified -> Qualified -> Bool (Qualified -> Qualified -> Bool) -> (Qualified -> Qualified -> Bool) -> Eq Qualified forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: Qualified -> Qualified -> Bool == :: Qualified -> Qualified -> Bool $c/= :: Qualified -> Qualified -> Bool /= :: Qualified -> Qualified -> Bool Eq, Eq Qualified Eq Qualified => (Qualified -> Qualified -> Ordering) -> (Qualified -> Qualified -> Bool) -> (Qualified -> Qualified -> Bool) -> (Qualified -> Qualified -> Bool) -> (Qualified -> Qualified -> Bool) -> (Qualified -> Qualified -> Qualified) -> (Qualified -> Qualified -> Qualified) -> Ord Qualified Qualified -> Qualified -> Bool Qualified -> Qualified -> Ordering Qualified -> Qualified -> Qualified forall a. Eq a => (a -> a -> Ordering) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> a) -> (a -> a -> a) -> Ord a $ccompare :: Qualified -> Qualified -> Ordering compare :: Qualified -> Qualified -> Ordering $c< :: Qualified -> Qualified -> Bool < :: Qualified -> Qualified -> Bool $c<= :: Qualified -> Qualified -> Bool <= :: Qualified -> Qualified -> Bool $c> :: Qualified -> Qualified -> Bool > :: Qualified -> Qualified -> Bool $c>= :: Qualified -> Qualified -> Bool >= :: Qualified -> Qualified -> Bool $cmax :: Qualified -> Qualified -> Qualified max :: Qualified -> Qualified -> Qualified $cmin :: Qualified -> Qualified -> Qualified min :: Qualified -> Qualified -> Qualified Ord, Int -> Qualified -> ShowS [Qualified] -> ShowS Qualified -> String (Int -> Qualified -> ShowS) -> (Qualified -> String) -> ([Qualified] -> ShowS) -> Show Qualified forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a $cshowsPrec :: Int -> Qualified -> ShowS showsPrec :: Int -> Qualified -> ShowS $cshow :: Qualified -> String show :: Qualified -> String $cshowList :: [Qualified] -> ShowS showList :: [Qualified] -> ShowS Show, (forall x. Qualified -> Rep Qualified x) -> (forall x. Rep Qualified x -> Qualified) -> Generic Qualified forall x. Rep Qualified x -> Qualified forall x. Qualified -> Rep Qualified x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cfrom :: forall x. Qualified -> Rep Qualified x from :: forall x. Qualified -> Rep Qualified x $cto :: forall x. Rep Qualified x -> Qualified to :: forall x. Rep Qualified x -> Qualified Generic) deriving anyclass (Eq Qualified Eq Qualified => (Int -> Qualified -> Int) -> (Qualified -> Int) -> Hashable Qualified Int -> Qualified -> Int Qualified -> Int forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a $chashWithSalt :: Int -> Qualified -> Int hashWithSalt :: Int -> Qualified -> Int $chash :: Qualified -> Int hash :: Qualified -> Int Hashable) newtype Field = Field Text deriving stock (Field -> Field -> Bool (Field -> Field -> Bool) -> (Field -> Field -> Bool) -> Eq Field forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: Field -> Field -> Bool == :: Field -> Field -> Bool $c/= :: Field -> Field -> Bool /= :: Field -> Field -> Bool Eq, Eq Field Eq Field => (Field -> Field -> Ordering) -> (Field -> Field -> Bool) -> (Field -> Field -> Bool) -> (Field -> Field -> Bool) -> (Field -> Field -> Bool) -> (Field -> Field -> Field) -> (Field -> Field -> Field) -> Ord Field Field -> Field -> Bool Field -> Field -> Ordering Field -> Field -> Field forall a. Eq a => (a -> a -> Ordering) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> a) -> (a -> a -> a) -> Ord a $ccompare :: Field -> Field -> Ordering compare :: Field -> Field -> Ordering $c< :: Field -> Field -> Bool < :: Field -> Field -> Bool $c<= :: Field -> Field -> Bool <= :: Field -> Field -> Bool $c> :: Field -> Field -> Bool > :: Field -> Field -> Bool $c>= :: Field -> Field -> Bool >= :: Field -> Field -> Bool $cmax :: Field -> Field -> Field max :: Field -> Field -> Field $cmin :: Field -> Field -> Field min :: Field -> Field -> Field Ord, Int -> Field -> ShowS [Field] -> ShowS Field -> String (Int -> Field -> ShowS) -> (Field -> String) -> ([Field] -> ShowS) -> Show Field forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a $cshowsPrec :: Int -> Field -> ShowS showsPrec :: Int -> Field -> ShowS $cshow :: Field -> String show :: Field -> String $cshowList :: [Field] -> ShowS showList :: [Field] -> ShowS Show, (forall x. Field -> Rep Field x) -> (forall x. Rep Field x -> Field) -> Generic Field forall x. Rep Field x -> Field forall x. Field -> Rep Field x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cfrom :: forall x. Field -> Rep Field x from :: forall x. Field -> Rep Field x $cto :: forall x. Rep Field x -> Field to :: forall x. Rep Field x -> Field Generic) deriving newtype (String -> Field (String -> Field) -> IsString Field forall a. (String -> a) -> IsString a $cfromString :: String -> Field fromString :: String -> Field IsString) deriving anyclass (Eq Field Eq Field => (Int -> Field -> Int) -> (Field -> Int) -> Hashable Field Int -> Field -> Int Field -> Int forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a $chashWithSalt :: Int -> Field -> Int hashWithSalt :: Int -> Field -> Int $chash :: Field -> Int hash :: Field -> Int Hashable) newtype Constructor = Constructor Text deriving stock (Constructor -> Constructor -> Bool (Constructor -> Constructor -> Bool) -> (Constructor -> Constructor -> Bool) -> Eq Constructor forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: Constructor -> Constructor -> Bool == :: Constructor -> Constructor -> Bool $c/= :: Constructor -> Constructor -> Bool /= :: Constructor -> Constructor -> Bool Eq, Eq Constructor Eq Constructor => (Constructor -> Constructor -> Ordering) -> (Constructor -> Constructor -> Bool) -> (Constructor -> Constructor -> Bool) -> (Constructor -> Constructor -> Bool) -> (Constructor -> Constructor -> Bool) -> (Constructor -> Constructor -> Constructor) -> (Constructor -> Constructor -> Constructor) -> Ord Constructor Constructor -> Constructor -> Bool Constructor -> Constructor -> Ordering Constructor -> Constructor -> Constructor forall a. Eq a => (a -> a -> Ordering) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> a) -> (a -> a -> a) -> Ord a $ccompare :: Constructor -> Constructor -> Ordering compare :: Constructor -> Constructor -> Ordering $c< :: Constructor -> Constructor -> Bool < :: Constructor -> Constructor -> Bool $c<= :: Constructor -> Constructor -> Bool <= :: Constructor -> Constructor -> Bool $c> :: Constructor -> Constructor -> Bool > :: Constructor -> Constructor -> Bool $c>= :: Constructor -> Constructor -> Bool >= :: Constructor -> Constructor -> Bool $cmax :: Constructor -> Constructor -> Constructor max :: Constructor -> Constructor -> Constructor $cmin :: Constructor -> Constructor -> Constructor min :: Constructor -> Constructor -> Constructor Ord, Int -> Constructor -> ShowS [Constructor] -> ShowS Constructor -> String (Int -> Constructor -> ShowS) -> (Constructor -> String) -> ([Constructor] -> ShowS) -> Show Constructor forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a $cshowsPrec :: Int -> Constructor -> ShowS showsPrec :: Int -> Constructor -> ShowS $cshow :: Constructor -> String show :: Constructor -> String $cshowList :: [Constructor] -> ShowS showList :: [Constructor] -> ShowS Show, (forall x. Constructor -> Rep Constructor x) -> (forall x. Rep Constructor x -> Constructor) -> Generic Constructor forall x. Rep Constructor x -> Constructor forall x. Constructor -> Rep Constructor x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cfrom :: forall x. Constructor -> Rep Constructor x from :: forall x. Constructor -> Rep Constructor x $cto :: forall x. Rep Constructor x -> Constructor to :: forall x. Rep Constructor x -> Constructor Generic) deriving newtype (String -> Constructor (String -> Constructor) -> IsString Constructor forall a. (String -> a) -> IsString a $cfromString :: String -> Constructor fromString :: String -> Constructor IsString) deriving anyclass (Eq Constructor Eq Constructor => (Int -> Constructor -> Int) -> (Constructor -> Int) -> Hashable Constructor Int -> Constructor -> Int Constructor -> Int forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a $chashWithSalt :: Int -> Constructor -> Int hashWithSalt :: Int -> Constructor -> Int $chash :: Constructor -> Int hash :: Constructor -> Int Hashable) isConstructor :: Qualified -> Bool isConstructor :: Qualified -> Bool isConstructor Qualified name = case Qualified name of Qualified "List.::" -> Bool True Qualified "Basics.," -> Bool True Qualified "Basics.()" -> Bool True Qualified Module _ (Text -> Maybe (Char, Text) Text.uncons -> Just (Char firstChar, Text _)) -> Char -> Bool Char.isUpper Char firstChar Qualified _ -> Bool False instance IsString Qualified where fromString :: String -> Qualified fromString String s = case Module -> Maybe (Module, Text) forall a. [a] -> Maybe ([a], a) unsnoc (Module -> Maybe (Module, Text)) -> Module -> Maybe (Module, Text) forall a b. (a -> b) -> a -> b $ HasCallStack => Text -> Text -> Module Text -> Text -> Module Text.splitOn Text "." (Text -> Module) -> Text -> Module forall a b. (a -> b) -> a -> b $ String -> Text forall a. IsString a => String -> a fromString String s of Maybe (Module, Text) Nothing -> String -> Qualified forall a. HasCallStack => String -> a error String "Empty name" Just ([], Text x) -> String -> Qualified forall a. HasCallStack => String -> a error (String -> Qualified) -> String -> Qualified forall a b. (a -> b) -> a -> b $ String "Unqualified name " String -> ShowS forall a. Semigroup a => a -> a -> a <> Text -> String forall a. Show a => a -> String show Text x Just (Module xs, Text x) -> Module -> Text -> Qualified Qualified Module xs Text x where unsnoc :: [a] -> Maybe ([a], a) unsnoc :: forall a. [a] -> Maybe ([a], a) unsnoc [] = Maybe ([a], a) forall a. Maybe a Nothing unsnoc (a a:[a] as) = ([a], a) -> Maybe ([a], a) forall a. a -> Maybe a Just (([a], a) -> Maybe ([a], a)) -> ([a], a) -> Maybe ([a], a) forall a b. (a -> b) -> a -> b $ a -> [a] -> ([a], a) forall a. a -> [a] -> ([a], a) go a a [a] as go :: a -> [a] -> ([a], a) go :: forall a. a -> [a] -> ([a], a) go a a [] = ([], a a) go a a (a a':[a] as) = ([a] -> [a]) -> ([a], a) -> ([a], a) forall a b c. (a -> b) -> (a, c) -> (b, c) forall (p :: * -> * -> *) a b c. Bifunctor p => (a -> b) -> p a c -> p b c first (a aa -> [a] -> [a] forall a. a -> [a] -> [a] :) (([a], a) -> ([a], a)) -> ([a], a) -> ([a], a) forall a b. (a -> b) -> a -> b $ a -> [a] -> ([a], a) forall a. a -> [a] -> ([a], a) go a a' [a] as