0N/ACopyright : (c) Sonja Groening, Christian Maeder, Uni Bremen 2002-2004
0N/AMaintainer : maeder@tzi.de
0N/AStability : provisional
0N/APortability : portable
0N/A G_l_sentence_list (..),
1879N/A-- toplevel function: Creates DevGraph and
1879N/A-- (including all imported modules)
1879N/AanaHaskellFile :: HetcatsOpts
0N/A -> IO (Maybe (LIB_NAME, -- filename
1879N/A DGraph, -- development graph
0N/A LibEnv)) -- DGraphs for
0N/A -- incl. main module
1879N/AanaHaskellFile _ srcFile = anaHaskellFileAux srcFile
1879N/AanaHaskellFileAux :: String -> -- DGraph ->
1879N/A IO (Maybe (LIB_NAME, HsModule,
0N/AanaHaskellFileAux srcFile =
1879N/A moduleSyntax <- fmap cvrtHsModule $ parseFile srcFile
0N/A (absSyn, modInfo, le) <- typeInference moduleSyntax
0N/A let libName = Lib_id(Indirect_link srcFile [])
0N/A -- convert HaskellEnv to DGraph, build up corresponding LibEnv
0N/A let (dg',le') = hasEnv2DG libName absSyn modInfo le
0N/A return (Just(libName, moduleSyntax, dg', le'))
0N/AtypeInference :: HsModule
0N/A -> IO (AHsModule, ModuleInfo, LibEnv)
0N/AtypeInference moduleSyntax =
0N/A let annotatedSyntax = getAnnotedSyntax moduleSyntax
1879N/A (modInfos, le) <- anaImportDecls annotatedSyntax
0N/A -- concat all modInfos
0N/A let importedModInfo = concatModuleInfos modInfos
1879N/A -- this is the ModuleInfo that we were passing into tiModule
0N/A -- earlier (just the Prelude stuff)
0N/A let initialModInfo = joinModuleInfo preludeModInfo importedModInfo
1934N/A -- call the type inference code for this module
1879N/A moduleSynonyms) = tiModule annotatedSyntax initialModInfo
1879N/A let modInfo = ModuleInfo { varAssumps = moduleEnv,
1879N/A moduleName = getAModuleName annotatedSyntax,
1879N/A classHierarchy = newClassHierarchy,
1879N/A tyconsMembers = getTyconsMembers moduleRenamed,
1879N/A infixDecls = getInfixDecls moduleRenamed,
1879N/A synonyms = moduleSynonyms }
1879N/A return (moduleRenamed, modInfo, le)
0N/AanaImportDecls :: AHsModule -> IO ([ModuleInfo], LibEnv)
0N/AanaImportDecls (AHsModule _ _ idecls _) = anaImports idecls []
Map.empty 1879N/AanaImports :: [AHsImportDecl] -> [ModuleInfo] -> LibEnv
1879N/A -> IO ([ModuleInfo], LibEnv)
1879N/AanaImports [] modInfos le = do return (modInfos, le)
1879N/AanaImports (imp:imps) modInfos le =
1879N/A (newModInfo, le') <- anaOneImport imp le
1879N/A anaImports imps (newModInfo:modInfos) le'
0N/AanaOneImport :: AHsImportDecl -> LibEnv
1879N/AanaOneImport (AHsImportDecl _ aMod _ _ maybeListOfIdents) le = do
1879N/A modSyn <- parseFile (fileName aMod)
1879N/A (annoSyn, modInfo, leImports) <- typeInference modSyn
1879N/A filteredModInfo = filtModInfo aMod modInfo maybeListOfIdents
1879N/A (dg,node) = addNode empty annoSyn filteredModInfo
1879N/A AHsModule _ _ idecls _ -> case idecls of
1879N/A [] -> return (filteredModInfo,addDG2LibEnv le' ln node dg)
1879N/A _ -> return (filteredModInfo, addDG2LibEnv le' ln node
1879N/A $ addLinks idecls dg node le')
1879N/A where filtModInfo _ modInfo Nothing = modInfo
1879N/A -- we're not imposing restrictions
1879N/A filtModInfo aModule modInfo (Just (_, importSpecs)) =
1879N/A filterModuleInfo aModule modInfo $
1879N/A expandDotsInTyCons aModule (tyconsMembers modInfo) $
1879N/A map importSpecToExportSpec importSpecs
1879N/AtoLibName :: AModule -> LIB_NAME
1879N/AtoLibName aMod = Lib_id(Indirect_link (fileName aMod) [])
0N/AaddLinks :: [AHsImportDecl] -> DGraph -> Node -> LibEnv
0N/AaddLinks (idecl:idecls) dg mainNode le =
1879N/A let ln = toLibName (getModName idecl)
1879N/A (dgWithRef, ref) = addDGRef ln dg node
1879N/A link = createDGLinkLabel idecl
1879N/A -- insert new edge with LinkLabel
1879N/A linkedDG = insEdge (ref,mainNode,link) dgWithRef
1879N/A in addLinks idecls linkedDG mainNode le
1879N/A where getModName (AHsImportDecl _ name _ _ _) = name
1879N/AhasEnv2DG :: LIB_NAME -> AHsModule -> ModuleInfo
1879N/A -> LibEnv -> (DGraph, LibEnv)
1879N/AhasEnv2DG ln aMod modInfo le =
1879N/A let (dg, node) = addNode empty aMod modInfo
1879N/A dg' = addLinks (getImps aMod) dg node le
1879N/A in (dg', (addDG2LibEnv le ln node dg'))
1879N/A where getImps (AHsModule _ _ imps _) = imps
1879N/A-- input: (so far generated) DGraph,
1879N/A-- a module's abstract syntax and its ModuleInfo
1879N/A-- task: adds a new node (representing the module)
1879N/AaddNode :: DGraph -> AHsModule -> ModuleInfo
1879N/AaddNode dg (AHsModule name exps imps decls) modInfo =
1879N/A -- create a node, representing the module
1879N/A | imps == [] = -- module with no imports
1879N/A dgn_name = aHsMod2SimpleId name,
1879N/A dgn_sign = G_sign Haskell modInfo,
1879N/A dgn_sens = G_l_sentence_list Haskell
1879N/A (extractSentences (AHsModule name
1879N/A | otherwise = -- module with imports
1879N/A dgn_name = aHsMod2SimpleId name,
1879N/A dgn_sign = G_sign Haskell modInfo,
1879N/A dgn_sens = G_l_sentence_list Haskell
1879N/A (extractSentences (AHsModule name
1879N/A in (insNode (node, node_contents) dg, node)
1879N/AaddDGRef :: LIB_NAME -> DGraph -> Node -> (DGraph, Node)
0N/A dgn_renamed = ln2SimpleId ln,
0N/A [newNode] = newNodes 0 dg
1879N/A in (insNode (newNode, node_contents) dg, newNode)
1879N/Aln2SimpleId :: LIB_NAME -> Maybe (SIMPLE_ID)
0N/Aln2SimpleId (Lib_id (Indirect_link modName _)) =
0N/A Just (Token { tokStr = modName,
0N/Aln2SimpleId (Lib_id (Direct_link modName _)) =
0N/A Just (Token { tokStr = modName,
0N/Aln2SimpleId (Lib_version link _) = ln2SimpleId (Lib_id link)
1879N/A-- --------------- utilities --------------- --
1879N/AcreateDGLinkLabel :: AHsImportDecl -> DGLinkLab
1879N/A AHsImportDecl _ _ _ _ Nothing -> -- no hiding
1879N/A dgl_morphism = gEmbed (G_morphism Haskell ()),
1879N/A AHsImportDecl _ _ _ _ (Just(False,_)) -> -- no hiding
0N/A dgl_morphism = gEmbed (G_morphism Haskell ()),
0N/A dgl_type = GlobalDef,
0N/A dgl_origin = DGExtension }
0N/A AHsImportDecl _ _ _ _ (Just(True,_)) -> -- hiding
1879N/A dgl_morphism = gEmbed (G_morphism Haskell ()),
1879N/AaddDG2LibEnv :: LibEnv -> LIB_NAME -> Node -> DGraph -> LibEnv
1879N/AaddDG2LibEnv le libName n dg =
Just(nodeLab) = getNodeContent n dg
imp = EmptyNode (Logic Haskell)
parsig = dgn_sign nodeLab -- empty_signature Haskell
body = NodeSig (n, (dgn_sign nodeLab))
(SpecEntry (imp,params,parsig,body))
Map.insert libName (emptyGlobalAnnos, globalEnv, dg) le
lookupNode :: LIB_NAME -> LibEnv -> Node
(_, (SpecEntry (_, _, _, body))) =
Map.elemAt 0 globalEnv
aHsMod2SimpleId :: AModule -> Maybe SIMPLE_ID
aHsMod2SimpleId (AModule name) = Just (Token { tokStr = name,
fileName :: AModule -> String
fileName (AModule name) = name ++ ".hs"
getNodeContent :: Node -> DGraph -> Maybe (DGNodeLab)
(Just (_,_,nodeLab,_), _) -> Just (nodeLab)
getDgn_name :: DGNodeLab -> SIMPLE_ID
getDgn_name nl = let Just(n) = dgn_name nl