-- | This module exposes functions obtaining both explicitly versioned
-- and implicitly versioned analyses of source code.
module Language.Fortran.Extras.Analysis
  ( versionedExpandedProgramAnalysis
  , versionedProgramAnalysis
  , versionedProgramAnalysisWithMods
  , programAnalysis
  , programAnalysisWithMods
  )
where

import qualified Data.ByteString.Char8         as B
import           Language.Fortran.AST           ( A0
                                                , ProgramFile
                                                )
import           Language.Fortran.Analysis      ( Analysis
                                                , initAnalysis
                                                )
import           Language.Fortran.Analysis.Types
                                                ( analyseTypes
                                                , analyseTypesWithEnv
                                                )
import           Language.Fortran.Version       ( FortranVersion(..) )
import           Language.Fortran.Util.ModFile  ( combinedTypeEnv
                                                , ModFiles
                                                )

import           Language.Fortran.Extras.ProgramFile
                                                ( programFile
                                                , versionedProgramFile
                                                , versionedExpandedProgramFile
                                                )

-- | Obtain the analysis of the 'ProgramFile'.
programAnalysis' :: ProgramFile A0 -> ProgramFile (Analysis A0)
programAnalysis' :: ProgramFile A0 -> ProgramFile (Analysis A0)
programAnalysis' = (ProgramFile (Analysis A0), TypeEnv) -> ProgramFile (Analysis A0)
forall a b. (a, b) -> a
fst ((ProgramFile (Analysis A0), TypeEnv) -> ProgramFile (Analysis A0))
-> (ProgramFile A0 -> (ProgramFile (Analysis A0), TypeEnv))
-> ProgramFile A0
-> ProgramFile (Analysis A0)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile (Analysis A0) -> (ProgramFile (Analysis A0), TypeEnv)
forall a.
Data a =>
ProgramFile (Analysis a) -> (ProgramFile (Analysis a), TypeEnv)
analyseTypes (ProgramFile (Analysis A0) -> (ProgramFile (Analysis A0), TypeEnv))
-> (ProgramFile A0 -> ProgramFile (Analysis A0))
-> ProgramFile A0
-> (ProgramFile (Analysis A0), TypeEnv)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile A0 -> ProgramFile (Analysis A0)
forall (b :: * -> *) a. Functor b => b a -> b (Analysis a)
initAnalysis

-- | Obtain the analysis of the 'ProgramFile' and modules.
programAnalysisWithMods'
  :: ModFiles -> ProgramFile A0 -> ProgramFile (Analysis A0)
programAnalysisWithMods' :: ModFiles -> ProgramFile A0 -> ProgramFile (Analysis A0)
programAnalysisWithMods' ModFiles
mods =
  let tenv :: TypeEnv
tenv = ModFiles -> TypeEnv
combinedTypeEnv ModFiles
mods
  in  (ProgramFile (Analysis A0), TypeEnv) -> ProgramFile (Analysis A0)
forall a b. (a, b) -> a
fst ((ProgramFile (Analysis A0), TypeEnv) -> ProgramFile (Analysis A0))
-> (ProgramFile A0 -> (ProgramFile (Analysis A0), TypeEnv))
-> ProgramFile A0
-> ProgramFile (Analysis A0)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeEnv
-> ProgramFile (Analysis A0)
-> (ProgramFile (Analysis A0), TypeEnv)
forall a.
Data a =>
TypeEnv
-> ProgramFile (Analysis a) -> (ProgramFile (Analysis a), TypeEnv)
analyseTypesWithEnv TypeEnv
tenv (ProgramFile (Analysis A0) -> (ProgramFile (Analysis A0), TypeEnv))
-> (ProgramFile A0 -> ProgramFile (Analysis A0))
-> ProgramFile A0
-> (ProgramFile (Analysis A0), TypeEnv)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile A0 -> ProgramFile (Analysis A0)
forall (b :: * -> *) a. Functor b => b a -> b (Analysis a)
initAnalysis

-- | Obtain the analysis of source code with imports expanded using
-- a specific version of the parser.
versionedExpandedProgramAnalysis
  :: FortranVersion
  -> [String]
  -> String
  -> B.ByteString
  -> IO (ProgramFile (Analysis A0))
