module GF.Compile.Tags
( writeTags
, gf2gftags
) where
import GF.Infra.Option
import GF.Infra.UseIO
import GF.Data.Operations
import GF.Grammar
--import Data.List
import qualified Data.Map as Map
import qualified Data.Set as Set
--import Control.Monad
import GF.Text.Pretty
import System.FilePath
writeTags opts gr file mo = do
let imports = getImports opts gr mo
locals = getLocalTags [] mo
txt = unlines ((Set.toList . Set.fromList) (imports++locals))
putPointE Normal opts (" write file" +++ file) $ liftIO $ writeFile file txt
getLocalTags x (m,mi) =
[showIdent i ++ "\t" ++ k ++ "\t" ++ l ++ "\t" ++ t
| (i,jment) <- Map.toList (jments mi),
(k,l,t) <- getLocations jment] ++ x
where
getLocations :: Info -> [(String,String,String)]
getLocations (AbsCat mb_ctxt) = maybe (loc "cat") mb_ctxt
getLocations (AbsFun mb_type _ mb_eqs _) = maybe (ltype "fun") mb_type ++
maybe (list (loc "def")) mb_eqs
getLocations (ResParam mb_params _) = maybe (loc "param") mb_params
getLocations (ResValue mb_type) = ltype "param-value" mb_type
getLocations (ResOper mb_type mb_def) = maybe (ltype "oper-type") mb_type ++
maybe (loc "oper-def") mb_def
getLocations (ResOverload _ defs) = list (\(x,y) -> ltype "overload-type" x ++
loc "overload-def" y) defs
getLocations (CncCat mty md mr mprn _) = maybe (loc "lincat") mty ++
maybe (loc "lindef") md ++
maybe (loc "linref") mr ++
maybe (loc "printname") mprn
getLocations (CncFun _ mlin mprn _) = maybe (loc "lin") mlin ++
maybe (loc "printname") mprn
getLocations _ = []
loc kind (L loc _) = [(kind,render (ppLocation (msrc mi) loc),"")]
ltype kind (L loc ty) = [(kind,render (ppLocation (msrc mi) loc),render (ppTerm Unqualified 0 ty))]
maybe f (Just x) = f x
maybe f Nothing = []
list f xs = concatMap f xs
render = renderStyle style{mode=OneLineMode}
getImports opts gr mo@(m,mi) = concatMap toDep allOpens
where
allOpens = [(OSimple m,incl) | (m,incl) <- mextend mi] ++
[(o,MIAll) | o <- mopens mi]
toDep (OSimple m,incl) =
let Ok mi = lookupModule gr m
in [showIdent id ++ "\t" ++ "indir" ++ "\t" ++ render m ++ "\t\t" ++ gf2gftags opts (orig mi info)
| (id,info) <- Map.toList (jments mi), filter incl id]
toDep (OQualif m1 m2,incl) =
let Ok mi = lookupModule gr m2
in [showIdent id ++ "\t" ++ "indir" ++ "\t" ++ render m2 ++ "\t" ++ render m1 ++ "\t" ++ gf2gftags opts (orig mi info)
| (id,info) <- Map.toList (jments mi), filter incl id]
filter MIAll id = True
filter (MIOnly ids) id = elem id ids
filter (MIExcept ids) id = not (elem id ids)
orig mi info =
case info of
AnyInd _ m0 -> let Ok mi0 = lookupModule gr m0
in msrc mi0
_ -> msrc mi
gftagsFile :: FilePath -> FilePath
gftagsFile f = addExtension f "gf-tags"
gf2gftags :: Options -> FilePath -> FilePath
gf2gftags opts file = maybe (gftagsFile (dropExtension file))
(\dir -> dir </> gftagsFile (dropExtension (takeFileName file)))
(flag optOutputDir opts)