-- | 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' = forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a.
Data a =>
ProgramFile (Analysis a) -> (ProgramFile (Analysis a), TypeEnv)
analyseTypes forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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  forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a.
Data a =>
TypeEnv
-> ProgramFile (Analysis a) -> (ProgramFile (Analysis a), TypeEnv)
analyseTypesWithEnv TypeEnv
tenv forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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
  forall (m :: * -> *) a. Monad m => a -> m a
return 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' 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 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' 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 forall a b. (a -> b) -> a -> b
$ String -> ByteString -> ProgramFile A0
programFile String
path ByteString
contents