versionedExpandedProgramAnalysis :: FortranVersion
-> [String]
-> String
-> ByteString
-> IO (ProgramFile (Analysis A0))
versionedExpandedProgramAnalysis FortranVersion
version [String]
importDirs String
path ByteString
contents = do
  ProgramFile A0
pf <- FortranVersion
-> [String] -> String -> ByteString -> IO (ProgramFile A0)
versionedExpandedProgramFile FortranVersion
version [String]
importDirs String
path ByteString
contents
  ProgramFile (Analysis A0) -> IO (ProgramFile (Analysis A0))
forall (m :: * -> *) a. Monad m => a -> m a
return (ProgramFile (Analysis A0) -> IO (ProgramFile (Analysis A0)))
-> ProgramFile (Analysis A0) -> IO (ProgramFile (Analysis A0))
forall a b. (a -> b) -> a -> b
$ ProgramFile A0 -> ProgramFile (Analysis A0)
programAnalysis' ProgramFile A0
pf

-- | Obtain the analysis of source code using an explicit version of
-- the parser.
versionedProgramAnalysis
  :: FortranVersion -> String -> B.ByteString -> ProgramFile (Analysis A0)
versionedProgramAnalysis :: FortranVersion -> String -> ByteString -> ProgramFile (Analysis A0)
versionedProgramAnalysis FortranVersion
version String
path ByteString
contents =
  ProgramFile A0 -> ProgramFile (Analysis A0)
programAnalysis' (ProgramFile A0 -> ProgramFile (Analysis A0))
-> ProgramFile A0 -> ProgramFile (Analysis A0)
forall a b. (a -> b) -> a -> b
$ FortranVersion -> String -> ByteString -> ProgramFile A0
versionedProgramFile FortranVersion
version String
path ByteString
contents

-- | Obtain the analysis of source code and module files using an
-- explicit version of the parser.
versionedProgramAnalysisWithMods
  :: FortranVersion
  -> ModFiles
  -> String
  -> B.ByteString
  -> ProgramFile (Analysis A0)
versionedProgramAnalysisWithMods :: FortranVersion
-> ModFiles -> String -> ByteString -> ProgramFile (Analysis A0)
versionedProgramAnalysisWithMods FortranVersion
version ModFiles
mods String
path ByteString
contents =
  ModFiles -> ProgramFile A0 -> ProgramFile (Analysis A0)
programAnalysisWithMods' ModFiles
mods (ProgramFile A0 -> ProgramFile (Analysis A0))
-> ProgramFile A0 -> ProgramFile (Analysis A0)
forall a b. (a -> b) -> a -> b
$ FortranVersion -> String -> ByteString -> ProgramFile A0
versionedProgramFile FortranVersion
version String
path ByteString
contents

-- | Obtain the analysis of source code using an implicit version of
-- the parser.
programAnalysis :: String -> B.ByteString -> ProgramFile (Analysis A0)
programAnalysis :: String -> ByteString -> ProgramFile (Analysis A0)
programAnalysis String
path ByteString
contents = ProgramFile A0 -> ProgramFile (Analysis A0)
programAnalysis' (ProgramFile A0 -> ProgramFile (Analysis A0))
-> ProgramFile A0 -> ProgramFile (Analysis A0)
forall a b. (a -> b) -> a -> b
$ String -> ByteString -> ProgramFile A0
programFile String
path ByteString
contents

-- | Obtain the analysis of source code and module files using an
-- implicit version of the parser.
programAnalysisWithMods
  :: ModFiles -> String -> B.ByteString -> ProgramFile (Analysis A0)
programAnalysisWithMods :: ModFiles -> String -> ByteString -> ProgramFile (Analysis A0)
programAnalysisWithMods ModFiles
mods String
path ByteString
contents =
  ModFiles -> ProgramFile A0 -> ProgramFile (Analysis A0)
programAnalysisWithMods' ModFiles
mods (ProgramFile A0 -> ProgramFile (Analysis A0))
-> ProgramFile A0 -> ProgramFile (Analysis A0)
forall a b. (a -> b) -> a -> b
$ String -> ByteString -> ProgramFile A0
programFile String
path ByteString
contents