diff options
Diffstat (limited to 'haddock-api/src/Haddock/Interface/Create.hs')
| -rw-r--r-- | haddock-api/src/Haddock/Interface/Create.hs | 121 | 
1 files changed, 79 insertions, 42 deletions
| diff --git a/haddock-api/src/Haddock/Interface/Create.hs b/haddock-api/src/Haddock/Interface/Create.hs index 52a983a8..4866f76b 100644 --- a/haddock-api/src/Haddock/Interface/Create.hs +++ b/haddock-api/src/Haddock/Interface/Create.hs @@ -115,7 +115,7 @@ createInterface tm flags modMap instIfaceMap = do        unrestrictedImportedMods          -- module re-exports are only possible with          -- explicit export list -        | Just _ <- exports +        | Just{} <- exports          = unrestrictedModuleImports (map unLoc imports)          | otherwise = M.empty @@ -380,7 +380,7 @@ mkMaps dflags gre instances decls = do              m'   <- traverse (processDocStringParas dflags gre) m              pure (doc', m') -      (doc, args) <- declDoc docStrs (typeDocs decl) +      (doc, args) <- declDoc docStrs (declTypeDocs decl)        let            subs :: [(Name, [HsDocString], Map Int HsDocString)] @@ -445,14 +445,14 @@ subordinates instMap decl = case decl of            | isDataDecl  d -> dataSubs (tcdDataDefn d)    _ -> []    where -    classSubs dd = [ (name, doc, typeDocs d) | (L _ d, doc) <- classDecls dd +    classSubs dd = [ (name, doc, declTypeDocs d) | (L _ d, doc) <- classDecls dd                     , name <- getMainDeclBinder d, not (isValD d)                     ]      dataSubs :: HsDataDefn GhcRn -> [(Name, [HsDocString], Map Int HsDocString)]      dataSubs dd = constrs ++ fields ++ derivs        where          cons = map unL $ (dd_cons dd) -        constrs = [ (unL cname, maybeToList $ fmap unL $ con_doc c, M.empty) +        constrs = [ (unL cname, maybeToList $ fmap unL $ con_doc c, conArgDocs c)                    | c <- cons, cname <- getConNames c ]          fields  = [ (selectorFieldOcc n, maybeToList $ fmap unL doc, M.empty)                    | RecCon flds <- map getConArgs cons @@ -464,17 +464,33 @@ subordinates instMap decl = case decl of                             unLoc $ dd_derivs dd                    , Just instName <- [M.lookup l instMap] ] +-- | Extract constructor argument docs from inside constructor decls. +conArgDocs :: ConDecl GhcRn -> Map Int HsDocString +conArgDocs con = case getConArgs con of +                   PrefixCon args -> go 0 (map unLoc args ++ ret) +                   InfixCon arg1 arg2 -> go 0 ([unLoc arg1, unLoc arg2] ++ ret) +                   RecCon _ -> go 1 ret +  where +    go n (HsDocTy _ (L _ ds) : tys) = M.insert n ds $ go (n+1) tys +    go n (_ : tys) = go (n+1) tys +    go _ [] = M.empty + +    ret = case con of +            ConDeclGADT { con_res_ty = res_ty } -> [ unLoc res_ty ] +            _ -> [] + +-- | Extract function argument docs from inside top-level decls. +declTypeDocs :: HsDecl GhcRn -> Map Int HsDocString +declTypeDocs (SigD (TypeSig _ ty))      = typeDocs (unLoc (hsSigWcType ty)) +declTypeDocs (SigD (ClassOpSig _ _ ty)) = typeDocs (unLoc (hsSigType ty)) +declTypeDocs (SigD (PatSynSig _ ty))    = typeDocs (unLoc (hsSigType ty)) +declTypeDocs (ForD (ForeignImport _ ty _ _))   = typeDocs (unLoc (hsSigType ty)) +declTypeDocs (TyClD (SynDecl { tcdRhs = ty })) = typeDocs (unLoc ty) +declTypeDocs _ = M.empty +  -- | Extract function argument docs from inside types. -typeDocs :: HsDecl GhcRn -> Map Int HsDocString -typeDocs d = -  let docs = go 0 in -  case d of -    SigD (TypeSig _ ty)      -> docs (unLoc (hsSigWcType ty)) -    SigD (ClassOpSig _ _ ty) -> docs (unLoc (hsSigType ty)) -    SigD (PatSynSig _ ty)    -> docs (unLoc (hsSigType ty)) -    ForD (ForeignImport _ ty _ _)   -> docs (unLoc (hsSigType ty)) -    TyClD (SynDecl { tcdRhs = ty }) -> docs (unLoc ty) -    _ -> M.empty +typeDocs :: HsType GhcRn -> Map Int HsDocString +typeDocs = go 0    where      go n (HsForAllTy { hst_body = ty }) = go n (unLoc ty)      go n (HsQualTy   { hst_body = ty }) = go n (unLoc ty) @@ -483,7 +499,6 @@ typeDocs d =      go n (HsDocTy _ (L _ doc)) = M.singleton n doc      go _ _ = M.empty -  -- | All the sub declarations of a class (that we handle), ordered by  -- source location, with documentation attached if it exists.  classDecls :: TyClDecl GhcRn -> [(LHsDecl GhcRn, [HsDocString])] @@ -689,11 +704,6 @@ availExportItem is_sig modMap thisMod semMod warnings exportedNames            let declNames = getMainDeclBinder (unL decl)            in case () of              _ -              -- TODO: temp hack: we filter out separately exported ATs, since we haven't decided how -              -- to handle them yet. We should really give an warning message also, and filter the -              -- name out in mkVisibleNames... -              | t `elem` declATs (unL decl)        -> return [] -                -- We should not show a subordinate by itself if any of its                -- parents is also exported. See note [1].                | t `notElem` declNames, @@ -767,7 +777,7 @@ availExportItem is_sig modMap thisMod semMod warnings exportedNames            return [ ExportDecl {                         expItemDecl      = restrictTo (fmap fst subs) -                                            (extractDecl (availName avail) decl) +                                            (extractDecl declMap (availName avail) decl)                       , expItemPats      = bundledPatSyns                       , expItemMbDoc     = doc                       , expItemSubDocs   = subs @@ -779,7 +789,7 @@ availExportItem is_sig modMap thisMod semMod warnings exportedNames        | otherwise =            return [ ExportDecl { -                       expItemDecl      = extractDecl sub decl +                       expItemDecl      = extractDecl declMap sub decl                       , expItemPats      = []                       , expItemMbDoc     = sub_doc                       , expItemSubDocs   = [] @@ -978,47 +988,74 @@ fullModuleContents :: Bool               -- is it a signature                     -> Avails                     -> ErrMsgGhc [ExportItem GhcRn]  fullModuleContents is_sig modMap thisMod semMod warnings exportedNames -  decls maps fixMap splices instIfaceMap dflags avails = do -  let availEnv = availsToNameEnv avails +  decls maps@(_, _, declMap, _) fixMap splices instIfaceMap dflags avails = do +  let availEnv = availsToNameEnv (nubAvails avails)    (concat . concat) `fmap` (for decls $ \decl -> do      for (getMainDeclBinder (unLoc decl)) $ \nm -> do        case lookupNameEnv availEnv nm of -        Just avail -> availExportItem is_sig modMap thisMod -                        semMod warnings exportedNames maps fixMap -                        splices instIfaceMap dflags avail +        Just avail +          | L _ (ValD valDecl) <- decl +          , (name:_) <- collectHsBindBinders valDecl +          , Just (L _ SigD{}:_) <- filter isSigD <$> M.lookup name declMap +          -> pure [] + +          | otherwise +          -> availExportItem is_sig modMap thisMod +               semMod warnings exportedNames maps fixMap +               splices instIfaceMap dflags avail          Nothing -> pure []) - +  where +    isSigD (L _ SigD{}) = True +    isSigD _            = False  -- | Sometimes the declaration we want to export is not the "main" declaration:  -- it might be an individual record selector or a class method.  In these  -- cases we have to extract the required declaration (and somehow cobble  -- together a type signature for it...). -extractDecl :: Name -> LHsDecl GhcRn -> LHsDecl GhcRn -extractDecl name decl +extractDecl :: DeclMap -> Name -> LHsDecl GhcRn -> LHsDecl GhcRn +extractDecl declMap name decl    | name `elem` getMainDeclBinder (unLoc decl) = decl    | otherwise  =      case unLoc decl of        TyClD d@ClassDecl {} -> -        let matches = [ lsig -                      | lsig <- tcdSigs d -                      , ClassOpSig False _ _ <- pure $ unLoc lsig -                        -- Note: exclude `default` declarations (see #505) -                      , name `elem` sigName lsig -                      ] +        let +          matchesMethod = +            [ lsig +            | lsig <- tcdSigs d +            , ClassOpSig False _ _ <- pure $ unLoc lsig +              -- Note: exclude `default` declarations (see #505) +            , name `elem` sigName lsig +            ] + +          matchesAssociatedType = +            [ lfam_decl +            | lfam_decl <- tcdATs d +            , name == unLoc (fdLName (unLoc lfam_decl)) +            ] +              -- TODO: document fixity -        in case matches of -          [s0] -> let (n, tyvar_names) = (tcdName d, tyClDeclTyVars d) -                      L pos sig = addClassContext n tyvar_names s0 -                  in L pos (SigD sig) +        in case (matchesMethod, matchesAssociatedType)  of +          ([s0], _) -> let (n, tyvar_names) = (tcdName d, tyClDeclTyVars d) +                           L pos sig = addClassContext n tyvar_names s0 +                       in L pos (SigD sig) +          (_, [L pos fam_decl]) -> L pos (TyClD (FamDecl fam_decl)) + +          ([], []) +            | Just (famInstDecl:_) <- M.lookup name declMap +            -> extractDecl declMap name famInstDecl            _ -> O.pprPanic "extractDecl" (O.text "Ambiguous decl for" O.<+> O.ppr name O.<+> O.text "in class:"                                           O.$$ O.nest 4 (O.ppr d)                                           O.$$ O.text "Matches:" -                                         O.$$ O.nest 4 (O.ppr matches)) +                                         O.$$ O.nest 4 (O.ppr matchesMethod O.<+> O.ppr matchesAssociatedType))        TyClD d@DataDecl {} ->          let (n, tyvar_tys) = (tcdName d, lHsQTyVarsToTypes (tyClDeclTyVars d))          in if isDataConName name             then SigD <$> extractPatternSyn name n tyvar_tys (dd_cons (tcdDataDefn d))             else SigD <$> extractRecSel name n tyvar_tys (dd_cons (tcdDataDefn d)) +      TyClD FamDecl {} +        | isValName name +        , Just (famInst:_) <- M.lookup name declMap +        -> extractDecl declMap name famInst        InstD (DataFamInstD (DataFamInstDecl (HsIB { hsib_body =                               FamEqn { feqn_tycon = L _ n                                      , feqn_pats  = tys @@ -1034,7 +1071,7 @@ extractDecl name decl                             , selectorFieldOcc n == name                        ]          in case matches of -          [d0] -> extractDecl name (noLoc . InstD $ DataFamInstD d0) +          [d0] -> extractDecl declMap name (noLoc . InstD $ DataFamInstD d0)            _ -> error "internal: extractDecl (ClsInstD)"        _ -> error "internal: extractDecl" | 
