{-# LANGUAGE DoAndIfThenElse #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Camfort.Functionality
(
AnnotationType(..)
, CamfortEnv(..)
, ast
, countVarDecls
, implicitNone
, allocCheck
, fpCheck
, useCheck
, arrayCheck
, stencilsCheck
, stencilsInfer
, stencilsSynth
, unitsCriticals
, unitsCheck
, unitsDump
, unitsInfer
, unitsCompile
, unitsSynth
, invariantsCheck
, common
, dead
, equivalences
, ddtRefactor
, ddtInfer
, ddtCheck
, ddtSynth
, ddtCompile
, camfortInitialize
) where
import Camfort.Analysis
import Camfort.Analysis.Logger
import Camfort.Analysis.ModFile (readParseSrcFile, MFCompiler, getModFiles, genModFiles
, readParseSrcDir, readParseSrcDirP, simpleCompiler)
import Camfort.Analysis.Simple
import Camfort.Helpers (FileOrDir, Filename)
import Camfort.Input
import qualified Camfort.Specification.DerivedDataType as DDT
import qualified Camfort.Specification.Hoare as Hoare
import qualified Camfort.Specification.Stencils as Stencils
import Camfort.Specification.Stencils.Analysis (compileStencils)
import qualified Camfort.Specification.Units as LU
import Camfort.Specification.Units.Analysis (compileUnits)
import Camfort.Specification.Units.Analysis.Consistent (checkUnits)
import Camfort.Specification.Units.Analysis.Criticals (inferCriticalVariables)
import Camfort.Specification.Units.Analysis.Infer (InferenceResult(..), InferenceReport(..), inferUnits)
import Camfort.Specification.Units.Annotation (unitInfo)
import Camfort.Specification.Units.ModFile (dumpModFileCompiledUnits)
import Camfort.Specification.Units.Monad (runUnitAnalysis, unitOpts0)
import Camfort.Specification.Units.MonadTypes (LiteralsOpt, UnitAnalysis, UnitEnv (..), UnitOpts (..))
import Camfort.Transformation.CommonBlockElim
import Camfort.Transformation.DeadCode
import Camfort.Transformation.EquivalenceElim
import Control.DeepSeq
import Control.Monad
import Control.Monad.IO.Class
import qualified Data.ByteString.Lazy as LB
import Data.Char (toLower)
import Data.List (intersperse)
import Data.Maybe (fromMaybe)
import qualified Language.Fortran.Analysis as FA
import qualified Language.Fortran.Analysis.ModGraph as FM
import qualified Language.Fortran.Analysis.Renaming as FA
import Language.Fortran.Version (FortranVersion(..))
import qualified Language.Fortran.Util.ModFile as FM
import Pipes
import qualified Pipes.Prelude as P
import Prelude hiding (mod)
import System.Directory
import System.Directory (doesDirectoryExist, createDirectoryIfMissing, getCurrentDirectory)
import System.FilePath (takeDirectory, (</>), takeExtension, replaceExtension)
import System.IO
import Text.PrettyPrint.GenericPretty (pp)
data AnnotationType = ATDefault | Doxygen | Ford
markerChar :: AnnotationType -> Char
markerChar :: AnnotationType -> Char
markerChar AnnotationType
Doxygen = Char
'<'
markerChar AnnotationType
Ford = Char
'!'
markerChar AnnotationType
ATDefault = Char
'='
data CamfortEnv =
CamfortEnv
{ CamfortEnv -> [Char]
ceInputSources :: FileOrDir
, CamfortEnv -> Maybe [Char]
ceIncludeDir :: Maybe FileOrDir
, CamfortEnv -> [[Char]]
ceExcludeFiles :: [Filename]
, CamfortEnv -> LogLevel
ceLogLevel :: LogLevel
, CamfortEnv -> Bool
ceSourceSnippets :: Bool
, CamfortEnv -> Maybe FortranVersion
ceFortranVersion :: Maybe FortranVersion
}
runWithOutput
:: (Describe e, Describe w)
=> String
-> AnalysisProgram e w IO a b
-> (FileOrDir -> FilePath -> AnalysisRunner e w IO a b r)
-> MFCompiler i IO
-> i
-> FilePath
-> CamfortEnv
-> IO r
runWithOutput :: forall e w a b r i.
(Describe e, Describe w) =>
[Char]
-> AnalysisProgram e w IO a b
-> ([Char] -> [Char] -> AnalysisRunner e w IO a b r)
-> MFCompiler i IO
-> i
-> [Char]
-> CamfortEnv
-> IO r
runWithOutput [Char]
description AnalysisProgram e w IO a b
program [Char] -> [Char] -> AnalysisRunner e w IO a b r
runner MFCompiler i IO
mfCompiler i
mfInput [Char]
outSrc CamfortEnv
env =
let runner' :: AnalysisRunner e w IO a b r
runner' = [Char] -> [Char] -> AnalysisRunner e w IO a b r
runner (CamfortEnv -> [Char]
ceInputSources CamfortEnv
env) [Char]
outSrc
in [Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunner e w IO a b r
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO r
forall e w a b r i.
(Describe e, Describe w) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunner e w IO a b r
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO r
runFunctionality [Char]
description AnalysisProgram e w IO a b
program AnalysisRunner e w IO a b r
runner' MFCompiler i IO
mfCompiler i
mfInput CamfortEnv
env
runFunctionality
:: (Describe e, Describe w)
=> String
-> AnalysisProgram e w IO a b
-> AnalysisRunner e w IO a b r
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO r
runFunctionality :: forall e w a b r i.
(Describe e, Describe w) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunner e w IO a b r
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO r
runFunctionality [Char]
description AnalysisProgram e w IO a b
program AnalysisRunner e w IO a b r
runner MFCompiler i IO
_ i
_ CamfortEnv
env = do
[Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
description [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" '" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ CamfortEnv -> [Char]
ceInputSources CamfortEnv
env [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"'"
[Char]
incDir' <- IO [Char] -> ([Char] -> IO [Char]) -> Maybe [Char] -> IO [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe IO [Char]
getCurrentDirectory [Char] -> IO [Char]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CamfortEnv -> Maybe [Char]
ceIncludeDir CamfortEnv
env)
Bool
isDir <- [Char] -> IO Bool
doesDirectoryExist [Char]
incDir'
let incDir :: [Char]
incDir | Bool
isDir = [Char]
incDir'
| Bool
otherwise = [Char] -> [Char]
takeDirectory [Char]
incDir'
ModFiles
modFiles <- [Char] -> IO ModFiles
getModFiles [Char]
incDir
[(ProgramFile A, SourceText)]
pfsTexts <- Maybe FortranVersion
-> ModFiles
-> [Char]
-> [[Char]]
-> IO [(ProgramFile A, SourceText)]
readParseSrcDir (CamfortEnv -> Maybe FortranVersion
ceFortranVersion CamfortEnv
env) ModFiles
modFiles (CamfortEnv -> [Char]
ceInputSources CamfortEnv
env) (CamfortEnv -> [[Char]]
ceExcludeFiles CamfortEnv
env)
AnalysisRunner e w IO a b r
runner AnalysisProgram e w IO a b
program (Bool -> LogOutput IO
forall (m :: * -> *). MonadIO m => Bool -> LogOutput m
logOutputStd Bool
True) (CamfortEnv -> LogLevel
ceLogLevel CamfortEnv
env) (CamfortEnv -> Bool
ceSourceSnippets CamfortEnv
env) ModFiles
modFiles [(ProgramFile A, SourceText)]
pfsTexts
runFunctionalityP
:: (Describe e, Describe w, ExitCodeOfReport b)
=> String
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP :: forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP [Char]
description AnalysisProgram e w IO a b
program AnalysisRunnerP e w IO a b (AnalysisReport e w b)
runner MFCompiler i IO
_ i
_ CamfortEnv
env = do
[Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
description [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" '" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ CamfortEnv -> [Char]
ceInputSources CamfortEnv
env [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"'"
[Char]
incDir' <- IO [Char] -> ([Char] -> IO [Char]) -> Maybe [Char] -> IO [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe IO [Char]
getCurrentDirectory [Char] -> IO [Char]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CamfortEnv -> Maybe [Char]
ceIncludeDir CamfortEnv
env)
Bool
isDir <- [Char] -> IO Bool
doesDirectoryExist [Char]
incDir'
let incDir :: [Char]
incDir | Bool
isDir = [Char]
incDir'
| Bool
otherwise = [Char] -> [Char]
takeDirectory [Char]
incDir'
ModFiles
modFiles <- [Char] -> IO ModFiles
getModFiles [Char]
incDir
[AnalysisReport e w b]
reports <- Producer (AnalysisReport e w b) IO () -> IO [AnalysisReport e w b]
forall (m :: * -> *) a. Monad m => Producer a m () -> m [a]
P.toListM (Producer (AnalysisReport e w b) IO ()
-> IO [AnalysisReport e w b])
-> Producer (AnalysisReport e w b) IO ()
-> IO [AnalysisReport e w b]
forall a b. (a -> b) -> a -> b
$
Maybe FortranVersion
-> ModFiles
-> [Char]
-> [[Char]]
-> Producer' (ProgramFile A, SourceText) IO ()
forall (m :: * -> *).
MonadIO m =>
Maybe FortranVersion
-> ModFiles
-> [Char]
-> [[Char]]
-> Producer' (ProgramFile A, SourceText) m ()
readParseSrcDirP (CamfortEnv -> Maybe FortranVersion
ceFortranVersion CamfortEnv
env) ModFiles
modFiles (CamfortEnv -> [Char]
ceInputSources CamfortEnv
env) (CamfortEnv -> [[Char]]
ceExcludeFiles CamfortEnv
env) Proxy Void () () (ProgramFile A, SourceText) IO ()
-> Proxy
() (ProgramFile A, SourceText) () (AnalysisReport e w b) IO ()
-> Producer (AnalysisReport e w b) IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>->
AnalysisRunnerP e w IO a b (AnalysisReport e w b)
runner AnalysisProgram e w IO a b
program (Bool -> LogOutput IO
forall (m :: * -> *). MonadIO m => Bool -> LogOutput m
logOutputStd Bool
True) (CamfortEnv -> LogLevel
ceLogLevel CamfortEnv
env) (CamfortEnv -> Bool
ceSourceSnippets CamfortEnv
env) ModFiles
modFiles
Int -> IO Int
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> IO Int)
-> ([AnalysisReport e w b] -> Int)
-> [AnalysisReport e w b]
-> IO Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [AnalysisReport e w b] -> Int
forall a. ExitCodeOfReport a => [a] -> Int
exitCodeOfSet ([AnalysisReport e w b] -> IO Int)
-> [AnalysisReport e w b] -> IO Int
forall a b. (a -> b) -> a -> b
$ [AnalysisReport e w b]
reports
ast :: CamfortEnv -> IO ()
ast :: CamfortEnv -> IO ()
ast CamfortEnv
env = do
[Char]
incDir' <- IO [Char] -> ([Char] -> IO [Char]) -> Maybe [Char] -> IO [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe IO [Char]
getCurrentDirectory [Char] -> IO [Char]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CamfortEnv -> Maybe [Char]
ceIncludeDir CamfortEnv
env)
ModFiles
modFiles <- [Char] -> IO ModFiles
getModFiles [Char]
incDir'
[(ProgramFile A, SourceText)]
xs <- Maybe FortranVersion
-> ModFiles
-> [Char]
-> [[Char]]
-> IO [(ProgramFile A, SourceText)]
readParseSrcDir (CamfortEnv -> Maybe FortranVersion
ceFortranVersion CamfortEnv
env) ModFiles
modFiles (CamfortEnv -> [Char]
ceInputSources CamfortEnv
env) (CamfortEnv -> [[Char]]
ceExcludeFiles CamfortEnv
env)
[ProgramFile A] -> IO ()
forall a. Show a => a -> IO ()
print ([ProgramFile A] -> IO ())
-> ([(ProgramFile A, SourceText)] -> [ProgramFile A])
-> [(ProgramFile A, SourceText)]
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((ProgramFile A, SourceText) -> ProgramFile A)
-> [(ProgramFile A, SourceText)] -> [ProgramFile A]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ProgramFile A, SourceText) -> ProgramFile A
forall a b. (a, b) -> a
fst ([(ProgramFile A, SourceText)] -> IO ())
-> [(ProgramFile A, SourceText)] -> IO ()
forall a b. (a -> b) -> a -> b
$ [(ProgramFile A, SourceText)]
xs
countVarDecls :: CamfortEnv -> IO Int
countVarDecls :: CamfortEnv -> IO Int
countVarDecls =
[Char]
-> AnalysisProgram () () IO (ProgramFile A) VarCountReport
-> AnalysisRunnerP
()
()
IO
(ProgramFile A)
VarCountReport
(AnalysisReport () () VarCountReport)
-> MFCompiler () IO
-> ()
-> CamfortEnv
-> IO Int
forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP
[Char]
"Counting variable declarations in"
(PureAnalysis () () VarCountReport
-> AnalysisT () () IO VarCountReport
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis () () VarCountReport
-> AnalysisT () () IO VarCountReport)
-> (ProgramFile A -> PureAnalysis () () VarCountReport)
-> AnalysisProgram () () IO (ProgramFile A) VarCountReport
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile A -> PureAnalysis () () VarCountReport
forall a.
Data a =>
ProgramFile a -> PureAnalysis () () VarCountReport
countVariableDeclarations)
(Text
-> AnalysisRunnerP
()
()
IO
(ProgramFile A)
VarCountReport
(AnalysisReport () () VarCountReport)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"count variable declarations")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
dead :: FileOrDir -> CamfortEnv -> IO Int
dead :: [Char] -> CamfortEnv -> IO Int
dead =
[Char]
-> AnalysisProgram
Void Void IO [ProgramFile A] ((), [Either Void (ProgramFile A)])
-> ([Char]
-> [Char]
-> AnalysisRunner
Void
Void
IO
[ProgramFile A]
((), [Either Void (ProgramFile A)])
Int)
-> MFCompiler () IO
-> ()
-> [Char]
-> CamfortEnv
-> IO Int
forall e w a b r i.
(Describe e, Describe w) =>
[Char]
-> AnalysisProgram e w IO a b
-> ([Char] -> [Char] -> AnalysisRunner e w IO a b r)
-> MFCompiler i IO
-> i
-> [Char]
-> CamfortEnv
-> IO r
runWithOutput
[Char]
"Eliminating dead code in"
((PureAnalysis Void Void ((), [Either Void (ProgramFile A)])
-> AnalysisT Void Void IO ((), [Either Void (ProgramFile A)]))
-> ([ProgramFile A]
-> PureAnalysis Void Void ((), [Either Void (ProgramFile A)]))
-> AnalysisProgram
Void Void IO [ProgramFile A] ((), [Either Void (ProgramFile A)])
forall a b.
(a -> b) -> ([ProgramFile A] -> a) -> [ProgramFile A] -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PureAnalysis Void Void ((), [Either Void (ProgramFile A)])
-> AnalysisT Void Void IO ((), [Either Void (ProgramFile A)])
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (([ProgramFile A]
-> PureAnalysis Void Void ((), [Either Void (ProgramFile A)]))
-> AnalysisProgram
Void Void IO [ProgramFile A] ((), [Either Void (ProgramFile A)]))
-> ((ProgramFile A -> DeadCodeAnalysis (ProgramFile A))
-> [ProgramFile A]
-> PureAnalysis Void Void ((), [Either Void (ProgramFile A)]))
-> (ProgramFile A -> DeadCodeAnalysis (ProgramFile A))
-> AnalysisProgram
Void Void IO [ProgramFile A] ((), [Either Void (ProgramFile A)])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ProgramFile A -> DeadCodeAnalysis (ProgramFile A))
-> [ProgramFile A]
-> PureAnalysis Void Void ((), [Either Void (ProgramFile A)])
forall (m :: * -> *) e w.
Monad m =>
AnalysisProgram e w m (ProgramFile A) (ProgramFile A)
-> AnalysisProgram
e w m [ProgramFile A] ((), [Either e (ProgramFile A)])
perFileRefactoring ((ProgramFile A -> DeadCodeAnalysis (ProgramFile A))
-> AnalysisProgram
Void Void IO [ProgramFile A] ((), [Either Void (ProgramFile A)]))
-> (ProgramFile A -> DeadCodeAnalysis (ProgramFile A))
-> AnalysisProgram
Void Void IO [ProgramFile A] ((), [Either Void (ProgramFile A)])
forall a b. (a -> b) -> a -> b
$ Bool -> ProgramFile A -> DeadCodeAnalysis (ProgramFile A)
deadCode Bool
False)
(Text
-> [Char]
-> [Char]
-> AnalysisRunner
Void
Void
IO
[ProgramFile A]
((), [Either Void (ProgramFile A)])
Int
forall e e' w r.
(Describe e, Describe e', Describe w, Describe r,
ExitCodeOfReport r) =>
Text
-> [Char]
-> [Char]
-> AnalysisRunner
e w IO [ProgramFile A] (r, [Either e' (ProgramFile A)]) Int
doRefactor Text
"dead code elimination")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
common :: FileOrDir -> CamfortEnv -> IO Int
common :: [Char] -> CamfortEnv -> IO Int
common [Char]
outSrc =
[Char]
-> AnalysisProgram
Void Void IO [ProgramFile A] ([ProgramFile A], [ProgramFile A])
-> ([Char]
-> [Char]
-> AnalysisRunner
Void
Void
IO
[ProgramFile A]
([ProgramFile A], [ProgramFile A])
Int)
-> MFCompiler () IO
-> ()
-> [Char]
-> CamfortEnv
-> IO Int
forall e w a b r i.
(Describe e, Describe w) =>
[Char]
-> AnalysisProgram e w IO a b
-> ([Char] -> [Char] -> AnalysisRunner e w IO a b r)
-> MFCompiler i IO
-> i
-> [Char]
-> CamfortEnv
-> IO r
runWithOutput
[Char]
"Refactoring common blocks in"
(PureAnalysis Void Void ([ProgramFile A], [ProgramFile A])
-> AnalysisT Void Void IO ([ProgramFile A], [ProgramFile A])
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis Void Void ([ProgramFile A], [ProgramFile A])
-> AnalysisT Void Void IO ([ProgramFile A], [ProgramFile A]))
-> ([ProgramFile A]
-> PureAnalysis Void Void ([ProgramFile A], [ProgramFile A]))
-> AnalysisProgram
Void Void IO [ProgramFile A] ([ProgramFile A], [ProgramFile A])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char]
-> [ProgramFile A]
-> PureAnalysis Void Void ([ProgramFile A], [ProgramFile A])
commonElimToModules ([Char] -> [Char]
takeDirectory [Char]
outSrc [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"/"))
(Text
-> [Char]
-> [Char]
-> AnalysisRunner
Void Void IO [ProgramFile A] ([ProgramFile A], [ProgramFile A]) Int
forall e w.
(Describe e, Describe w) =>
Text
-> [Char]
-> [Char]
-> AnalysisRunner
e w IO [ProgramFile A] ([ProgramFile A], [ProgramFile A]) Int
doRefactorAndCreate Text
"common block refactoring")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
[Char]
outSrc
equivalences :: FileOrDir -> CamfortEnv -> IO Int
equivalences :: [Char] -> CamfortEnv -> IO Int
equivalences =
[Char]
-> AnalysisProgram
Void Void IO [ProgramFile A] ((), [Either Void (ProgramFile A)])
-> ([Char]
-> [Char]
-> AnalysisRunner
Void
Void
IO
[ProgramFile A]
((), [Either Void (ProgramFile A)])
Int)
-> MFCompiler () IO
-> ()
-> [Char]
-> CamfortEnv
-> IO Int
forall e w a b r i.
(Describe e, Describe w) =>
[Char]
-> AnalysisProgram e w IO a b
-> ([Char] -> [Char] -> AnalysisRunner e w IO a b r)
-> MFCompiler i IO
-> i
-> [Char]
-> CamfortEnv
-> IO r
runWithOutput
[Char]
"Refactoring equivalences blocks in"
((PureAnalysis Void Void ((), [Either Void (ProgramFile A)])
-> AnalysisT Void Void IO ((), [Either Void (ProgramFile A)]))
-> ([ProgramFile A]
-> PureAnalysis Void Void ((), [Either Void (ProgramFile A)]))
-> AnalysisProgram
Void Void IO [ProgramFile A] ((), [Either Void (ProgramFile A)])
forall a b.
(a -> b) -> ([ProgramFile A] -> a) -> [ProgramFile A] -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PureAnalysis Void Void ((), [Either Void (ProgramFile A)])
-> AnalysisT Void Void IO ((), [Either Void (ProgramFile A)])
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (([ProgramFile A]
-> PureAnalysis Void Void ((), [Either Void (ProgramFile A)]))
-> AnalysisProgram
Void Void IO [ProgramFile A] ((), [Either Void (ProgramFile A)]))
-> ((ProgramFile A -> DeadCodeAnalysis (ProgramFile A))
-> [ProgramFile A]
-> PureAnalysis Void Void ((), [Either Void (ProgramFile A)]))
-> (ProgramFile A -> DeadCodeAnalysis (ProgramFile A))
-> AnalysisProgram
Void Void IO [ProgramFile A] ((), [Either Void (ProgramFile A)])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ProgramFile A -> DeadCodeAnalysis (ProgramFile A))
-> [ProgramFile A]
-> PureAnalysis Void Void ((), [Either Void (ProgramFile A)])
forall (m :: * -> *) e w.
Monad m =>
AnalysisProgram e w m (ProgramFile A) (ProgramFile A)
-> AnalysisProgram
e w m [ProgramFile A] ((), [Either e (ProgramFile A)])
perFileRefactoring ((ProgramFile A -> DeadCodeAnalysis (ProgramFile A))
-> AnalysisProgram
Void Void IO [ProgramFile A] ((), [Either Void (ProgramFile A)]))
-> (ProgramFile A -> DeadCodeAnalysis (ProgramFile A))
-> AnalysisProgram
Void Void IO [ProgramFile A] ((), [Either Void (ProgramFile A)])
forall a b. (a -> b) -> a -> b
$ ProgramFile A -> DeadCodeAnalysis (ProgramFile A)
refactorEquivalences)
(Text
-> [Char]
-> [Char]
-> AnalysisRunner
Void
Void
IO
[ProgramFile A]
((), [Either Void (ProgramFile A)])
Int
forall e e' w r.
(Describe e, Describe e', Describe w, Describe r,
ExitCodeOfReport r) =>
Text
-> [Char]
-> [Char]
-> AnalysisRunner
e w IO [ProgramFile A] (r, [Either e' (ProgramFile A)]) Int
doRefactor Text
"equivalence block refactoring")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
implicitNone :: Bool -> CamfortEnv -> IO Int
implicitNone :: Bool -> CamfortEnv -> IO Int
implicitNone Bool
allPU =
[Char]
-> AnalysisProgram [Char] () IO (ProgramFile A) ImplicitNoneReport
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
ImplicitNoneReport
(AnalysisReport [Char] () ImplicitNoneReport)
-> MFCompiler () IO
-> ()
-> CamfortEnv
-> IO Int
forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP
[Char]
"Checking 'implicit none' completeness"
(PureAnalysis [Char] () ImplicitNoneReport
-> AnalysisT [Char] () IO ImplicitNoneReport
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis [Char] () ImplicitNoneReport
-> AnalysisT [Char] () IO ImplicitNoneReport)
-> (ProgramFile A -> PureAnalysis [Char] () ImplicitNoneReport)
-> AnalysisProgram [Char] () IO (ProgramFile A) ImplicitNoneReport
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> ProgramFile A -> PureAnalysis [Char] () ImplicitNoneReport
forall a.
Data a =>
Bool -> ProgramFile a -> PureAnalysis [Char] () ImplicitNoneReport
checkImplicitNone Bool
allPU))
(Text
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
ImplicitNoneReport
(AnalysisReport [Char] () ImplicitNoneReport)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"check 'implicit none'")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
allocCheck :: CamfortEnv -> IO Int
allocCheck :: CamfortEnv -> IO Int
allocCheck =
[Char]
-> AnalysisProgram [Char] () IO (ProgramFile A) CheckAllocReport
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
CheckAllocReport
(AnalysisReport [Char] () CheckAllocReport)
-> MFCompiler () IO
-> ()
-> CamfortEnv
-> IO Int
forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP
[Char]
"Checking allocate / deallocate usage"
(PureAnalysis [Char] () CheckAllocReport
-> AnalysisT [Char] () IO CheckAllocReport
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis [Char] () CheckAllocReport
-> AnalysisT [Char] () IO CheckAllocReport)
-> (ProgramFile A -> PureAnalysis [Char] () CheckAllocReport)
-> AnalysisProgram [Char] () IO (ProgramFile A) CheckAllocReport
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile A -> PureAnalysis [Char] () CheckAllocReport
forall a.
Data a =>
ProgramFile a -> PureAnalysis [Char] () CheckAllocReport
checkAllocateStatements)
(Text
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
CheckAllocReport
(AnalysisReport [Char] () CheckAllocReport)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"check allocate / deallocate")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
fpCheck :: CamfortEnv -> IO Int
fpCheck :: CamfortEnv -> IO Int
fpCheck =
[Char]
-> AnalysisProgram [Char] () IO (ProgramFile A) CheckFPReport
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
CheckFPReport
(AnalysisReport [Char] () CheckFPReport)
-> MFCompiler () IO
-> ()
-> CamfortEnv
-> IO Int
forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP
[Char]
"Checking usage of floating point"
(PureAnalysis [Char] () CheckFPReport
-> AnalysisT [Char] () IO CheckFPReport
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis [Char] () CheckFPReport
-> AnalysisT [Char] () IO CheckFPReport)
-> (ProgramFile A -> PureAnalysis [Char] () CheckFPReport)
-> AnalysisProgram [Char] () IO (ProgramFile A) CheckFPReport
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile A -> PureAnalysis [Char] () CheckFPReport
forall a.
Data a =>
ProgramFile a -> PureAnalysis [Char] () CheckFPReport
checkFloatingPointUse)
(Text
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
CheckFPReport
(AnalysisReport [Char] () CheckFPReport)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"check floating point")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
useCheck :: CamfortEnv -> IO Int
useCheck :: CamfortEnv -> IO Int
useCheck =
[Char]
-> AnalysisProgram [Char] () IO (ProgramFile A) CheckUseReport
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
CheckUseReport
(AnalysisReport [Char] () CheckUseReport)
-> MFCompiler () IO
-> ()
-> CamfortEnv
-> IO Int
forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP
[Char]
"Checking usage of USE statements"
(PureAnalysis [Char] () CheckUseReport
-> AnalysisT [Char] () IO CheckUseReport
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis [Char] () CheckUseReport
-> AnalysisT [Char] () IO CheckUseReport)
-> (ProgramFile A -> PureAnalysis [Char] () CheckUseReport)
-> AnalysisProgram [Char] () IO (ProgramFile A) CheckUseReport
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile A -> PureAnalysis [Char] () CheckUseReport
forall a.
Data a =>
ProgramFile a -> PureAnalysis [Char] () CheckUseReport
checkModuleUse)
(Text
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
CheckUseReport
(AnalysisReport [Char] () CheckUseReport)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"check module USE")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
arrayCheck :: CamfortEnv -> IO Int
arrayCheck :: CamfortEnv -> IO Int
arrayCheck =
[Char]
-> AnalysisProgram [Char] () IO (ProgramFile A) CheckArrayReport
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
CheckArrayReport
(AnalysisReport [Char] () CheckArrayReport)
-> MFCompiler () IO
-> ()
-> CamfortEnv
-> IO Int
forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP
[Char]
"Checking array usage"
(PureAnalysis [Char] () CheckArrayReport
-> AnalysisT [Char] () IO CheckArrayReport
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis [Char] () CheckArrayReport
-> AnalysisT [Char] () IO CheckArrayReport)
-> (ProgramFile A -> PureAnalysis [Char] () CheckArrayReport)
-> AnalysisProgram [Char] () IO (ProgramFile A) CheckArrayReport
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile A -> PureAnalysis [Char] () CheckArrayReport
forall a.
Data a =>
ProgramFile a -> PureAnalysis [Char] () CheckArrayReport
checkArrayUse)
(Text
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
CheckArrayReport
(AnalysisReport [Char] () CheckArrayReport)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"check array usage")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
ddtRefactor :: FileOrDir -> CamfortEnv -> IO Int
ddtRefactor :: [Char] -> CamfortEnv -> IO Int
ddtRefactor =
[Char]
-> AnalysisProgram
[Char]
()
IO
[ProgramFile A]
(DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
-> ([Char]
-> [Char]
-> AnalysisRunner
[Char]
()
IO
[ProgramFile A]
(DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
Int)
-> MFCompiler () IO
-> ()
-> [Char]
-> CamfortEnv
-> IO Int
forall e w a b r i.
(Describe e, Describe w) =>
[Char]
-> AnalysisProgram e w IO a b
-> ([Char] -> [Char] -> AnalysisRunner e w IO a b r)
-> MFCompiler i IO
-> i
-> [Char]
-> CamfortEnv
-> IO r
runWithOutput
[Char]
"Refactoring derived datatypes"
(PureAnalysis
[Char] () (DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
-> AnalysisT
[Char]
()
IO
(DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis
[Char] () (DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
-> AnalysisT
[Char]
()
IO
(DerivedDataTypeReport, [Either [Char] (ProgramFile A)]))
-> ([ProgramFile A]
-> PureAnalysis
[Char] () (DerivedDataTypeReport, [Either [Char] (ProgramFile A)]))
-> AnalysisProgram
[Char]
()
IO
[ProgramFile A]
(DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ProgramFile A]
-> PureAnalysis
[Char] () (DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
DDT.refactor)
(Text
-> [Char]
-> [Char]
-> AnalysisRunner
[Char]
()
IO
[ProgramFile A]
(DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
Int
forall e e' w r.
(Describe e, Describe e', Describe w, Describe r,
ExitCodeOfReport r) =>
Text
-> [Char]
-> [Char]
-> AnalysisRunner
e w IO [ProgramFile A] (r, [Either e' (ProgramFile A)]) Int
doRefactor Text
"infer derived data types")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
ddtSynth :: AnnotationType -> FileOrDir -> CamfortEnv -> IO Int
ddtSynth :: AnnotationType -> [Char] -> CamfortEnv -> IO Int
ddtSynth AnnotationType
annType =
[Char]
-> AnalysisProgram
[Char]
()
IO
[ProgramFile A]
(DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
-> ([Char]
-> [Char]
-> AnalysisRunner
[Char]
()
IO
[ProgramFile A]
(DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
Int)
-> MFCompiler () IO
-> ()
-> [Char]
-> CamfortEnv
-> IO Int
forall e w a b r i.
(Describe e, Describe w) =>
[Char]
-> AnalysisProgram e w IO a b
-> ([Char] -> [Char] -> AnalysisRunner e w IO a b r)
-> MFCompiler i IO
-> i
-> [Char]
-> CamfortEnv
-> IO r
runWithOutput
[Char]
"Synthesising derived datatypes"
(PureAnalysis
[Char] () (DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
-> AnalysisT
[Char]
()
IO
(DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis
[Char] () (DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
-> AnalysisT
[Char]
()
IO
(DerivedDataTypeReport, [Either [Char] (ProgramFile A)]))
-> ([ProgramFile A]
-> PureAnalysis
[Char] () (DerivedDataTypeReport, [Either [Char] (ProgramFile A)]))
-> AnalysisProgram
[Char]
()
IO
[ProgramFile A]
(DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char
-> [ProgramFile A]
-> PureAnalysis
[Char] () (DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
DDT.synth (AnnotationType -> Char
markerChar AnnotationType
annType))
(Text
-> [Char]
-> [Char]
-> AnalysisRunner
[Char]
()
IO
[ProgramFile A]
(DerivedDataTypeReport, [Either [Char] (ProgramFile A)])
Int
forall e e' w r.
(Describe e, Describe e', Describe w, Describe r,
ExitCodeOfReport r) =>
Text
-> [Char]
-> [Char]
-> AnalysisRunner
e w IO [ProgramFile A] (r, [Either e' (ProgramFile A)]) Int
doRefactor Text
"synth derived data types")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
ddtCheck :: CamfortEnv -> IO Int
ddtCheck :: CamfortEnv -> IO Int
ddtCheck =
[Char]
-> AnalysisProgram
[Char] () IO (ProgramFile A) DerivedDataTypeReport
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
DerivedDataTypeReport
(AnalysisReport [Char] () DerivedDataTypeReport)
-> MFCompiler () IO
-> ()
-> CamfortEnv
-> IO Int
forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP
[Char]
"Checking derived datatype annotations"
(PureAnalysis [Char] () DerivedDataTypeReport
-> AnalysisT [Char] () IO DerivedDataTypeReport
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis [Char] () DerivedDataTypeReport
-> AnalysisT [Char] () IO DerivedDataTypeReport)
-> (ProgramFile A -> PureAnalysis [Char] () DerivedDataTypeReport)
-> AnalysisProgram
[Char] () IO (ProgramFile A) DerivedDataTypeReport
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile A -> PureAnalysis [Char] () DerivedDataTypeReport
DDT.check)
(Text
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
DerivedDataTypeReport
(AnalysisReport [Char] () DerivedDataTypeReport)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"check derived datatypes")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
ddtInfer :: CamfortEnv -> IO Int
ddtInfer :: CamfortEnv -> IO Int
ddtInfer =
[Char]
-> AnalysisProgram
[Char] () IO (ProgramFile A) DerivedDataTypeReport
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
DerivedDataTypeReport
(AnalysisReport [Char] () DerivedDataTypeReport)
-> MFCompiler () IO
-> ()
-> CamfortEnv
-> IO Int
forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP
[Char]
"Inferring derived datatypes"
(PureAnalysis [Char] () DerivedDataTypeReport
-> AnalysisT [Char] () IO DerivedDataTypeReport
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis [Char] () DerivedDataTypeReport
-> AnalysisT [Char] () IO DerivedDataTypeReport)
-> (ProgramFile A -> PureAnalysis [Char] () DerivedDataTypeReport)
-> AnalysisProgram
[Char] () IO (ProgramFile A) DerivedDataTypeReport
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile A -> PureAnalysis [Char] () DerivedDataTypeReport
DDT.infer)
(Text
-> AnalysisRunnerP
[Char]
()
IO
(ProgramFile A)
DerivedDataTypeReport
(AnalysisReport [Char] () DerivedDataTypeReport)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"infer derived datatypes")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
ddtCompile :: CamfortEnv -> IO Int
ddtCompile :: CamfortEnv -> IO Int
ddtCompile CamfortEnv
env = do
let description :: [Char]
description = [Char]
"Compiling derived datatypes for"
[Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
description [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" '" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ CamfortEnv -> [Char]
ceInputSources CamfortEnv
env [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"'"
[Char]
incDir' <- IO [Char] -> ([Char] -> IO [Char]) -> Maybe [Char] -> IO [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe IO [Char]
getCurrentDirectory [Char] -> IO [Char]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CamfortEnv -> Maybe [Char]
ceIncludeDir CamfortEnv
env)
Bool
isDir <- [Char] -> IO Bool
doesDirectoryExist [Char]
incDir'
let incDir :: [Char]
incDir | Bool
isDir = [Char]
incDir'
| Bool
otherwise = [Char] -> [Char]
takeDirectory [Char]
incDir'
ModFiles
modFileNames <- [Char] -> IO ModFiles
getModFiles [Char]
incDir
ModFiles
modFiles <- Maybe FortranVersion
-> ModFiles
-> MFCompiler () IO
-> ()
-> [Char]
-> [[Char]]
-> IO ModFiles
forall (m :: * -> *) r.
MonadIO m =>
Maybe FortranVersion
-> ModFiles
-> MFCompiler r m
-> r
-> [Char]
-> [[Char]]
-> m ModFiles
genModFiles (CamfortEnv -> Maybe FortranVersion
ceFortranVersion CamfortEnv
env) ModFiles
modFileNames MFCompiler () IO
DDT.compile () (CamfortEnv -> [Char]
ceInputSources CamfortEnv
env) (CamfortEnv -> [[Char]]
ceExcludeFiles CamfortEnv
env)
ModFiles -> (ModFile -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ModFiles
modFiles ((ModFile -> IO ()) -> IO ()) -> (ModFile -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ ModFile
modFile -> do
let mfname :: [Char]
mfname = [Char] -> [Char] -> [Char]
replaceExtension (ModFile -> [Char]
FM.moduleFilename ModFile
modFile) [Char]
FM.modFileSuffix
[Char] -> ByteString -> IO ()
LB.writeFile [Char]
mfname (ModFiles -> ByteString
FM.encodeModFile [ModFile
modFile])
Int -> IO Int
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
0
runUnitsFunctionalityP
:: (Describe e, Describe w, ExitCodeOfReport b)
=> String
-> (UnitOpts -> AnalysisProgram e w IO a b)
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> LiteralsOpt
-> CamfortEnv
-> IO Int
runUnitsFunctionalityP :: forall e w b a.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> (UnitOpts -> AnalysisProgram e w IO a b)
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> LiteralsOpt
-> CamfortEnv
-> IO Int
runUnitsFunctionalityP [Char]
description UnitOpts -> AnalysisProgram e w IO a b
unitsProgram AnalysisRunnerP e w IO a b (AnalysisReport e w b)
runner LiteralsOpt
opts =
let uo :: UnitOpts
uo = LiteralsOpt -> UnitOpts
optsToUnitOpts LiteralsOpt
opts
in [Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler UnitOpts IO
-> UnitOpts
-> CamfortEnv
-> IO Int
forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP [Char]
description (UnitOpts -> AnalysisProgram e w IO a b
unitsProgram UnitOpts
uo) AnalysisRunnerP e w IO a b (AnalysisReport e w b)
runner MFCompiler UnitOpts IO
compileUnits UnitOpts
uo
optsToUnitOpts :: LiteralsOpt -> UnitOpts
optsToUnitOpts :: LiteralsOpt -> UnitOpts
optsToUnitOpts LiteralsOpt
m = UnitOpts
o1
where o1 :: UnitOpts
o1 = UnitOpts
unitOpts0 { uoLiterals :: LiteralsOpt
uoLiterals = LiteralsOpt
m
}
singlePfUnits
:: UnitAnalysis a -> UnitOpts
-> AnalysisProgram () () IO ProgramFile a
singlePfUnits :: forall a.
UnitAnalysis a
-> UnitOpts -> AnalysisProgram () () IO (ProgramFile A) a
singlePfUnits UnitAnalysis a
unitAnalysis UnitOpts
opts ProgramFile A
pf =
let ue :: UnitEnv
ue = UnitEnv
{ unitOpts :: UnitOpts
unitOpts = UnitOpts
opts
, unitProgramFile :: ProgramFile A
unitProgramFile = ProgramFile A
pf
}
in UnitEnv -> UnitAnalysis a -> AnalysisT () () IO a
forall a. UnitEnv -> UnitAnalysis a -> AnalysisT () () IO a
runUnitAnalysis UnitEnv
ue UnitAnalysis a
unitAnalysis
multiPfUnits
:: (Describe a)
=> UnitAnalysis (Either e (a, b))
-> UnitOpts
-> AnalysisProgram () () IO [ProgramFile] (Text, [Either e b])
multiPfUnits :: forall a e b.
Describe a =>
UnitAnalysis (Either e (a, b))
-> UnitOpts
-> AnalysisProgram () () IO [ProgramFile A] (Text, [Either e b])
multiPfUnits UnitAnalysis (Either e (a, b))
unitAnalysis UnitOpts
opts [ProgramFile A]
pfs = do
let ue :: ProgramFile A -> UnitEnv
ue ProgramFile A
pf = UnitEnv
{ unitOpts :: UnitOpts
unitOpts = UnitOpts
opts
, unitProgramFile :: ProgramFile A
unitProgramFile = ProgramFile A
pf
}
[Either e (a, b)]
results <- (ProgramFile A -> AnalysisT () () IO (Either e (a, b)))
-> [ProgramFile A] -> AnalysisT () () IO [Either e (a, b)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (\ProgramFile A
pf -> UnitEnv
-> UnitAnalysis (Either e (a, b))
-> AnalysisT () () IO (Either e (a, b))
forall a. UnitEnv -> UnitAnalysis a -> AnalysisT () () IO a
runUnitAnalysis (ProgramFile A -> UnitEnv
ue ProgramFile A
pf) UnitAnalysis (Either e (a, b))
unitAnalysis) [ProgramFile A]
pfs
let ([a]
rs, [Either e b]
ps) = (Either e (a, b) -> ([a], Either e b))
-> [Either e (a, b)] -> ([a], [Either e b])
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (((a, b) -> ([a], b)) -> Either e (a, b) -> ([a], Either e b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Either e a -> f (Either e b)
traverse (\(a
x, b
y) -> ([a
x], b
y))) [Either e (a, b)]
results
rs' :: Text
rs' = [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat ([Text] -> Text) -> ([a] -> [Text]) -> [a] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
intersperse Text
"\n" ([Text] -> [Text]) -> ([a] -> [Text]) -> [a] -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Text) -> [a] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map a -> Text
forall a. Describe a => a -> Text
describe ([a] -> Text) -> [a] -> Text
forall a b. (a -> b) -> a -> b
$ [a]
rs
(Text, [Either e b]) -> AnalysisT () () IO (Text, [Either e b])
forall a. a -> AnalysisT () () IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Text
rs', [Either e b]
ps)
unitsDump :: LiteralsOpt -> CamfortEnv -> IO Int
unitsDump :: LiteralsOpt -> CamfortEnv -> IO Int
unitsDump LiteralsOpt
_ CamfortEnv
env = do
let modFileName :: [Char]
modFileName = CamfortEnv -> [Char]
ceInputSources CamfortEnv
env
ByteString
modData <- [Char] -> IO ByteString
LB.readFile [Char]
modFileName
let eResult :: Either [Char] ModFiles
eResult = ByteString -> Either [Char] ModFiles
FM.decodeModFile ByteString
modData
case Either [Char] ModFiles
eResult of
Left [Char]
msg -> do
[Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
modFileName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
": Error: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
forall a. Show a => a -> [Char]
show [Char]
msg
Int -> IO Int
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
1
Right ModFiles
modFiles -> do
ModFiles -> (ModFile -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ModFiles
modFiles ((ModFile -> IO ()) -> IO ()) -> (ModFile -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ ModFile
modFile -> do
[Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
modFileName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
": successfully parsed summary file."
[Char] -> IO ()
putStrLn ([Char] -> IO ())
-> (Maybe [Char] -> [Char]) -> Maybe [Char] -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Maybe [Char] -> [Char]
forall a. a -> Maybe a -> a
fromMaybe [Char]
"unable to find units info" (Maybe [Char] -> IO ()) -> Maybe [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ ModFile -> Maybe [Char]
dumpModFileCompiledUnits ModFile
modFile
Int -> IO Int
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
0
unitsCheck :: LiteralsOpt -> CamfortEnv -> IO Int
unitsCheck :: LiteralsOpt -> CamfortEnv -> IO Int
unitsCheck =
[Char]
-> (UnitOpts
-> AnalysisProgram () () IO (ProgramFile A) ConsistencyReport)
-> AnalysisRunnerP
()
()
IO
(ProgramFile A)
ConsistencyReport
(AnalysisReport () () ConsistencyReport)
-> LiteralsOpt
-> CamfortEnv
-> IO Int
forall e w b a.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> (UnitOpts -> AnalysisProgram e w IO a b)
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> LiteralsOpt
-> CamfortEnv
-> IO Int
runUnitsFunctionalityP
[Char]
"Checking units for"
(UnitAnalysis ConsistencyReport
-> UnitOpts
-> AnalysisProgram () () IO (ProgramFile A) ConsistencyReport
forall a.
UnitAnalysis a
-> UnitOpts -> AnalysisProgram () () IO (ProgramFile A) a
singlePfUnits UnitAnalysis ConsistencyReport
checkUnits)
(Text
-> AnalysisRunnerP
()
()
IO
(ProgramFile A)
ConsistencyReport
(AnalysisReport () () ConsistencyReport)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"unit checking")
unitsInfer :: Bool -> LiteralsOpt -> CamfortEnv -> IO Int
unitsInfer :: Bool -> LiteralsOpt -> CamfortEnv -> IO Int
unitsInfer Bool
showAST =
[Char]
-> (UnitOpts
-> AnalysisProgram () () IO (ProgramFile A) InferenceResult)
-> AnalysisRunnerP
()
()
IO
(ProgramFile A)
InferenceResult
(AnalysisReport () () InferenceResult)
-> LiteralsOpt
-> CamfortEnv
-> IO Int
forall e w b a.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> (UnitOpts -> AnalysisProgram e w IO a b)
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> LiteralsOpt
-> CamfortEnv
-> IO Int
runUnitsFunctionalityP
[Char]
"Inferring units for"
(UnitAnalysis InferenceResult
-> UnitOpts
-> AnalysisProgram () () IO (ProgramFile A) InferenceResult
forall a.
UnitAnalysis a
-> UnitOpts -> AnalysisProgram () () IO (ProgramFile A) a
singlePfUnits UnitAnalysis InferenceResult
inferUnits)
(if Bool
showAST
then AnalysisRunnerP
()
()
IO
(ProgramFile A)
InferenceResult
(AnalysisReport () () InferenceResult)
forall (m :: * -> *) w e.
(MonadIO m, Describe w, Describe e, NFData w, NFData e) =>
AnalysisRunnerP
e
w
m
(ProgramFile A)
InferenceResult
(AnalysisReport e w InferenceResult)
describePerFileAnalysisShowASTUnitInfoP
else Text
-> AnalysisRunnerP
()
()
IO
(ProgramFile A)
InferenceResult
(AnalysisReport () () InferenceResult)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"unit inference")
describePerFileAnalysisShowASTUnitInfoP
:: (MonadIO m, Describe w, Describe e, NFData w, NFData e)
=> AnalysisRunnerP e w m ProgramFile InferenceResult (AnalysisReport e w InferenceResult)
describePerFileAnalysisShowASTUnitInfoP :: forall (m :: * -> *) w e.
(MonadIO m, Describe w, Describe e, NFData w, NFData e) =>
AnalysisRunnerP
e
w
m
(ProgramFile A)
InferenceResult
(AnalysisReport e w InferenceResult)
describePerFileAnalysisShowASTUnitInfoP AnalysisProgram e w m (ProgramFile A) InferenceResult
program LogOutput m
logOutput LogLevel
logLevel Bool
snippets ModFiles
modFiles =
AnalysisRunnerP
e
w
m
(ProgramFile A)
InferenceResult
(AnalysisReport e w InferenceResult)
forall (m :: * -> *) e w b.
(MonadIO m, Describe e, Describe w, NFData e, NFData w,
NFData b) =>
AnalysisRunnerP e w m (ProgramFile A) b (AnalysisReport e w b)
runPerFileAnalysisP AnalysisProgram e w m (ProgramFile A) InferenceResult
program LogOutput m
logOutput LogLevel
logLevel Bool
snippets ModFiles
modFiles Proxy
()
(ProgramFile A, SourceText)
()
(AnalysisReport e w InferenceResult)
m
()
-> Proxy
()
(AnalysisReport e w InferenceResult)
()
(AnalysisReport e w InferenceResult)
m
()
-> Proxy
()
(ProgramFile A, SourceText)
()
(AnalysisReport e w InferenceResult)
m
()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>->
((AnalysisReport e w InferenceResult
-> m (AnalysisReport e w InferenceResult))
-> Proxy
()
(AnalysisReport e w InferenceResult)
()
(AnalysisReport e w InferenceResult)
m
()
forall (m :: * -> *) a b r. Monad m => (a -> m b) -> Pipe a b m r
P.mapM ((AnalysisReport e w InferenceResult
-> m (AnalysisReport e w InferenceResult))
-> Proxy
()
(AnalysisReport e w InferenceResult)
()
(AnalysisReport e w InferenceResult)
m
())
-> (AnalysisReport e w InferenceResult
-> m (AnalysisReport e w InferenceResult))
-> Proxy
()
(AnalysisReport e w InferenceResult)
()
(AnalysisReport e w InferenceResult)
m
()
forall a b. (a -> b) -> a -> b
$ \ AnalysisReport e w InferenceResult
r -> do
case AnalysisReport e w InferenceResult
r of
AnalysisReport [Char]
_ [SomeMessage e w]
_ (ARSuccess (Inferred (InferenceReport ProgramFile UA
pfUA [(VV, UnitInfo)]
_))) ->
IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ())
-> (ProgramFile UA -> IO ()) -> ProgramFile UA -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile (Maybe UnitInfo) -> IO ()
forall a. Out a => a -> IO ()
pp (ProgramFile (Maybe UnitInfo) -> IO ())
-> (ProgramFile UA -> ProgramFile (Maybe UnitInfo))
-> ProgramFile UA
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UA -> Maybe UnitInfo)
-> ProgramFile UA -> ProgramFile (Maybe UnitInfo)
forall a b. (a -> b) -> ProgramFile a -> ProgramFile b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (UnitAnnotation A -> Maybe UnitInfo
forall a. UnitAnnotation a -> Maybe UnitInfo
unitInfo (UnitAnnotation A -> Maybe UnitInfo)
-> (UA -> UnitAnnotation A) -> UA -> Maybe UnitInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UA -> UnitAnnotation A
forall a. Analysis a -> a
FA.prevAnnotation) (ProgramFile UA -> ProgramFile (Maybe UnitInfo))
-> (ProgramFile UA -> ProgramFile UA)
-> ProgramFile UA
-> ProgramFile (Maybe UnitInfo)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile UA -> ProgramFile UA
forall a.
Data a =>
ProgramFile (Analysis a) -> ProgramFile (Analysis a)
FA.rename (ProgramFile UA -> m ()) -> ProgramFile UA -> m ()
forall a b. (a -> b) -> a -> b
$ ProgramFile UA
pfUA
AnalysisReport e w InferenceResult
_ -> () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Text
-> Maybe LogLevel
-> Bool
-> AnalysisReport e w InferenceResult
-> m ()
forall e w r (m :: * -> *).
(Describe e, Describe w, Describe r, MonadIO m) =>
Text -> Maybe LogLevel -> Bool -> AnalysisReport e w r -> m ()
putDescribeReport Text
"unit inference" (LogLevel -> Maybe LogLevel
forall a. a -> Maybe a
Just LogLevel
logLevel) Bool
snippets AnalysisReport e w InferenceResult
r
AnalysisReport e w InferenceResult
-> m (AnalysisReport e w InferenceResult)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure AnalysisReport e w InferenceResult
r)
expandDirs :: [FilePath] -> IO [FilePath]
expandDirs :: [[Char]] -> IO [[Char]]
expandDirs = ([[[Char]]] -> [[Char]]) -> IO [[[Char]]] -> IO [[Char]]
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [[[Char]]] -> [[Char]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (IO [[[Char]]] -> IO [[Char]])
-> ([[Char]] -> IO [[[Char]]]) -> [[Char]] -> IO [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> IO [[Char]]) -> [[Char]] -> IO [[[Char]]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM [Char] -> IO [[Char]]
doEach
where
doEach :: [Char] -> IO [[Char]]
doEach [Char]
path = do
Bool
isDir <- [Char] -> IO Bool
doesDirectoryExist [Char]
path
if Bool
isDir
then [Char] -> IO [[Char]]
listFortranFiles [Char]
path
else [[Char]] -> IO [[Char]]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [[Char]
path]
listFortranFiles :: FilePath -> IO [FilePath]
listFortranFiles :: [Char] -> IO [[Char]]
listFortranFiles [Char]
dir = ([Char] -> Bool) -> [[Char]] -> [[Char]]
forall a. (a -> Bool) -> [a] -> [a]
filter [Char] -> Bool
isFortran ([[Char]] -> [[Char]]) -> IO [[Char]] -> IO [[Char]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> IO [[Char]]
listDirectoryRecursively [Char]
dir
where
isFortran :: FilePath -> Bool
isFortran :: [Char] -> Bool
isFortran [Char]
x = (Char -> Char) -> [Char] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower ([Char] -> [Char]
takeExtension [Char]
x) [Char] -> [[Char]] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [[Char]]
exts
where exts :: [[Char]]
exts = [[Char]
".f", [Char]
".f90", [Char]
".f77", [Char]
".f03"]
listDirectoryRecursively :: FilePath -> IO [FilePath]
listDirectoryRecursively :: [Char] -> IO [[Char]]
listDirectoryRecursively [Char]
dir = [Char] -> [Char] -> IO [[Char]]
listDirectoryRec [Char]
dir [Char]
""
where
listDirectoryRec :: FilePath -> FilePath -> IO [FilePath]
listDirectoryRec :: [Char] -> [Char] -> IO [[Char]]
listDirectoryRec [Char]
d [Char]
f = do
let fullPath :: [Char]
fullPath = [Char]
d [Char] -> [Char] -> [Char]
</> [Char]
f
Bool
isDir <- [Char] -> IO Bool
doesDirectoryExist [Char]
fullPath
if Bool
isDir
then do
[[Char]]
conts <- [Char] -> IO [[Char]]
listDirectory [Char]
fullPath
[[[Char]]] -> [[Char]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[[Char]]] -> [[Char]]) -> IO [[[Char]]] -> IO [[Char]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([Char] -> IO [[Char]]) -> [[Char]] -> IO [[[Char]]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ([Char] -> [Char] -> IO [[Char]]
listDirectoryRec [Char]
fullPath) [[Char]]
conts
else [[Char]] -> IO [[Char]]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [[Char]
fullPath]
decodeOneModFile :: FilePath -> IO FM.ModFiles
decodeOneModFile :: [Char] -> IO ModFiles
decodeOneModFile [Char]
path = do
ByteString
contents <- [Char] -> IO ByteString
LB.readFile [Char]
path
case ByteString -> Either [Char] ModFiles
FM.decodeModFile ByteString
contents of
Left [Char]
msg -> do
Handle -> [Char] -> IO ()
hPutStrLn Handle
stderr ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
path [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
": Error: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
msg
ModFiles -> IO ModFiles
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []
Right ModFiles
modFiles -> do
Handle -> [Char] -> IO ()
hPutStrLn Handle
stderr ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
path [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
": successfully parsed summary file."
ModFiles -> IO ModFiles
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ModFiles
modFiles
unitsCompile :: LiteralsOpt -> CamfortEnv -> IO Int
unitsCompile :: LiteralsOpt -> CamfortEnv -> IO Int
unitsCompile LiteralsOpt
opts CamfortEnv
env = do
let uo :: UnitOpts
uo = LiteralsOpt -> UnitOpts
optsToUnitOpts LiteralsOpt
opts
let description :: [Char]
description = [Char]
"Compiling units for"
[Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
description [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" '" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ CamfortEnv -> [Char]
ceInputSources CamfortEnv
env [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"'"
[Char]
incDir' <- IO [Char] -> ([Char] -> IO [Char]) -> Maybe [Char] -> IO [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe IO [Char]
getCurrentDirectory [Char] -> IO [Char]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CamfortEnv -> Maybe [Char]
ceIncludeDir CamfortEnv
env)
Bool
isDir <- [Char] -> IO Bool
doesDirectoryExist [Char]
incDir'
let incDir :: [Char]
incDir | Bool
isDir = [Char]
incDir'
| Bool
otherwise = [Char] -> [Char]
takeDirectory [Char]
incDir'
[[Char]]
paths' <- [[Char]] -> IO [[Char]]
expandDirs ([[Char]] -> IO [[Char]]) -> [[Char]] -> IO [[Char]]
forall a b. (a -> b) -> a -> b
$ [CamfortEnv -> [Char]
ceInputSources CamfortEnv
env]
ModGraph
mg0 <- Maybe FortranVersion -> [[Char]] -> [[Char]] -> IO ModGraph
FM.genModGraph (CamfortEnv -> Maybe FortranVersion
ceFortranVersion CamfortEnv
env) [[Char]
incDir] [[Char]]
paths'
let compileFileToMod :: ModFiles -> ProgramFile A -> IO ModFile
compileFileToMod ModFiles
mods ProgramFile A
pf = do
ModFile
mod <- MFCompiler UnitOpts IO
compileUnits UnitOpts
uo ModFiles
mods ProgramFile A
pf
let mfname :: [Char]
mfname = [Char] -> [Char] -> [Char]
replaceExtension (ModFile -> [Char]
FM.moduleFilename ModFile
mod) [Char]
FM.modFileSuffix
[Char] -> ByteString -> IO ()
LB.writeFile [Char]
mfname (ModFiles -> ByteString
FM.encodeModFile [ModFile
mod])
ModFile -> IO ModFile
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ModFile
mod
let loop :: ModGraph -> ModFiles -> IO ModFiles
loop ModGraph
mg ModFiles
mods
| [(Int, Maybe ModOrigin)]
nxt <- ModGraph -> [(Int, Maybe ModOrigin)]
FM.takeNextMods ModGraph
mg
, Bool -> Bool
not ([(Int, Maybe ModOrigin)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Int, Maybe ModOrigin)]
nxt) = do
let fnPaths :: [[Char]]
fnPaths = [ [Char]
fn | (Int
_, Just (FM.MOFile [Char]
fn)) <- [(Int, Maybe ModOrigin)]
nxt ]
ModFiles
newMods <- ([ModFiles] -> ModFiles) -> IO [ModFiles] -> IO ModFiles
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [ModFiles] -> ModFiles
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (IO [ModFiles] -> IO ModFiles)
-> (([Char] -> IO ModFiles) -> IO [ModFiles])
-> ([Char] -> IO ModFiles)
-> IO ModFiles
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Char]] -> ([Char] -> IO ModFiles) -> IO [ModFiles]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [[Char]]
fnPaths (([Char] -> IO ModFiles) -> IO ModFiles)
-> ([Char] -> IO ModFiles) -> IO ModFiles
forall a b. (a -> b) -> a -> b
$ \ [Char]
fnPath -> do
TimestampStatus
tsStatus <- [Char] -> IO TimestampStatus
FM.checkTimestamps [Char]
fnPath
case TimestampStatus
tsStatus of
TimestampStatus
FM.NoSuchFile -> do
[Char] -> IO ()
putStr ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Does not exist: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
fnPath
ModFiles -> IO ModFiles
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [ModFile
FM.emptyModFile]
FM.ModFileExists [Char]
modPath -> do
[Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Loading mod file " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
modPath [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"."
[Char] -> IO ModFiles
decodeOneModFile [Char]
modPath
TimestampStatus
FM.CompileFile -> do
[Char] -> IO ()
putStr ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Summarising " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
fnPath [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"..."
Maybe (ProgramFile A, SourceText)
m_pf <- Maybe FortranVersion
-> ModFiles -> [Char] -> IO (Maybe (ProgramFile A, SourceText))
readParseSrcFile (CamfortEnv -> Maybe FortranVersion
ceFortranVersion CamfortEnv
env) ModFiles
mods [Char]
fnPath
case Maybe (ProgramFile A, SourceText)
m_pf of
Just (ProgramFile A
pf, SourceText
_) -> do
ModFile
mod <- ModFiles -> ProgramFile A -> IO ModFile
compileFileToMod ModFiles
mods ProgramFile A
pf
[Char] -> IO ()
putStrLn [Char]
"done"
ModFiles -> IO ModFiles
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [ModFile
mod]
Maybe (ProgramFile A, SourceText)
Nothing -> do
[Char] -> IO ()
putStrLn [Char]
"failed"
ModFiles -> IO ModFiles
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
let ns :: [Int]
ns = ((Int, Maybe ModOrigin) -> Int)
-> [(Int, Maybe ModOrigin)] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Maybe ModOrigin) -> Int
forall a b. (a, b) -> a
fst [(Int, Maybe ModOrigin)]
nxt
let mg' :: ModGraph
mg' = [Int] -> ModGraph -> ModGraph
FM.delModNodes [Int]
ns ModGraph
mg
ModGraph -> ModFiles -> IO ModFiles
loop ModGraph
mg' (ModFiles -> IO ModFiles) -> ModFiles -> IO ModFiles
forall a b. (a -> b) -> a -> b
$ ModFiles
newMods ModFiles -> ModFiles -> ModFiles
forall a. [a] -> [a] -> [a]
++ ModFiles
mods
loop ModGraph
_ ModFiles
mods = ModFiles -> IO ModFiles
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ModFiles
mods
ModFiles
_allMods <- ModGraph -> ModFiles -> IO ModFiles
loop ModGraph
mg0 []
Int -> IO Int
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
0
unitsSynth :: AnnotationType -> FileOrDir -> LiteralsOpt -> CamfortEnv -> IO Int
unitsSynth :: AnnotationType -> [Char] -> LiteralsOpt -> CamfortEnv -> IO Int
unitsSynth AnnotationType
annType [Char]
outSrc LiteralsOpt
opts CamfortEnv
env =
[Char]
-> AnalysisProgram
()
()
IO
[ProgramFile A]
(Text, [Either ConsistencyError (ProgramFile A)])
-> AnalysisRunner
()
()
IO
[ProgramFile A]
(Text, [Either ConsistencyError (ProgramFile A)])
Int
-> MFCompiler UnitOpts IO
-> UnitOpts
-> CamfortEnv
-> IO Int
forall e w a b r i.
(Describe e, Describe w) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunner e w IO a b r
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO r
runFunctionality [Char]
"Synthesising units for"
(UnitAnalysis
(Either ConsistencyError (InferenceReport, ProgramFile A))
-> UnitOpts
-> AnalysisProgram
()
()
IO
[ProgramFile A]
(Text, [Either ConsistencyError (ProgramFile A)])
forall a e b.
Describe a =>
UnitAnalysis (Either e (a, b))
-> UnitOpts
-> AnalysisProgram () () IO [ProgramFile A] (Text, [Either e b])
multiPfUnits (Char
-> UnitAnalysis
(Either ConsistencyError (InferenceReport, ProgramFile A))
LU.synthesiseUnits (AnnotationType -> Char
markerChar AnnotationType
annType)) UnitOpts
uo)
(Text
-> [Char]
-> [Char]
-> AnalysisRunner
()
()
IO
[ProgramFile A]
(Text, [Either ConsistencyError (ProgramFile A)])
Int
forall e e' w r.
(Describe e, Describe e', Describe w, Describe r,
ExitCodeOfReport r) =>
Text
-> [Char]
-> [Char]
-> AnalysisRunner
e w IO [ProgramFile A] (r, [Either e' (ProgramFile A)]) Int
doRefactor Text
"unit synthesis" (CamfortEnv -> [Char]
ceInputSources CamfortEnv
env) [Char]
outSrc)
MFCompiler UnitOpts IO
compileUnits
UnitOpts
uo
CamfortEnv
env
where uo :: UnitOpts
uo = LiteralsOpt -> UnitOpts
optsToUnitOpts LiteralsOpt
opts
unitsCriticals :: LiteralsOpt -> CamfortEnv -> IO Int
unitsCriticals :: LiteralsOpt -> CamfortEnv -> IO Int
unitsCriticals =
[Char]
-> (UnitOpts -> AnalysisProgram () () IO (ProgramFile A) Criticals)
-> AnalysisRunnerP
() () IO (ProgramFile A) Criticals (AnalysisReport () () Criticals)
-> LiteralsOpt
-> CamfortEnv
-> IO Int
forall e w b a.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> (UnitOpts -> AnalysisProgram e w IO a b)
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> LiteralsOpt
-> CamfortEnv
-> IO Int
runUnitsFunctionalityP
[Char]
"Suggesting variables to annotate with unit specifications in"
(UnitAnalysis Criticals
-> UnitOpts -> AnalysisProgram () () IO (ProgramFile A) Criticals
forall a.
UnitAnalysis a
-> UnitOpts -> AnalysisProgram () () IO (ProgramFile A) a
singlePfUnits UnitAnalysis Criticals
inferCriticalVariables)
(Text
-> AnalysisRunnerP
() () IO (ProgramFile A) Criticals (AnalysisReport () () Criticals)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"unit critical variable analysis")
stencilsCheck :: CamfortEnv -> IO Int
stencilsCheck :: CamfortEnv -> IO Int
stencilsCheck =
[Char]
-> AnalysisProgram () () IO (ProgramFile A) CheckResult
-> AnalysisRunnerP
()
()
IO
(ProgramFile A)
CheckResult
(AnalysisReport () () CheckResult)
-> MFCompiler () IO
-> ()
-> CamfortEnv
-> IO Int
forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP
[Char]
"Checking stencil specs for"
(PureAnalysis () () CheckResult -> AnalysisT () () IO CheckResult
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis () () CheckResult -> AnalysisT () () IO CheckResult)
-> (ProgramFile A -> PureAnalysis () () CheckResult)
-> AnalysisProgram () () IO (ProgramFile A) CheckResult
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProgramFile A -> PureAnalysis () () CheckResult
Stencils.check)
(Text
-> AnalysisRunnerP
()
()
IO
(ProgramFile A)
CheckResult
(AnalysisReport () () CheckResult)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"stencil checking")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
compileStencils ()
stencilsInfer :: Bool -> CamfortEnv -> IO Int
stencilsInfer :: Bool -> CamfortEnv -> IO Int
stencilsInfer Bool
useEval =
[Char]
-> AnalysisProgram () () IO (ProgramFile A) StencilsReport
-> AnalysisRunnerP
()
()
IO
(ProgramFile A)
StencilsReport
(AnalysisReport () () StencilsReport)
-> MFCompiler () IO
-> ()
-> CamfortEnv
-> IO Int
forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP
[Char]
"Inferring stencil specs for"
(PureAnalysis () () StencilsReport
-> AnalysisT () () IO StencilsReport
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis () () StencilsReport
-> AnalysisT () () IO StencilsReport)
-> (ProgramFile A -> PureAnalysis () () StencilsReport)
-> AnalysisProgram () () IO (ProgramFile A) StencilsReport
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Char -> ProgramFile A -> PureAnalysis () () StencilsReport
Stencils.infer Bool
useEval Char
'=')
(Text
-> AnalysisRunnerP
()
()
IO
(ProgramFile A)
StencilsReport
(AnalysisReport () () StencilsReport)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"stencil inference")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
compileStencils ()
stencilsSynth :: AnnotationType -> FileOrDir -> CamfortEnv -> IO Int
stencilsSynth :: AnnotationType -> [Char] -> CamfortEnv -> IO Int
stencilsSynth AnnotationType
annType =
let
program :: AnalysisProgram () () IO [ProgramFile] ((), [Either () ProgramFile])
program :: AnalysisProgram
() () IO [ProgramFile A] ((), [Either () (ProgramFile A)])
program [ProgramFile A]
pfs = PureAnalysis () () ((), [Either () (ProgramFile A)])
-> AnalysisT () () IO ((), [Either () (ProgramFile A)])
forall (m :: * -> *) e w a.
Monad m =>
PureAnalysis e w a -> AnalysisT e w m a
generalizePureAnalysis (PureAnalysis () () ((), [Either () (ProgramFile A)])
-> AnalysisT () () IO ((), [Either () (ProgramFile A)]))
-> PureAnalysis () () ((), [Either () (ProgramFile A)])
-> AnalysisT () () IO ((), [Either () (ProgramFile A)])
forall a b. (a -> b) -> a -> b
$ do
[ProgramFile A]
pfs' <- Char -> [ProgramFile A] -> StencilsAnalysis [ProgramFile A]
Stencils.synth (AnnotationType -> Char
markerChar AnnotationType
annType) [ProgramFile A]
pfs
((), [Either () (ProgramFile A)])
-> PureAnalysis () () ((), [Either () (ProgramFile A)])
forall a. a -> AnalysisT () () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return ((), (ProgramFile A -> Either () (ProgramFile A))
-> [ProgramFile A] -> [Either () (ProgramFile A)]
forall a b. (a -> b) -> [a] -> [b]
map ProgramFile A -> Either () (ProgramFile A)
forall a b. b -> Either a b
Right [ProgramFile A]
pfs')
in [Char]
-> AnalysisProgram
() () IO [ProgramFile A] ((), [Either () (ProgramFile A)])
-> ([Char]
-> [Char]
-> AnalysisRunner
() () IO [ProgramFile A] ((), [Either () (ProgramFile A)]) Int)
-> MFCompiler () IO
-> ()
-> [Char]
-> CamfortEnv
-> IO Int
forall e w a b r i.
(Describe e, Describe w) =>
[Char]
-> AnalysisProgram e w IO a b
-> ([Char] -> [Char] -> AnalysisRunner e w IO a b r)
-> MFCompiler i IO
-> i
-> [Char]
-> CamfortEnv
-> IO r
runWithOutput
[Char]
"Synthesising stencil specs for"
AnalysisProgram
() () IO [ProgramFile A] ((), [Either () (ProgramFile A)])
program
(Text
-> [Char]
-> [Char]
-> AnalysisRunner
() () IO [ProgramFile A] ((), [Either () (ProgramFile A)]) Int
forall e e' w r.
(Describe e, Describe e', Describe w, Describe r,
ExitCodeOfReport r) =>
Text
-> [Char]
-> [Char]
-> AnalysisRunner
e w IO [ProgramFile A] (r, [Either e' (ProgramFile A)]) Int
doRefactor Text
"stencil synthesis")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
compileStencils ()
invariantsCheck :: Hoare.PrimReprOption -> CamfortEnv -> IO Int
invariantsCheck :: PrimReprOption -> CamfortEnv -> IO Int
invariantsCheck PrimReprOption
pro =
[Char]
-> AnalysisProgram
HoareFrontendError
HoareFrontendWarning
IO
(ProgramFile A)
HoareCheckResults
-> AnalysisRunnerP
HoareFrontendError
HoareFrontendWarning
IO
(ProgramFile A)
HoareCheckResults
(AnalysisReport
HoareFrontendError HoareFrontendWarning HoareCheckResults)
-> MFCompiler () IO
-> ()
-> CamfortEnv
-> IO Int
forall e w b a i.
(Describe e, Describe w, ExitCodeOfReport b) =>
[Char]
-> AnalysisProgram e w IO a b
-> AnalysisRunnerP e w IO a b (AnalysisReport e w b)
-> MFCompiler i IO
-> i
-> CamfortEnv
-> IO Int
runFunctionalityP
[Char]
"Checking invariants in"
(PrimReprOption
-> AnalysisProgram
HoareFrontendError
HoareFrontendWarning
IO
(ProgramFile A)
HoareCheckResults
Hoare.check PrimReprOption
pro)
(Text
-> AnalysisRunnerP
HoareFrontendError
HoareFrontendWarning
IO
(ProgramFile A)
HoareCheckResults
(AnalysisReport
HoareFrontendError HoareFrontendWarning HoareCheckResults)
forall (m :: * -> *) r w e.
(MonadIO m, Describe r, ExitCodeOfReport r, Describe w, Describe e,
NFData e, NFData w, NFData r) =>
Text
-> AnalysisRunnerP e w m (ProgramFile A) r (AnalysisReport e w r)
describePerFileAnalysisP Text
"invariant checking")
MFCompiler () IO
forall (m :: * -> *). Monad m => MFCompiler () m
simpleCompiler ()
camfortInitialize :: FilePath -> IO ()
camfortInitialize :: [Char] -> IO ()
camfortInitialize [Char]
projectDir =
Bool -> [Char] -> IO ()
createDirectoryIfMissing Bool
False ([Char]
projectDir [Char] -> [Char] -> [Char]
</> [Char]
".camfort")