Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve reporting, mostly around type information but also source spans #292

Merged
merged 3 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ main = do
Right a -> a
outfmt = outputFormat opts
mmap = combinedModuleMap mods
tenv = combinedTypeEnv mods
tenv = stripExtended $ combinedTypeEnv mods
pvm = combinedParamVarMap mods

let runTypes = analyseAndCheckTypesWithEnv tenv . analyseRenamesWithModuleMap mmap . initAnalysis
Expand All @@ -143,7 +143,7 @@ main = do
Lex -> ioError $ userError $ usageInfo programName options
Parse -> pp parsedPF
Typecheck -> let (pf, _, errs) = runTypes parsedPF in
printTypeErrors errs >> printTypes (extractTypeEnv pf)
printTypeErrors errs >> printTypes (extractTypeEnvExtended pf)
Rename -> pp $ runRenamer parsedPF
BBlocks -> putStrLn $ runBBlocks parsedPF
SuperGraph -> putStrLn $ runSuperGraph parsedPF
Expand Down Expand Up @@ -220,7 +220,7 @@ compileFileToMod mvers mods path moutfile = do
contents <- flexReadFile path
let version = fromMaybe (deduceFortranVersion path) mvers
mmap = combinedModuleMap mods
tenv = combinedTypeEnv mods
tenv = stripExtended $ combinedTypeEnv mods
runCompile = genModFile . fst . analyseTypesWithEnv tenv . analyseRenamesWithModuleMap mmap . initAnalysis
parsedPF <-
case (Parser.byVerWithMods mods version) path contents of
Expand Down Expand Up @@ -295,12 +295,14 @@ showStringMap :: StringMap -> String
showStringMap = showGenericMap
showModuleMap :: ModuleMap -> String
showModuleMap = concatMap (\ (n, m) -> show n ++ ":\n" ++ (unlines . map (" "++) . lines . showGenericMap $ m)) . M.toList
showTypes :: TypeEnv -> String
showTypes :: TypeEnvExtended -> String
showTypes tenv =
flip concatMap (M.toList tenv) $
\ (name, IDType { idVType = vt, idCType = ct }) ->
printf "%s\t\t%s %s\n" name (drop 1 $ maybe " -" show vt) (drop 2 $ maybe " " show ct)
printTypes :: TypeEnv -> IO ()
let sortedInfo = sortBy (\(_, (_, sp1, _)) (_, (_, sp2, _)) -> compare sp1 sp2) $ M.toList tenv
in
flip concatMap sortedInfo $
\ (_, (name, sp, IDType { idVType = vt, idCType = ct })) ->
printf "%s\t %s\t\t%s %s\n" (show $ ssFrom sp) name (drop 1 $ maybe " -" show vt) (drop 2 $ maybe " " show ct)
printTypes :: TypeEnvExtended -> IO ()
printTypes = putStrLn . showTypes
showTypeErrors :: [TypeError] -> String
showTypeErrors errs = unlines [ show ss ++ ": " ++ msg | (msg, ss) <- sortBy (comparing snd) errs ]
Expand Down
26 changes: 26 additions & 0 deletions src/Language/Fortran/Analysis/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ module Language.Fortran.Analysis.Types
( analyseTypes
, analyseTypesWithEnv
, analyseAndCheckTypesWithEnv
, stripExtended
, extractTypeEnv
, extractTypeEnvExtended
, TypeEnv
, TypeEnvExtended
, TypeError
, deriveSemTypeFromDeclaration
, deriveSemTypeFromTypeSpec
Expand Down Expand Up @@ -35,6 +38,11 @@ import Language.Fortran.Version (FortranVersion(..))

-- | Mapping of names to type information.
type TypeEnv = M.Map Name IDType
-- | Mapping of names to type information with more information about the source
type TypeEnvExtended = M.Map Name (Name, SrcSpan, IDType)

stripExtended :: TypeEnvExtended -> TypeEnv
stripExtended = M.map (\(_, _, t) -> t)

-- | Information about a detected type error.
type TypeError = (String, SrcSpan)
Expand Down Expand Up @@ -120,6 +128,24 @@ extractTypeEnv pf = M.union puEnv expEnv
, let n = varName e
, ty <- maybeToList (idType (getAnnotation e)) ]

