@@ -24,6 +24,7 @@ import Idris.DSL
24import Idris.Imports
24import Idris.Imports
25import Idris.Delaborate
25import Idris.Delaborate
26import Idris.Error
26import Idris.Error
27+import Idris.Elab.Value
27import Idris.ElabDecls
28import Idris.ElabDecls
28import Idris.ElabTerm
29import Idris.ElabTerm
29import Idris.Coverage
30import Idris.Coverage
@@ -90,18 +91,21 @@ import System.IO
90 ModuleHeader ::= 'module' Identifier_t ';'?;
91 ModuleHeader ::= 'module' Identifier_t ';'?;
93−moduleHeader :: IdrisParser [String]
94+moduleHeader :: IdrisParser (Maybe (Docstring ()), [String])
94−moduleHeader = try (do noDocCommentHere "Modules cannot have documentation comments"
95+moduleHeader = try (do docs <- optional docComment
95 reserved "module"
97 reserved "module"
96 i <- identifier
98 i <- identifier
97 option ';' (lchar ';')
99 option ';' (lchar ';')
98− return (moduleName i))
100+ return (fmap fst docs, moduleName i))
99 <|> try (do lchar '%'; reserved "unqualified"
101 <|> try (do lchar '%'; reserved "unqualified"
100− return [])
102+ return (Nothing, []))
101− <|> return (moduleName "Main")
103+ <|> return (Nothing, moduleName "Main")
102 where moduleName x = case span (/='.') x of
104 where moduleName x = case span (/='.') x of
103 (x, "") -> [x]
105 (x, "") -> [x]
104 (x, '.':y) -> x : moduleName y
106 (x, '.':y) -> x : moduleName y
107+ noArgs (Just (_, args)) | not (null args) = fail "Modules do not take arguments"
108+ noArgs _ = return ()
106{- | Parses an import statement
110{- | Parses an import statement
@@ -1133,24 +1137,24 @@ parseTactic :: IState -> String -> Result PTactic
1133parseTactic st = runparser (fullTactic defaultSyntax) st "(input)"
1137parseTactic st = runparser (fullTactic defaultSyntax) st "(input)"
1135-- | Parse module header and imports
1139-- | Parse module header and imports
1136−parseImports :: FilePath -> String -> Idris ([String], [(Bool, String, Maybe String, FC)], Maybe Delta)
1140+parseImports :: FilePath -> String -> Idris (Maybe (Docstring ()), [String], [(Bool, String, Maybe String, FC)], Maybe Delta)
1137parseImports fname input
1141parseImports fname input
1138 = do i <- getIState
1142 = do i <- getIState
1139 case parseString (runInnerParser (evalStateT imports i)) (Directed (UTF8.fromString fname) 0 0 0 0) input of
1143 case parseString (runInnerParser (evalStateT imports i)) (Directed (UTF8.fromString fname) 0 0 0 0) input of
1140 Failure err -> fail (show err)
1144 Failure err -> fail (show err)
1141 Success (x, i) -> do putIState i
1145 Success (x, i) -> do putIState i
1142 return x
1146 return x
1143− where imports :: IdrisParser (([String], [(Bool, String, Maybe String, FC)], Maybe Delta), IState)
1147+ where imports :: IdrisParser ((Maybe (Docstring ()), [String], [(Bool, String, Maybe String, FC)], Maybe Delta), IState)
1144 imports = do whiteSpace
1148 imports = do whiteSpace
1145− mname <- moduleHeader
1149+ (mdoc, mname) <- moduleHeader
1146− ps <- many import_
1150+ ps <- many import_
1147− mrk <- mark
1151+ mrk <- mark
1148− isEof <- lookAheadMatches eof
1152+ isEof <- lookAheadMatches eof
1149 let mrk' = if isEof
1153 let mrk' = if isEof
1150 then Nothing
1154 then Nothing
1151 else Just mrk
1155 else Just mrk
1152 i <- get
1156 i <- get
1153− return ((mname, ps, mrk'), i)
1157+ return ((mdoc, mname, ps, mrk'), i)
1155-- | There should be a better way of doing this...
1159-- | There should be a better way of doing this...
1156findFC :: Doc -> (FC, String)
1160findFC :: Doc -> (FC, String)
@@ -1261,7 +1265,7 @@ loadSource lidr f toline
1261 let def_total = default_total i
1265 let def_total = default_total i
1262 file_in <- runIO $ readFile f
1266 file_in <- runIO $ readFile f
1263 file <- if lidr then tclift $ unlit f file_in else return file_in
1267 file <- if lidr then tclift $ unlit f file_in else return file_in
1264− (mname, imports_in, pos) <- parseImports f file
1268+ (mdocs, mname, imports_in, pos) <- parseImports f file
1265 ai <- getAutoImports
1269 ai <- getAutoImports
1266 let imports = map (\n -> (True, n, Just n, emptyFC)) ai ++ imports_in
1270 let imports = map (\n -> (True, n, Just n, emptyFC)) ai ++ imports_in
1267 ids <- allImportDirs
1271 ids <- allImportDirs
@@ -1340,6 +1344,13 @@ loadSource lidr f toline
1340 i <- getIState
1344 i <- getIState
1341 addHides (hide_list i)
1345 addHides (hide_list i)
1347+ -- Save module documentation if applicable
1350+ Nothing -> return ()
1351+ Just docs -> addModDoc syntax mname docs
1343 -- Finally, write an ibc if checking was successful
1354 -- Finally, write an ibc if checking was successful
1344 ok <- noErrors
1355 ok <- noErrors
1345 when ok $
1356 when ok $
@@ -1364,6 +1375,17 @@ loadSource lidr f toline
1364 PInstance _ _ _ _ _ _ _ _ -> r
1375 PInstance _ _ _ _ _ _ _ _ -> r
1378+ addModDoc :: SyntaxInfo -> [String] -> Docstring () -> Idris ()
1379+ addModDoc syn mname docs =
1380+ do ist <- getIState
1381+ docs' <- elabDocTerms recinfo (parsedDocs ist)
1382+ let modDocs' = addDef docName docs' (idris_moduledocs ist)
1383+ putIState ist { idris_moduledocs = modDocs' }
1384+ addIBC (IBCModDocs docName)
1386+ docName = NS modDocName (map T.pack (reverse mname))
1387+ parsedDocs ist = annotCode (tryFullExpr syn ist) docs
1367{- | Adds names to hide list -}
1389{- | Adds names to hide list -}
1368addHides :: [(Name, Maybe Accessibility)] -> Idris ()
1390addHides :: [(Name, Maybe Accessibility)] -> Idris ()
1369addHides xs = do i <- getIState
1391addHides xs = do i <- getIState