module Language.Fortran.Util.ModFile
(
ModFile, ModFiles, emptyModFile, emptyModFiles, modFileSuffix
, lookupModFileData, getLabelsModFileData, alterModFileData, alterModFileDataF
, genModFile, regenModFile
, encodeModFile, decodeModFile, decodeModFiles, decodeModFiles'
, moduleFilename
, StringMap, extractStringMap, combinedStringMap
, DeclContext(..), DeclMap, extractDeclMap, combinedDeclMap
, extractModuleMap, combinedModuleMap, combinedTypeEnv
, ParamVarMap, extractParamVarMap, combinedParamVarMap
, genUniqNameToFilenameMap
, TimestampStatus(..), checkTimestamps
) where
import qualified Language.Fortran.AST as F
import qualified Language.Fortran.Analysis as FA
import qualified Language.Fortran.Analysis.BBlocks as FAB
import qualified Language.Fortran.Analysis.DataFlow as FAD
import qualified Language.Fortran.Analysis.Renaming as FAR
import qualified Language.Fortran.Analysis.Types as FAT
import qualified Language.Fortran.Util.Position as P
import Language.Fortran.Util.Files ( getDirContents )
import Control.Monad.State
import Data.Binary (Binary, encode, decodeOrFail)
import qualified Data.ByteString.Lazy.Char8 as LB
import Data.Data
import Data.Generics.Uniplate.Operations
import qualified Data.Map.Strict as M
import Data.Maybe
import GHC.Generics (Generic)
import System.Directory ( doesFileExist, getModificationTime )
import qualified System.FilePath
import System.FilePath ( (-<.>), (</>) )
import System.IO ( hPutStrLn, stderr )
modFileSuffix :: String
modFileSuffix :: String
modFileSuffix = String
".fsmod"
isModFile :: FilePath -> Bool
isModFile :: String -> Bool
isModFile = String -> String -> Bool
System.FilePath.isExtensionOf String
modFileSuffix
data DeclContext = DCMain | DCBlockData | DCModule F.ProgramUnitName
| DCFunction (F.ProgramUnitName, F.ProgramUnitName)
| DCSubroutine (F.ProgramUnitName, F.ProgramUnitName)
deriving (Eq DeclContext
DeclContext -> DeclContext -> Bool
DeclContext -> DeclContext -> Ordering
DeclContext -> DeclContext -> DeclContext
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
min :: DeclContext -> DeclContext -> DeclContext
$cmin :: DeclContext -> DeclContext -> DeclContext
max :: DeclContext -> DeclContext -> DeclContext
$cmax :: DeclContext -> DeclContext -> DeclContext
>= :: DeclContext -> DeclContext -> Bool
$c>= :: DeclContext -> DeclContext -> Bool
> :: DeclContext -> DeclContext -> Bool
$c> :: DeclContext -> DeclContext -> Bool
<= :: DeclContext -> DeclContext -> Bool
$c<= :: DeclContext -> DeclContext -> Bool
< :: DeclContext -> DeclContext -> Bool
$c< :: DeclContext -> DeclContext -> Bool
compare :: DeclContext -> DeclContext -> Ordering
$ccompare :: DeclContext -> DeclContext -> Ordering
Ord, DeclContext -> DeclContext -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DeclContext -> DeclContext -> Bool
$c/= :: DeclContext -> DeclContext -> Bool
== :: DeclContext -> DeclContext -> Bool
$c== :: DeclContext -> DeclContext -> Bool
Eq, Int -> DeclContext -> ShowS
[DeclContext] -> ShowS
DeclContext -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DeclContext] -> ShowS
$cshowList :: [DeclContext] -> ShowS
show :: DeclContext -> String
$cshow :: DeclContext -> String
showsPrec :: Int -> DeclContext -> ShowS
$cshowsPrec :: Int -> DeclContext -> ShowS
Show, Typeable DeclContext
DeclContext -> DataType
DeclContext -> Constr
(forall b. Data b => b -> b) -> DeclContext -> DeclContext
forall a.
Typeable a
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> DeclContext -> u
forall u. (forall d. Data d => d -> u) -> DeclContext -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DeclContext -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DeclContext -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DeclContext -> m DeclContext
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DeclContext -> m DeclContext
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DeclContext
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DeclContext -> c DeclContext
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DeclContext)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c DeclContext)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DeclContext -> m DeclContext
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DeclContext -> m DeclContext
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DeclContext -> m DeclContext
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DeclContext -> m DeclContext
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DeclContext -> m DeclContext
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DeclContext -> m DeclContext
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DeclContext -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DeclContext -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> DeclContext -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> DeclContext -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DeclContext -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DeclContext -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DeclContext -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DeclContext -> r
gmapT :: (forall b. Data b => b -> b) -> DeclContext -> DeclContext
$cgmapT :: (forall b. Data b => b -> b) -> DeclContext -> DeclContext
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c DeclContext)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c DeclContext)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DeclContext)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DeclContext)
dataTypeOf :: DeclContext -> DataType
$cdataTypeOf :: DeclContext -> DataType
toConstr :: DeclContext -> Constr
$ctoConstr :: DeclContext -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DeclContext
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DeclContext
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DeclContext -> c DeclContext
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DeclContext -> c DeclContext
Data, Typeable, forall x. Rep DeclContext x -> DeclContext
forall x. DeclContext -> Rep DeclContext x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DeclContext x -> DeclContext
$cfrom :: forall x. DeclContext -> Rep DeclContext x
Generic)
instance Binary DeclContext
type DeclMap = M.Map F.Name (DeclContext, P.SrcSpan)
type StringMap = M.Map String String
type ParamVarMap = FAD.ParameterVarMap
data ModFile = ModFile { ModFile -> String
mfFilename :: String
, ModFile -> StringMap
mfStringMap :: StringMap
, ModFile -> ModuleMap
mfModuleMap :: FAR.ModuleMap
, ModFile -> DeclMap
mfDeclMap :: DeclMap
, ModFile -> TypeEnv
mfTypeEnv :: FAT.TypeEnv
, ModFile -> ParamVarMap
mfParamVarMap :: ParamVarMap
, ModFile -> Map String ByteString
mfOtherData :: M.Map String LB.ByteString }
deriving (ModFile -> ModFile -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ModFile -> ModFile -> Bool
$c/= :: ModFile -> ModFile -> Bool
== :: ModFile -> ModFile -> Bool
$c== :: ModFile -> ModFile -> Bool
Eq, Int -> ModFile -> ShowS
[ModFile] -> ShowS
ModFile -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ModFile] -> ShowS
$cshowList :: [ModFile] -> ShowS
show :: ModFile -> String
$cshow :: ModFile -> String
showsPrec :: Int -> ModFile -> ShowS
$cshowsPrec :: Int -> ModFile -> ShowS
Show, Typeable ModFile
ModFile -> DataType
ModFile -> Constr
(forall b. Data b => b -> b) -> ModFile -> ModFile
forall a.
Typeable a
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ModFile -> u
forall u. (forall d. Data d => d -> u) -> ModFile -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ModFile -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ModFile -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ModFile -> m ModFile
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ModFile -> m ModFile
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ModFile
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ModFile -> c ModFile
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ModFile)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ModFile)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ModFile -> m ModFile
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ModFile -> m ModFile
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ModFile -> m ModFile
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ModFile -> m ModFile
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ModFile -> m ModFile
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ModFile -> m ModFile
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ModFile -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ModFile -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> ModFile -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ModFile -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ModFile -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ModFile -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ModFile -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ModFile -> r
gmapT :: (forall b. Data b => b -> b) -> ModFile -> ModFile
$cgmapT :: (forall b. Data b => b -> b) -> ModFile -> ModFile
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ModFile)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ModFile)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ModFile)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ModFile)
dataTypeOf :: ModFile -> DataType
$cdataTypeOf :: ModFile -> DataType
toConstr :: ModFile -> Constr
$ctoConstr :: ModFile -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ModFile
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ModFile
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ModFile -> c ModFile
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ModFile -> c ModFile
Data, Typeable, forall x. Rep ModFile x -> ModFile
forall x. ModFile -> Rep ModFile x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ModFile x -> ModFile
$cfrom :: forall x. ModFile -> Rep ModFile x
Generic)
instance Binary ModFile
type ModFiles = [ModFile]
emptyModFiles :: ModFiles
emptyModFiles :: [ModFile]
emptyModFiles = []
emptyModFile :: ModFile
emptyModFile :: ModFile
emptyModFile = String
-> StringMap
-> ModuleMap
-> DeclMap
-> TypeEnv
-> ParamVarMap
-> Map String ByteString
-> ModFile
ModFile String
"" forall k a. Map k a
M.empty forall k a. Map k a
M.empty forall k a. Map k a
M.empty forall k a. Map k a
M.empty forall k a. Map k a
M.empty forall k a. Map k a
M.empty
regenModFile :: forall a. Data a => F.ProgramFile (FA.Analysis a) -> ModFile -> ModFile
regenModFile :: forall a. Data a => ProgramFile (Analysis a) -> ModFile -> ModFile
regenModFile ProgramFile (Analysis a)
pf ModFile
mf = ModFile
mf { mfModuleMap :: ModuleMap
mfModuleMap = forall a. Data a => ProgramFile (Analysis a) -> ModuleMap
extractModuleMap ProgramFile (Analysis a)
pf
, mfDeclMap :: DeclMap
mfDeclMap = forall a. Data a => ProgramFile (Analysis a) -> DeclMap
extractDeclMap ProgramFile (Analysis a)
pf
, mfTypeEnv :: TypeEnv
mfTypeEnv = forall a. Data a => ProgramFile (Analysis a) -> TypeEnv
FAT.extractTypeEnv ProgramFile (Analysis a)
pf
, mfParamVarMap :: ParamVarMap
mfParamVarMap = forall a. Data a => ProgramFile (Analysis a) -> ParamVarMap
extractParamVarMap ProgramFile (Analysis a)
pf
, mfFilename :: String
mfFilename = forall a. ProgramFile a -> String
F.pfGetFilename ProgramFile (Analysis a)
pf }
genModFile :: forall a. Data a => F.ProgramFile (FA.Analysis a) -> ModFile
genModFile :: forall a. Data a => ProgramFile (Analysis a) -> ModFile
genModFile = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Data a => ProgramFile (Analysis a) -> ModFile -> ModFile
regenModFile ModFile
emptyModFile
lookupModFileData :: String -> ModFile -> Maybe LB.ByteString
lookupModFileData :: String -> ModFile -> Maybe ByteString
lookupModFileData String
k = forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup String
k forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModFile -> Map String ByteString
mfOtherData
getLabelsModFileData :: ModFile -> [String]
getLabelsModFileData :: ModFile -> [String]
getLabelsModFileData = forall k a. Map k a -> [k]
M.keys forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModFile -> Map String ByteString
mfOtherData
alterModFileData :: (Maybe LB.ByteString -> Maybe LB.ByteString) -> String -> ModFile -> ModFile
alterModFileData :: (Maybe ByteString -> Maybe ByteString)
-> String -> ModFile -> ModFile
alterModFileData Maybe ByteString -> Maybe ByteString
f String
k ModFile
mf = ModFile
mf { mfOtherData :: Map String ByteString
mfOtherData = forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
M.alter Maybe ByteString -> Maybe ByteString
f String
k forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModFile -> Map String ByteString
mfOtherData forall a b. (a -> b) -> a -> b
$ ModFile
mf }
alterModFileDataF
:: Functor f
=> (Maybe LB.ByteString -> f (Maybe LB.ByteString)) -> String -> ModFile
-> f ModFile
alterModFileDataF :: forall (f :: * -> *).
Functor f =>
(Maybe ByteString -> f (Maybe ByteString))
-> String -> ModFile -> f ModFile
alterModFileDataF Maybe ByteString -> f (Maybe ByteString)
f String
k ModFile
mf =
(\Map String ByteString
od -> ModFile
mf { mfOtherData :: Map String ByteString
mfOtherData = Map String ByteString
od }) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) k a.
(Functor f, Ord k) =>
(Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)
M.alterF Maybe ByteString -> f (Maybe ByteString)
f String
k (ModFile -> Map String ByteString
mfOtherData ModFile
mf)
encodeModFile :: [ModFile] -> LB.ByteString
encodeModFile :: [ModFile] -> ByteString
encodeModFile = forall a. Binary a => a -> ByteString
encode forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map ModFile -> ModFile
each
where
each :: ModFile -> ModFile
each ModFile
mf = ModFile
mf' { mfStringMap :: StringMap
mfStringMap = StringMap
sm }
where
(ModFile
mf', StringMap
sm) = forall a. Data a => a -> (a, StringMap)
extractStringMap (ModFile
mf { mfStringMap :: StringMap
mfStringMap = forall k a. Map k a
M.empty })
decodeModFile :: LB.ByteString -> Either String [ModFile]
decodeModFile :: ByteString -> Either String [ModFile]
decodeModFile ByteString
bs = case forall a.
Binary a =>
ByteString
-> Either
(ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
decodeOrFail ByteString
bs of
Left (ByteString
_, ByteOffset
_, String
s) -> forall a b. a -> Either a b
Left String
s
Right (ByteString
_, ByteOffset
_, [ModFile]
mfs) -> forall a b. b -> Either a b
Right (forall a b. (a -> b) -> [a] -> [b]
map ModFile -> ModFile
each [ModFile]
mfs)
where
each :: ModFile -> ModFile
each ModFile
mf = (forall a. Data a => StringMap -> a -> a
revertStringMap StringMap
sm ModFile
mf { mfStringMap :: StringMap
mfStringMap = forall k a. Map k a
M.empty }) { mfStringMap :: StringMap
mfStringMap = StringMap
sm }
where sm :: StringMap
sm = ModFile -> StringMap
mfStringMap ModFile
mf
decodeModFiles :: [FilePath] -> IO [(FilePath, ModFile)]
decodeModFiles :: [String] -> IO [(String, ModFile)]
decodeModFiles = forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (\ [(String, ModFile)]
modFiles String
d -> do
[String]
modFileNames <- forall a. (a -> Bool) -> [a] -> [a]
filter String -> Bool
isModFile forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` String -> IO [String]
getDirContents String
d
[(String, ModFile)]
addedModFiles <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [String]
modFileNames forall a b. (a -> b) -> a -> b
$ \ String
modFileName -> do
ByteString
contents <- String -> IO ByteString
LB.readFile (String
d String -> ShowS
</> String
modFileName)
case ByteString -> Either String [ModFile]
decodeModFile ByteString
contents of
Left String
msg -> do
Handle -> String -> IO ()
hPutStrLn Handle
stderr forall a b. (a -> b) -> a -> b
$ String
modFileName forall a. [a] -> [a] -> [a]
++ String
": Error: " forall a. [a] -> [a] -> [a]
++ String
msg
forall (m :: * -> *) a. Monad m => a -> m a
return [(String
modFileName, ModFile
emptyModFile)]
Right [ModFile]
mods -> do
Handle -> String -> IO ()
hPutStrLn Handle
stderr forall a b. (a -> b) -> a -> b
$ String
modFileName forall a. [a] -> [a] -> [a]
++ String
": successfully parsed precompiled file."
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (String
modFileName,) [ModFile]
mods
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [(String, ModFile)]
addedModFiles forall a. [a] -> [a] -> [a]
++ [(String, ModFile)]
modFiles
) []
decodeModFiles' :: [FilePath] -> IO ModFiles
decodeModFiles' :: [String] -> IO [ModFile]
decodeModFiles' = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd) forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> IO [(String, ModFile)]
decodeModFiles
combinedModuleMap :: ModFiles -> FAR.ModuleMap
combinedModuleMap :: [ModFile] -> ModuleMap
combinedModuleMap = forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map ModFile -> ModuleMap
mfModuleMap
combinedTypeEnv :: ModFiles -> FAT.TypeEnv
combinedTypeEnv :: [ModFile] -> TypeEnv
combinedTypeEnv = forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map ModFile -> TypeEnv
mfTypeEnv
combinedDeclMap :: ModFiles -> DeclMap
combinedDeclMap :: [ModFile] -> DeclMap
combinedDeclMap = forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map ModFile -> DeclMap
mfDeclMap
combinedStringMap :: ModFiles -> StringMap
combinedStringMap :: [ModFile] -> StringMap
combinedStringMap = forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map ModFile -> StringMap
mfStringMap
combinedParamVarMap :: ModFiles -> ParamVarMap
combinedParamVarMap :: [ModFile] -> ParamVarMap
combinedParamVarMap = forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map ModFile -> ParamVarMap
mfParamVarMap
moduleFilename :: ModFile -> String
moduleFilename :: ModFile -> String
moduleFilename = ModFile -> String
mfFilename
genUniqNameToFilenameMap :: ModFiles -> M.Map F.Name String
genUniqNameToFilenameMap :: [ModFile] -> StringMap
genUniqNameToFilenameMap = forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map ModFile -> StringMap
perMF
where
perMF :: ModFile -> StringMap
perMF ModFile
mf = forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [ (String
n, String
fname) | Map String (String, NameType)
modEnv <- forall k a. Map k a -> [a]
M.elems (ModFile -> ModuleMap
mfModuleMap ModFile
mf)
, (String
n, NameType
_) <- forall k a. Map k a -> [a]
M.elems Map String (String, NameType)
modEnv ]
where
fname :: String
fname = ModFile -> String
mfFilename ModFile
mf
extractModuleMap :: forall a. Data a => F.ProgramFile (FA.Analysis a) -> FAR.ModuleMap
ProgramFile (Analysis a)
pf
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(ProgramUnitName, Map String (String, NameType))]
mmap = forall k a. k -> a -> Map k a
M.singleton ProgramUnitName
F.NamelessMain forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions [Map String (String, NameType)]
combinedEnv
| Bool
otherwise = forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(ProgramUnitName, Map String (String, NameType))]
mmap
where
mmap :: [(ProgramUnitName, Map String (String, NameType))]
mmap = [ (ProgramUnitName
n, Map String (String, NameType)
env) | pu :: ProgramUnit (Analysis a)
pu@F.PUModule{} <- forall from to. Biplate from to => from -> [to]
childrenBi ProgramFile (Analysis a)
pf :: [F.ProgramUnit (FA.Analysis a)]
, let a :: Analysis a
a = forall (f :: * -> *) a. Annotated f => f a -> a
F.getAnnotation ProgramUnit (Analysis a)
pu
, let n :: ProgramUnitName
n = forall a. Named a => a -> ProgramUnitName
F.getName ProgramUnit (Analysis a)
pu
, Map String (String, NameType)
env <- forall a. Maybe a -> [a]
maybeToList (forall a. Analysis a -> Maybe (Map String (String, NameType))
FA.moduleEnv Analysis a
a) ]
combinedEnv :: [Map String (String, NameType)]
combinedEnv = [ Map String (String, NameType)
env | ProgramUnit (Analysis a)
pu <- forall from to. Biplate from to => from -> [to]
childrenBi ProgramFile (Analysis a)
pf :: [F.ProgramUnit (FA.Analysis a)]
, let a :: Analysis a
a = forall (f :: * -> *) a. Annotated f => f a -> a
F.getAnnotation ProgramUnit (Analysis a)
pu
, Map String (String, NameType)
env <- forall a. Maybe a -> [a]
maybeToList (forall a. Analysis a -> Maybe (Map String (String, NameType))
FA.moduleEnv Analysis a
a) ]
extractDeclMap :: forall a. Data a => F.ProgramFile (FA.Analysis a) -> DeclMap
ProgramFile (Analysis a)
pf = forall k a. Ord k => [(k, a)] -> Map k a
M.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((DeclContext, Maybe (String, SrcSpan), [Block (Analysis a)])
-> [(String, (DeclContext, SrcSpan))]
blockDecls forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramUnit (Analysis a)
-> (DeclContext, Maybe (String, SrcSpan), [Block (Analysis a)])
nameAndBlocks) forall a b. (a -> b) -> a -> b
$ forall from to. Biplate from to => from -> [to]
universeBi ProgramFile (Analysis a)
pf
where
blockDecls :: (DeclContext, Maybe (F.Name, P.SrcSpan), [F.Block (FA.Analysis a)]) -> [(F.Name, (DeclContext, P.SrcSpan))]
blockDecls :: (DeclContext, Maybe (String, SrcSpan), [Block (Analysis a)])
-> [(String, (DeclContext, SrcSpan))]
blockDecls (DeclContext
dc, Maybe (String, SrcSpan)
mret, [Block (Analysis a)]
bs)
| Maybe (String, SrcSpan)
Nothing <- Maybe (String, SrcSpan)
mret = forall a b. (a -> b) -> [a] -> [b]
map Declarator (Analysis a) -> (String, (DeclContext, SrcSpan))
decls (forall from to. Biplate from to => from -> [to]
universeBi [Block (Analysis a)]
bs)
| Just (String
ret, SrcSpan
ss) <- Maybe (String, SrcSpan)
mret = (String
ret, (DeclContext
dc, SrcSpan
ss))forall a. a -> [a] -> [a]
:forall a b. (a -> b) -> [a] -> [b]
map Declarator (Analysis a) -> (String, (DeclContext, SrcSpan))
decls (forall from to. Biplate from to => from -> [to]
universeBi [Block (Analysis a)]
bs)
where
decls :: Declarator (Analysis a) -> (String, (DeclContext, SrcSpan))
decls Declarator (Analysis a)
d = let (String
v, SrcSpan
ss) = Declarator (Analysis a) -> (String, SrcSpan)
declVarName Declarator (Analysis a)
d in (String
v, (DeclContext
dc, SrcSpan
ss))
declVarName :: F.Declarator (FA.Analysis a) -> (F.Name, P.SrcSpan)
declVarName :: Declarator (Analysis a) -> (String, SrcSpan)
declVarName (F.Declarator Analysis a
_ SrcSpan
_ Expression (Analysis a)
e DeclaratorType (Analysis a)
_ Maybe (Expression (Analysis a))
_ Maybe (Expression (Analysis a))
_) = (forall a. Expression (Analysis a) -> String
FA.varName Expression (Analysis a)
e, forall a. Spanned a => a -> SrcSpan
P.getSpan Expression (Analysis a)
e)
nameAndBlocks :: F.ProgramUnit (FA.Analysis a) -> (DeclContext, Maybe (F.Name, P.SrcSpan), [F.Block (FA.Analysis a)])
nameAndBlocks :: ProgramUnit (Analysis a)
-> (DeclContext, Maybe (String, SrcSpan), [Block (Analysis a)])
nameAndBlocks ProgramUnit (Analysis a)
pu = case ProgramUnit (Analysis a)
pu of
F.PUMain Analysis a
_ SrcSpan
_ Maybe String
_ [Block (Analysis a)]
b Maybe [ProgramUnit (Analysis a)]
_ -> (DeclContext
DCMain, forall a. Maybe a
Nothing, [Block (Analysis a)]
b)
F.PUModule Analysis a
_ SrcSpan
_ String
_ [Block (Analysis a)]
b Maybe [ProgramUnit (Analysis a)]
_ -> (ProgramUnitName -> DeclContext
DCModule forall a b. (a -> b) -> a -> b
$ forall a. ProgramUnit (Analysis a) -> ProgramUnitName
FA.puName ProgramUnit (Analysis a)
pu, forall a. Maybe a
Nothing, [Block (Analysis a)]
b)
F.PUSubroutine Analysis a
_ SrcSpan
_ PrefixSuffix (Analysis a)
_ String
_ Maybe (AList Expression (Analysis a))
_ [Block (Analysis a)]
b Maybe [ProgramUnit (Analysis a)]
_ -> ((ProgramUnitName, ProgramUnitName) -> DeclContext
DCSubroutine (forall a. ProgramUnit (Analysis a) -> ProgramUnitName
FA.puName ProgramUnit (Analysis a)
pu, forall a. ProgramUnit (Analysis a) -> ProgramUnitName
FA.puSrcName ProgramUnit (Analysis a)
pu), forall a. Maybe a
Nothing, [Block (Analysis a)]
b)
F.PUFunction Analysis a
_ SrcSpan
_ Maybe (TypeSpec (Analysis a))
_ PrefixSuffix (Analysis a)
_ String
_ Maybe (AList Expression (Analysis a))
_ Maybe (Expression (Analysis a))
mret [Block (Analysis a)]
b Maybe [ProgramUnit (Analysis a)]
_
| Maybe (Expression (Analysis a))
Nothing <- Maybe (Expression (Analysis a))
mret
, F.Named String
n <- forall a. ProgramUnit (Analysis a) -> ProgramUnitName
FA.puName ProgramUnit (Analysis a)
pu -> ((ProgramUnitName, ProgramUnitName) -> DeclContext
DCFunction (forall a. ProgramUnit (Analysis a) -> ProgramUnitName
FA.puName ProgramUnit (Analysis a)
pu, forall a. ProgramUnit (Analysis a) -> ProgramUnitName
FA.puSrcName ProgramUnit (Analysis a)
pu), forall a. a -> Maybe a
Just (String
n, forall a. Spanned a => a -> SrcSpan
P.getSpan ProgramUnit (Analysis a)
pu), [Block (Analysis a)]
b)
| Just Expression (Analysis a)
ret <- Maybe (Expression (Analysis a))
mret -> ((ProgramUnitName, ProgramUnitName) -> DeclContext
DCFunction (forall a. ProgramUnit (Analysis a) -> ProgramUnitName
FA.puName ProgramUnit (Analysis a)
pu, forall a. ProgramUnit (Analysis a) -> ProgramUnitName
FA.puSrcName ProgramUnit (Analysis a)
pu), forall a. a -> Maybe a
Just (forall a. Expression (Analysis a) -> String
FA.varName Expression (Analysis a)
ret, forall a. Spanned a => a -> SrcSpan
P.getSpan Expression (Analysis a)
ret), [Block (Analysis a)]
b)
| Bool
otherwise -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"nameAndBlocks: un-named function with no return value! " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall a. ProgramUnit (Analysis a) -> ProgramUnitName
FA.puName ProgramUnit (Analysis a)
pu) forall a. [a] -> [a] -> [a]
++ String
" at source-span " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall a. Spanned a => a -> SrcSpan
P.getSpan ProgramUnit (Analysis a)
pu)
F.PUBlockData Analysis a
_ SrcSpan
_ Maybe String
_ [Block (Analysis a)]
b -> (DeclContext
DCBlockData, forall a. Maybe a
Nothing, [Block (Analysis a)]
b)
F.PUComment {} -> (DeclContext
DCBlockData, forall a. Maybe a
Nothing, [])
extractStringMap :: Data a => a -> (a, StringMap)
a
x = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall {a}. Map a String -> Map String a
inv forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall s a. State s a -> s -> (a, s)
runState (forall k a. Map k a
M.empty, Int
0) forall a b. (a -> b) -> a -> b
$ forall from to (m :: * -> *).
(Biplate from to, Applicative m) =>
(to -> m to) -> from -> m from
descendBiM String -> State (StringMap, Int) String
f a
x
where
inv :: Map a String -> Map String a
inv = forall k a. Ord k => [(k, a)] -> Map k a
M.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (\ (a
a,String
b) -> (String
b,a
a)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
M.toList
f :: String -> State (StringMap, Int) String
f :: String -> State (StringMap, Int) String
f String
s = do
(StringMap
m, Int
n) <- forall s (m :: * -> *). MonadState s m => m s
get
case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup String
s StringMap
m of
Just String
s' -> forall (m :: * -> *) a. Monad m => a -> m a
return String
s'
Maybe String
Nothing -> do
let s' :: String
s' = Char
'@'forall a. a -> [a] -> [a]
:forall a. Show a => a -> String
show Int
n
forall s (m :: * -> *). MonadState s m => s -> m ()
put (forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert String
s String
s' StringMap
m, Int
n forall a. Num a => a -> a -> a
+ Int
1)
forall (m :: * -> *) a. Monad m => a -> m a
return String
s'
revertStringMap :: Data a => StringMap -> a -> a
revertStringMap :: forall a. Data a => StringMap -> a -> a
revertStringMap StringMap
sm = forall from to. Biplate from to => (to -> to) -> from -> from
descendBi (\ String
s -> String
s forall a. a -> Maybe a -> a
`fromMaybe` forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup String
s StringMap
sm)
extractParamVarMap :: forall a. Data a => F.ProgramFile (FA.Analysis a) -> ParamVarMap
ProgramFile (Analysis a)
pf = forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(String, FValue)]
cvm
where
pf' :: ProgramFile (Analysis a)
pf' = forall a.
Data a =>
ProgramFile (Analysis a) -> ProgramFile (Analysis a)
FAD.analyseConstExps forall a b. (a -> b) -> a -> b
$ forall a.
Data a =>
ProgramFile (Analysis a) -> ProgramFile (Analysis a)
FAB.analyseBBlocks ProgramFile (Analysis a)
pf
cvm :: [(String, FValue)]
cvm = [ (forall a. Expression (Analysis a) -> String
FA.varName Expression (Analysis a)
v, FValue
con)
| F.PUModule Analysis a
_ SrcSpan
_ String
_ [Block (Analysis a)]
bs Maybe [ProgramUnit (Analysis a)]
_ <- forall from to. Biplate from to => from -> [to]
universeBi ProgramFile (Analysis a)
pf' :: [F.ProgramUnit (FA.Analysis a)]
, st :: Statement (Analysis a)
st@(F.StDeclaration Analysis a
_ SrcSpan
_ (F.TypeSpec Analysis a
_ SrcSpan
_ BaseType
_ Maybe (Selector (Analysis a))
_) Maybe (AList Attribute (Analysis a))
_ AList Declarator (Analysis a)
_) <- forall from to. Biplate from to => from -> [to]
universeBi [Block (Analysis a)]
bs :: [F.Statement (FA.Analysis a)]
, F.AttrParameter Analysis a
_ SrcSpan
_ <- forall from to. Biplate from to => from -> [to]
universeBi Statement (Analysis a)
st :: [F.Attribute (FA.Analysis a)]
, (F.Declarator Analysis a
_ SrcSpan
_ Expression (Analysis a)
v DeclaratorType (Analysis a)
F.ScalarDecl Maybe (Expression (Analysis a))
_ Maybe (Expression (Analysis a))
_) <- forall from to. Biplate from to => from -> [to]
universeBi Statement (Analysis a)
st :: [F.Declarator (FA.Analysis a)]
, Just FValue
con <- [forall a. Analysis a -> Maybe FValue
FA.constExp (forall (f :: * -> *) a. Annotated f => f a -> a
F.getAnnotation Expression (Analysis a)
v)] ] forall a. [a] -> [a] -> [a]
++
[ (forall a. Expression (Analysis a) -> String
FA.varName Expression (Analysis a)
v, FValue
con)
| F.PUModule Analysis a
_ SrcSpan
_ String
_ [Block (Analysis a)]
bs Maybe [ProgramUnit (Analysis a)]
_ <- forall from to. Biplate from to => from -> [to]
universeBi ProgramFile (Analysis a)
pf' :: [F.ProgramUnit (FA.Analysis a)]
, st :: Statement (Analysis a)
st@F.StParameter {} <- forall from to. Biplate from to => from -> [to]
universeBi [Block (Analysis a)]
bs :: [F.Statement (FA.Analysis a)]
, (F.Declarator Analysis a
_ SrcSpan
_ Expression (Analysis a)
v DeclaratorType (Analysis a)
F.ScalarDecl Maybe (Expression (Analysis a))
_ Maybe (Expression (Analysis a))
_) <- forall from to. Biplate from to => from -> [to]
universeBi Statement (Analysis a)
st :: [F.Declarator (FA.Analysis a)]
, Just FValue
con <- [forall a. Analysis a -> Maybe FValue
FA.constExp (forall (f :: * -> *) a. Annotated f => f a -> a
F.getAnnotation Expression (Analysis a)
v)] ]
data TimestampStatus = NoSuchFile | CompileFile | ModFileExists FilePath
checkTimestamps :: FilePath -> IO TimestampStatus
checkTimestamps :: String -> IO TimestampStatus
checkTimestamps String
path = do
Bool
pathExists <- String -> IO Bool
doesFileExist String
path
Bool
modExists <- String -> IO Bool
doesFileExist forall a b. (a -> b) -> a -> b
$ String
path String -> ShowS
-<.> String
modFileSuffix
case (Bool
pathExists, Bool
modExists) of
(Bool
False, Bool
_) -> forall (f :: * -> *) a. Applicative f => a -> f a
pure TimestampStatus
NoSuchFile
(Bool
True, Bool
False) -> forall (f :: * -> *) a. Applicative f => a -> f a
pure TimestampStatus
CompileFile
(Bool
True, Bool
True) -> do
let modPath :: String
modPath = String
path String -> ShowS
-<.> String
modFileSuffix
UTCTime
pathModTime <- String -> IO UTCTime
getModificationTime String
path
UTCTime
modModTime <- String -> IO UTCTime
getModificationTime String
modPath
if UTCTime
pathModTime forall a. Ord a => a -> a -> Bool
< UTCTime
modModTime
then forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ String -> TimestampStatus
ModFileExists String
modPath
else forall (f :: * -> *) a. Applicative f => a -> f a
pure TimestampStatus
CompileFile