extractTypeEnvExtended :: forall a. Data a => ProgramFile (Analysis a) -> TypeEnvExtended
extractTypeEnvExtended pf = M.union puEnv expEnv
where
puEnv = M.fromList [ (n, (srcName, getSpan pu, ty)) | pu <- universeBi pf :: [ProgramUnit (Analysis a)]
, Named n <- [puName pu]
, Named srcName <- [puSrcName pu]
, ty <- maybeToList (idType (getAnnotation pu)) ]
expEnv = M.fromList [ (n, (srcName e, sp, ty)) | e@(ExpValue _ _ ValVariable{}) <- universeBi pf :: [Expression (Analysis a)]
, let n = varName e
, sp <- getDeclarator n
, ty <- maybeToList (idType (getAnnotation e)) ]
getDeclarator v' =
[ sp | d@(Declarator _ sp ev _ _ _) <- universeBi pf :: [Declarator (Analysis a)]
, varName ev == v' ]




type TransType f g a = (f (Analysis a) -> Infer (f (Analysis a))) -> g (Analysis a) -> Infer (g (Analysis a))
annotateTypes :: Data a => ProgramFile (Analysis a) -> Infer (ProgramFile (Analysis a))
annotateTypes pf = (transformBiM :: Data a => TransType Expression ProgramFile a) annotateExpression pf >>=
Expand Down
6 changes: 4 additions & 2 deletions src/Language/Fortran/Transformation/Monad.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Language.Fortran.Transformation.Monad
import Prelude hiding (lookup)
import Control.Monad.State.Lazy hiding (state)
import Data.Data
import qualified Data.Map as M

import Language.Fortran.Analysis
import Language.Fortran.Analysis.Types
Expand All @@ -22,13 +23,14 @@ type Transform a = State (TransformationState a)

runTransform
:: Data a
=> TypeEnv -> ModuleMap -> Transform a () -> ProgramFile a -> ProgramFile a
=> TypeEnvExtended -> ModuleMap -> Transform a () -> ProgramFile a -> ProgramFile a
runTransform env mmap trans pf =
stripAnalysis . transProgramFile . execState trans $ initState
where
(pf', _) = analyseTypesWithEnv env . analyseRenamesWithModuleMap mmap . initAnalysis $ pf
(pf', _) = analyseTypesWithEnv (removeExtendedInfo env) . analyseRenamesWithModuleMap mmap . initAnalysis $ pf
initState = TransformationState
{ transProgramFile = pf' }
removeExtendedInfo = M.map (\(_, _, t) -> t)

getProgramFile :: Transform a (ProgramFile (Analysis a))
getProgramFile = gets transProgramFile
Expand Down
6 changes: 3 additions & 3 deletions src/Language/Fortran/Util/ModFile.hs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ data ModFile = ModFile { mfFilename :: String
, mfStringMap :: StringMap
, mfModuleMap :: FAR.ModuleMap
, mfDeclMap :: DeclMap
, mfTypeEnv :: FAT.TypeEnv
, mfTypeEnv :: FAT.TypeEnvExtended
, mfParamVarMap :: ParamVarMap
, mfOtherData :: M.Map String LB.ByteString }
deriving (Eq, Show, Data, Typeable, Generic)
Expand All @@ -142,7 +142,7 @@ emptyModFile = ModFile "" M.empty M.empty M.empty M.empty M.empty M.empty
regenModFile :: forall a. (Data a) => F.ProgramFile (FA.Analysis a) -> ModFile -> ModFile
regenModFile pf mf = mf { mfModuleMap = extractModuleMap pf
, mfDeclMap = extractDeclMap pf
, mfTypeEnv = FAT.extractTypeEnv pf
, mfTypeEnv = FAT.extractTypeEnvExtended pf
, mfParamVarMap = extractParamVarMap pf
, mfFilename = F.pfGetFilename pf }

Expand Down Expand Up @@ -224,7 +224,7 @@ localisedModuleMap = M.map (M.filter (not . FA.isImported . snd))

-- | Extract the combined module map from a set of ModFiles. Useful
-- for parsing a Fortran file in a large context of other modules.
combinedTypeEnv :: ModFiles -> FAT.TypeEnv
combinedTypeEnv :: ModFiles -> FAT.TypeEnvExtended
combinedTypeEnv = M.unions . map mfTypeEnv

-- | Extract the combined declaration map from a set of
Expand Down
5 changes: 4 additions & 1 deletion src/Language/Fortran/Util/Position.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ instance Binary Position
instance NFData Position

instance Show Position where
show (Position _ c l _ _) = show l ++ ':' : show c
-- Column number decrement by 1 as the lexer generates column numbers
-- starting at position 1
-- See PR https://github.com/camfort/fortran-src/pull/292
show (Position _ c l _ _) = show l ++ ':' : show (c - 1)
dorchard marked this conversation as resolved.
Show resolved Hide resolved

initPosition :: Position
initPosition = Position
Expand Down
Loading