tstModules.hs

import TypedIds
import WorkModule(WorkModuleI(..))
import HsParser(parse)
import ReAssocBase
import ReAssoc(getInfixes)
import MUtils(collectByFst)--,unlessM
import List(partition,nub)
--import Maybe(fromJust)
import ParseProgram
import ParserOptions
import DefinedNames(definedNames)
import ReAssoc(getInfixes)
import HsIdent(getHSName)
import NamesEntities
import Ents

import UniqueNames
import NoEq
--import UTF8Util
--import PrettyPrint
import PPU
import MUtils
import ScopeProgram
import TiPNT()
import ScopeNamesBase()
import NameMapsBase()
import NameMaps(Role(..),Context(..))
import Unlit(readHaskellFile)
import ParsedSyntax
import DirUtils
import ConvRefsTypes
import Relations() -- for show instances

import TiModule()

main = tstModules =<< getPPopts

tstModules (o,prog,args) = test flags0 args
  where
    test flags args =
	case args of
	  "noprelude":args         -> test flags{prel=False}    args
	  "cpp"      :args         -> test flags{cpp=Just cpp1} args
	  ('c':'p':'p':'=':s):args -> test flags{cpp=Just s}    args

	  "test"     :fs -> tstModules           =<< analyzePrg =<< expand fs
	  "create"   :fs -> do fs' <- expand fs
			       createInterfaceFiles fs' =<< analyzePrg fs'
	  "parse"    :fs -> tstParse             =<< parsePrg   =<< expand fs
	  "preparse" :fs -> tstParse'            =<< parseSrc   =<< expand fs
	  "preparse0":fs -> const (return ())    =<< parseSrc   =<< expand fs
	  "lex"      :fs -> tstLex               =<< readHFiles =<< expand fs
	  "unlit"    :fs -> mapM_ putStr         =<< readHFiles =<< expand fs
	  "defined"  :fs -> tstDefinedNames      =<< parseSrc   =<< expand fs
	  "infixes"  :fs -> tstInfixes           =<< parseSrc   =<< expand fs
	  "scope"    :fs -> tstScope             =<< scopePrg   =<< expand fs
	  "xrefs"    :fs -> createCrossRefs      =<< scopePrg   =<< expand fs
	--"update":[] -> ...
	  _ -> fail "Usage: tstModules [+utf8] [+debug] [cpp[=<cmd>]] [noprelude] (test|create|parse|preparse|lex|unlit|defined|infixes|scope|xrefs) <files>"
      where
	analyzePrg = analyzeFiles' flags parse
	parseSrc = parseSourceFiles (cpp flags) parse
	parsePrg = parseProgram' flags parse
	scopePrg files = scopeProgram' # parsePrg files

	tstModules = pput . ppAssoc . snd

	tstParse  = tstParse' . concat . fst
	tstParse' = pput . vcat

	tstDefinedNames = pput . definedNames
	tstInfixes = putStr . unlines . map (showl.getInfixes)

	tstScope (mss,_) = pput mss

	readHFiles = mapM (readHaskellFile (cpp flags))
	tstLex = mapM_ (print.lexerPass0)

    pput x = putStrLn $ ppu o x
--------------------------------------------------------------------------------

createInterfaceFiles files (modss,amods) =
    do optCreateDirectory "hi"
       writeFile "hi/SourceFiles.txt" (unlines files)
       writeModuleGraphInfo modss
       mapM_ createInterfaceFile amods

  where

    createInterfaceFile (m,wm) =
        writeFile (hiFile m) (render . vcat . interface . exports $ wm)

--    ent2Pair (m,n,s)         = (m,(n,s))
    ent2Pair (Ent m n s)         = (m,(n,s))
    

    interface = map iface . collectByFst . map (ent2Pair.snd)
      where
        iface (m,allns) = hsModule loc0 m (Just exports) ([],infixes)
        -- :: HsModuleI (HsIdentI (Src HsName)) [HsDeclI (HsIdentI (Src HsName))]
          where
            exports     = toExp `map` oth 
            (subs,oth)  = partition (subordinate.snd) allns   
            toExp (n,ty)
                | isClassOrType ty  = HsEThingWith n elems
                | otherwise         = HsEAbs n 
                where
                elems = [x | (x,idty) <- subs, idty `belongsTo` getHSName n]

            infixes = [Dec (HsInfixDecl loc0 f [qn']) |
                        mods<-modss, mod<-mods, hsModName mod==m,
                        (qn,f) <- getInfixes mod,
                        let n = getQualified qn; -- Because of Prelude.: etc
		                    qn' = mkUnqual n `asTypeOf` qn
                        ]

    hiFile (Module s) = hiDir++"/"++s++".hi"
    hiDir = "hi" -- name of directory where interface files are put

--------------------------------------------------------------------------------

createCrossRefs (mss,mrs) =
    do optCreateDirectory "hi"
       writeModuleGraphInfo mss
       mapM_ writeRefs (simplifyRefsTypes mrs)
  where
    writeRefs (m,rs) = writeFile ("hi/"++m++".refs") (showl rs)

--- Module graph info ----------------------------------------------------------

writeModuleGraphInfo mss =
    do writeFile "hi/ModuleSourceFiles.hv" (show mfs)
       writeFile "hi/ModuleSourceFiles.txt" (txt2 mfs)
       writeFile "hi/Modules.txt" (showModuleNames mss)
       writeFile "hi/ModuleGraph.hv" (pp g)
       writeFile "hi/ModuleGraph.txt" (txtn g)
       writeFile "hi/ModuleGraphRev.hv" (pp revg)
       writeFile "hi/ModuleGraphRev.txt" (txtn revg)
  where
    mfs = map modfile (concat mss)
    g = moduleGraph mss
    revg = collectByFst [(i,m)|(m,is)<-g,i<-is]

    modfile m = (srcFile m,pp (hsModName m))

    txt2 = unlines . map (\(f,m)->m++" "++f)
    txtn = unlines . map (\(m,is)->pp m++" "++unwords (map pp is))

    -- One strongly connected component per line:
    showModuleNames = unlines . map (unwords . map (pp . hsModName))

    moduleGraph = map moduleImports . concat 
    moduleImports m = (hsModName m,nub . map hsImpFrom . hsModImports $ m)

--- Pretty printing ------------------------------------------------------------

ppAssoc x = vcat . map cbn $ x
    where   
    cbn (k,v) = k <> ":" <+> v

--ppResult = ppAssoc . snd

--- Utils ----------------------------------------------------------------------

showl x = unlines . map show $ x

Plain-text version of tstModules.hs | Valid HTML?