From 209f431220b138f3a25f9294f702f658ea45ae37 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 3 Jun 2021 19:44:25 -0700 Subject: [PATCH 01/33] Refactor: Use do notation to expose `title` value --- src/Language/PureScript/Docs/Convert/Single.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index 4099ce6618..f57c5f215d 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -28,7 +28,9 @@ convertSingleModule m@(P.Module _ coms moduleName _ _) = comments = convertComments coms declarations = P.exportedDeclarations - >>> mapMaybe (\d -> getDeclarationTitle d >>= convertDeclaration d) + >>> mapMaybe (\d -> do + title <- getDeclarationTitle d + convertDeclaration d title) >>> augmentDeclarations -- | Different declarations we can augment From 67597801fed327d09665907a8dd24b0cf7867caa Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 3 Jun 2021 19:47:31 -0700 Subject: [PATCH 02/33] Flip order of arguments and use `\case` syntax --- .../PureScript/Docs/Convert/Single.hs | 99 ++++++++++--------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index f57c5f215d..9d9398bf22 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -30,7 +30,7 @@ convertSingleModule m@(P.Module _ coms moduleName _ _) = P.exportedDeclarations >>> mapMaybe (\d -> do title <- getDeclarationTitle d - convertDeclaration d title) + convertDeclaration title d) >>> augmentDeclarations -- | Different declarations we can augment @@ -114,54 +114,55 @@ mkDeclaration (ss, com) title info = basicDeclaration :: P.SourceAnn -> Text -> DeclarationInfo -> Maybe IntermediateDeclaration basicDeclaration sa title = Just . Right . mkDeclaration sa title -convertDeclaration :: P.Declaration -> Text -> Maybe IntermediateDeclaration -convertDeclaration (P.ValueDecl sa _ _ _ [P.MkUnguarded (P.TypedValue _ _ ty)]) title = - basicDeclaration sa title (ValueDeclaration (ty $> ())) -convertDeclaration (P.ValueDecl sa _ _ _ _) title = - -- If no explicit type declaration was provided, insert a wildcard, so that - -- the actual type will be added during type checking. - basicDeclaration sa title (ValueDeclaration (P.TypeWildcard () Nothing)) -convertDeclaration (P.ExternDeclaration sa _ ty) title = - basicDeclaration sa title (ValueDeclaration (ty $> ())) -convertDeclaration (P.DataDeclaration sa dtype _ args ctors) title = - Just (Right (mkDeclaration sa title info) { declChildren = children }) - where - info = DataDeclaration dtype (fmap (fmap (fmap ($> ()))) args) - children = map convertCtor ctors - convertCtor :: P.DataConstructorDeclaration -> ChildDeclaration - convertCtor P.DataConstructorDeclaration{..} = - ChildDeclaration (P.runProperName dataCtorName) (convertComments $ snd dataCtorAnn) Nothing (ChildDataConstructor (fmap (($> ()) . snd) dataCtorFields)) -convertDeclaration (P.ExternDataDeclaration sa _ kind') title = - basicDeclaration sa title (ExternDataDeclaration (kind' $> ())) -convertDeclaration (P.TypeSynonymDeclaration sa _ args ty) title = - basicDeclaration sa title (TypeSynonymDeclaration (fmap (fmap (fmap ($> ()))) args) (ty $> ())) -convertDeclaration (P.TypeClassDeclaration sa _ args implies fundeps ds) title = - Just (Right (mkDeclaration sa title info) { declChildren = children }) - where - args' = fmap (fmap (fmap ($> ()))) args - info = TypeClassDeclaration args' (fmap ($> ()) implies) (convertFundepsToStrings args' fundeps) - children = map convertClassMember ds - convertClassMember (P.TypeDeclaration (P.TypeDeclarationData (ss, com) ident' ty)) = - ChildDeclaration (P.showIdent ident') (convertComments com) (Just ss) (ChildTypeClassMember (ty $> ())) - convertClassMember _ = - P.internalError "convertDeclaration: Invalid argument to convertClassMember." -convertDeclaration (P.TypeInstanceDeclaration (ss, com) _ _ _ constraints className tys _) title = - Just (Left ((classNameString, AugmentClass) : map (, AugmentType) typeNameStrings, AugmentChild childDecl)) - where - classNameString = unQual className - typeNameStrings = ordNub (concatMap (P.everythingOnTypes (++) extractProperNames) tys) - unQual x = let (P.Qualified _ y) = x in P.runProperName y - - extractProperNames (P.TypeConstructor _ n) = [unQual n] - extractProperNames _ = [] - - childDecl = ChildDeclaration title (convertComments com) (Just ss) (ChildInstance (fmap ($> ()) constraints) (classApp $> ())) - classApp = foldl' P.srcTypeApp (P.srcTypeConstructor (fmap P.coerceProperName className)) tys -convertDeclaration (P.ValueFixityDeclaration sa fixity (P.Qualified mn alias) _) title = - Just . Right $ mkDeclaration sa title (AliasDeclaration fixity (P.Qualified mn (Right alias))) -convertDeclaration (P.TypeFixityDeclaration sa fixity (P.Qualified mn alias) _) title = - Just . Right $ mkDeclaration sa title (AliasDeclaration fixity (P.Qualified mn (Left alias))) -convertDeclaration _ _ = Nothing +convertDeclaration :: Text -> P.Declaration -> Maybe IntermediateDeclaration +convertDeclaration title = \case + P.ValueDecl sa _ _ _ [P.MkUnguarded (P.TypedValue _ _ ty)] -> + basicDeclaration sa title (ValueDeclaration (ty $> ())) + P.ValueDecl sa _ _ _ _ -> + -- If no explicit type declaration was provided, insert a wildcard, so that + -- the actual type will be added during type checking. + basicDeclaration sa title (ValueDeclaration (P.TypeWildcard () Nothing)) + P.ExternDeclaration sa _ ty -> + basicDeclaration sa title (ValueDeclaration (ty $> ())) + P.DataDeclaration sa dtype _ args ctors -> + Just (Right (mkDeclaration sa title info) { declChildren = children }) + where + info = DataDeclaration dtype (fmap (fmap (fmap ($> ()))) args) + children = map convertCtor ctors + convertCtor :: P.DataConstructorDeclaration -> ChildDeclaration + convertCtor P.DataConstructorDeclaration{..} = + ChildDeclaration (P.runProperName dataCtorName) (convertComments $ snd dataCtorAnn) Nothing (ChildDataConstructor (fmap (($> ()) . snd) dataCtorFields)) + P.ExternDataDeclaration sa _ kind' -> + basicDeclaration sa title (ExternDataDeclaration (kind' $> ())) + P.TypeSynonymDeclaration sa _ args ty -> + basicDeclaration sa title (TypeSynonymDeclaration (fmap (fmap (fmap ($> ()))) args) (ty $> ())) + P.TypeClassDeclaration sa _ args implies fundeps ds -> + Just (Right (mkDeclaration sa title info) { declChildren = children }) + where + args' = fmap (fmap (fmap ($> ()))) args + info = TypeClassDeclaration args' (fmap ($> ()) implies) (convertFundepsToStrings args' fundeps) + children = map convertClassMember ds + convertClassMember (P.TypeDeclaration (P.TypeDeclarationData (ss, com) ident' ty)) = + ChildDeclaration (P.showIdent ident') (convertComments com) (Just ss) (ChildTypeClassMember (ty $> ())) + convertClassMember _ = + P.internalError "convertDeclaration: Invalid argument to convertClassMember." + P.TypeInstanceDeclaration (ss, com) _ _ _ constraints className tys _ -> + Just (Left ((classNameString, AugmentClass) : map (, AugmentType) typeNameStrings, AugmentChild childDecl)) + where + classNameString = unQual className + typeNameStrings = ordNub (concatMap (P.everythingOnTypes (++) extractProperNames) tys) + unQual x = let (P.Qualified _ y) = x in P.runProperName y + + extractProperNames (P.TypeConstructor _ n) = [unQual n] + extractProperNames _ = [] + + childDecl = ChildDeclaration title (convertComments com) (Just ss) (ChildInstance (fmap ($> ()) constraints) (classApp $> ())) + classApp = foldl' P.srcTypeApp (P.srcTypeConstructor (fmap P.coerceProperName className)) tys + P.ValueFixityDeclaration sa fixity (P.Qualified mn alias) _ -> + Just . Right $ mkDeclaration sa title (AliasDeclaration fixity (P.Qualified mn (Right alias))) + P.TypeFixityDeclaration sa fixity (P.Qualified mn alias) _ -> + Just . Right $ mkDeclaration sa title (AliasDeclaration fixity (P.Qualified mn (Left alias))) + _ -> Nothing convertComments :: [P.Comment] -> Maybe Text convertComments cs = do From 8ae3a44c9db7928ae18f878b9e68867cf4d2334d Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 3 Jun 2021 19:48:45 -0700 Subject: [PATCH 03/33] Minor stylistic change --- src/Language/PureScript/Docs/Convert/Single.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index 9d9398bf22..c6635c7735 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -30,7 +30,8 @@ convertSingleModule m@(P.Module _ coms moduleName _ _) = P.exportedDeclarations >>> mapMaybe (\d -> do title <- getDeclarationTitle d - convertDeclaration title d) + convertDeclaration title d + ) >>> augmentDeclarations -- | Different declarations we can augment From 162ab15711d29a369367061f0f54d6fe0a17e928 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 3 Jun 2021 19:56:40 -0700 Subject: [PATCH 04/33] Extract data/newtype, type, and class declarations to where clause --- .../PureScript/Docs/Convert/Single.hs | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index c6635c7735..3358d8c06a 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -126,27 +126,13 @@ convertDeclaration title = \case P.ExternDeclaration sa _ ty -> basicDeclaration sa title (ValueDeclaration (ty $> ())) P.DataDeclaration sa dtype _ args ctors -> - Just (Right (mkDeclaration sa title info) { declChildren = children }) - where - info = DataDeclaration dtype (fmap (fmap (fmap ($> ()))) args) - children = map convertCtor ctors - convertCtor :: P.DataConstructorDeclaration -> ChildDeclaration - convertCtor P.DataConstructorDeclaration{..} = - ChildDeclaration (P.runProperName dataCtorName) (convertComments $ snd dataCtorAnn) Nothing (ChildDataConstructor (fmap (($> ()) . snd) dataCtorFields)) + mkDataDeclaration sa dtype args ctors P.ExternDataDeclaration sa _ kind' -> basicDeclaration sa title (ExternDataDeclaration (kind' $> ())) P.TypeSynonymDeclaration sa _ args ty -> - basicDeclaration sa title (TypeSynonymDeclaration (fmap (fmap (fmap ($> ()))) args) (ty $> ())) + mkTypeSynonymDeclaration sa args ty P.TypeClassDeclaration sa _ args implies fundeps ds -> - Just (Right (mkDeclaration sa title info) { declChildren = children }) - where - args' = fmap (fmap (fmap ($> ()))) args - info = TypeClassDeclaration args' (fmap ($> ()) implies) (convertFundepsToStrings args' fundeps) - children = map convertClassMember ds - convertClassMember (P.TypeDeclaration (P.TypeDeclarationData (ss, com) ident' ty)) = - ChildDeclaration (P.showIdent ident') (convertComments com) (Just ss) (ChildTypeClassMember (ty $> ())) - convertClassMember _ = - P.internalError "convertDeclaration: Invalid argument to convertClassMember." + mkTypeClassDeclaration sa args implies fundeps ds P.TypeInstanceDeclaration (ss, com) _ _ _ constraints className tys _ -> Just (Left ((classNameString, AugmentClass) : map (, AugmentType) typeNameStrings, AugmentChild childDecl)) where @@ -165,6 +151,30 @@ convertDeclaration title = \case Just . Right $ mkDeclaration sa title (AliasDeclaration fixity (P.Qualified mn (Left alias))) _ -> Nothing + where + mkDataDeclaration sa dtype args ctors = + Just (Right (mkDeclaration sa title info) { declChildren = children }) + where + info = DataDeclaration dtype (fmap (fmap (fmap ($> ()))) args) + children = map convertCtor ctors + convertCtor :: P.DataConstructorDeclaration -> ChildDeclaration + convertCtor P.DataConstructorDeclaration{..} = + ChildDeclaration (P.runProperName dataCtorName) (convertComments $ snd dataCtorAnn) Nothing (ChildDataConstructor (fmap (($> ()) . snd) dataCtorFields)) + + mkTypeSynonymDeclaration sa args ty = + basicDeclaration sa title (TypeSynonymDeclaration (fmap (fmap (fmap ($> ()))) args) (ty $> ())) + + mkTypeClassDeclaration sa args implies fundeps ds = + Just (Right (mkDeclaration sa title info) { declChildren = children }) + where + args' = fmap (fmap (fmap ($> ()))) args + info = TypeClassDeclaration args' (fmap ($> ()) implies) (convertFundepsToStrings args' fundeps) + children = map convertClassMember ds + convertClassMember (P.TypeDeclaration (P.TypeDeclarationData (ss, com) ident' ty)) = + ChildDeclaration (P.showIdent ident') (convertComments com) (Just ss) (ChildTypeClassMember (ty $> ())) + convertClassMember _ = + P.internalError "convertDeclaration: Invalid argument to convertClassMember." + convertComments :: [P.Comment] -> Maybe Text convertComments cs = do let raw = concatMap toLines cs From ffccc38c6f04aa47c97b2182fd71160157d2b6ba Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 9 Jun 2021 06:43:35 -0700 Subject: [PATCH 05/33] Render kind signatures and comments in docs --- .../Language/PureScript/AST/Declarations.hs | 31 +++- .../src/Language/PureScript/AST/Exported.hs | 38 +++++ src/Language/PureScript/Docs/AsHtml.hs | 5 +- .../PureScript/Docs/Convert/ReExports.hs | 1 + .../PureScript/Docs/Convert/Single.hs | 135 ++++++++++++------ src/Language/PureScript/Docs/Prim.hs | 2 + src/Language/PureScript/Docs/Render.hs | 10 ++ .../PureScript/Docs/RenderedCode/Types.hs | 9 ++ src/Language/PureScript/Docs/Types.hs | 35 +++++ 9 files changed, 219 insertions(+), 47 deletions(-) diff --git a/lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs b/lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs index e2ed1e2bd8..dee23cf940 100644 --- a/lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs +++ b/lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs @@ -473,7 +473,16 @@ data KindSignatureFor | NewtypeSig | TypeSynonymSig | ClassSig - deriving (Eq, Ord, Show) + deriving (Eq, Ord, Show, Generic) + +instance NFData KindSignatureFor + +kindSignatureForKeyword :: KindSignatureFor -> Text +kindSignatureForKeyword = \case + DataSig -> "data" + NewtypeSig -> "newtype" + TypeSynonymSig -> "type" + ClassSig -> "class" declSourceAnn :: Declaration -> SourceAnn declSourceAnn (DataDeclaration sa _ _ _ _) = sa @@ -513,6 +522,26 @@ declName KindDeclaration{} = Nothing declName TypeDeclaration{} = Nothing declName RoleDeclaration{} = Nothing +-- | Same as @declName@ except that KindDeclaration's names +-- are also included +declDocName :: Declaration -> Maybe Name +declDocName (DataDeclaration _ _ n _ _) = Just (TyName n) +declDocName (TypeSynonymDeclaration _ n _ _) = Just (TyName n) +declDocName (ValueDeclaration vd) = Just (IdentName (valdeclIdent vd)) +declDocName (ExternDeclaration _ n _) = Just (IdentName n) +declDocName (ExternDataDeclaration _ n _) = Just (TyName n) +declDocName (FixityDeclaration _ (Left (ValueFixity _ _ n))) = Just (ValOpName n) +declDocName (FixityDeclaration _ (Right (TypeFixity _ _ n))) = Just (TyOpName n) +declDocName (TypeClassDeclaration _ n _ _ _ _) = Just (TyClassName n) +declDocName (TypeInstanceDeclaration _ _ _ n _ _ _ _) = IdentName <$> hush n +declDocName (KindDeclaration _ _ n _) = Just (TyName n) +declDocName ImportDeclaration{} = Nothing +declDocName BindingGroupDeclaration{} = Nothing +declDocName DataBindingGroupDeclaration{} = Nothing +declDocName BoundValueDeclaration{} = Nothing +declDocName TypeDeclaration{} = Nothing +declDocName RoleDeclaration{} = Nothing + -- | -- Test if a declaration is a value declaration -- diff --git a/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs b/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs index 60c860cf8d..c7369cfaf1 100644 --- a/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs +++ b/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs @@ -1,5 +1,6 @@ module Language.PureScript.AST.Exported ( exportedDeclarations + , exportedDocumentedDeclarations , isExported ) where @@ -9,6 +10,7 @@ import Protolude (sortOn) import Control.Category ((>>>)) import Data.Maybe (mapMaybe) +import Data.Foldable (foldl') import qualified Data.Map as M import Language.PureScript.AST.Declarations @@ -39,6 +41,29 @@ exportedDeclarations (Module _ _ mn decls exps) = go decls >>> filterInstances mn exps >>> maybe id reorder exps +-- | This function is intended to be used solely for creating a module's +-- documentation. It functions exactly like @exportedDeclarations@, +-- except that @KindDeclaration@s are also exported if the corresponding +-- declaration is exported. +exportedDocumentedDeclarations :: Module -> [Declaration] +exportedDocumentedDeclarations (Module _ _ mn decls exps) = go decls + where + go = flattenDecls + >>> reverse . snd . foldl' (f exps) (Nothing, []) + >>> map (filterDataConstructors exps) + >>> filterInstances mn exps + >>> maybe id reorderForDocs exps + + f :: Maybe [DeclarationRef] -> (Maybe Declaration, [Declaration]) -> Declaration -> (Maybe Declaration, [Declaration]) + f _ (_, ls) d@KindDeclaration{} = (Just d, ls) + f Nothing (_, ls) d = (Nothing, d : ls) + f _ (_, ls) d@TypeInstanceDeclaration{} = (Nothing, d : ls) + f (Just exps') (ks, ls) d + | any matches exps' = (Nothing, maybe (d : ls) (\kd -> d : kd : ls) ks) + | otherwise = (Nothing, ls) + where + matches declRef = declName d == Just (declRefName declRef) + -- | -- Filter out all data constructors from a declaration which are not exported. -- If the supplied declaration is not a data declaration, this function returns @@ -154,3 +179,16 @@ reorder refs = M.fromList $ zip (map declRefName refs) [(0::Int)..] refIndex decl = declName decl >>= flip M.lookup refIndices + +-- | +-- Same as @reorder@ except KindDeclarations are included +-- when reordering +-- +reorderForDocs :: [DeclarationRef] -> [Declaration] -> [Declaration] +reorderForDocs refs = + sortOn refIndex + where + refIndices = + M.fromList $ zip (map declRefName refs) [(0::Int)..] + refIndex decl = + declDocName decl >>= flip M.lookup refIndices diff --git a/src/Language/PureScript/Docs/AsHtml.hs b/src/Language/PureScript/Docs/AsHtml.hs index 884b89d2bf..2f649135c3 100644 --- a/src/Language/PureScript/Docs/AsHtml.hs +++ b/src/Language/PureScript/Docs/AsHtml.hs @@ -145,7 +145,10 @@ declAsHtml r d@Declaration{..} = do case declInfo of AliasDeclaration fixity alias_ -> renderAlias fixity alias_ - _ -> + _ -> do + for_ declKind $ \kindInfo -> do + pre ! A.class_ "decl__signature" $ code $ + codeAsHtml r (Render.renderKindSig declTitle kindInfo) pre ! A.class_ "decl__signature" $ code $ codeAsHtml r (Render.renderDeclaration d) diff --git a/src/Language/PureScript/Docs/Convert/ReExports.hs b/src/Language/PureScript/Docs/Convert/ReExports.hs index 462f515bd4..e308c556ef 100644 --- a/src/Language/PureScript/Docs/Convert/ReExports.hs +++ b/src/Language/PureScript/Docs/Convert/ReExports.hs @@ -434,6 +434,7 @@ handleEnv TypeClassEnv{..} = , declSourceSpan = cdeclSourceSpan , declChildren = [] , declInfo = ValueDeclaration (addConstraint constraint typ) + , declKind = Nothing } _ -> internalErrorInModule diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index 3358d8c06a..30385830ca 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -27,9 +27,10 @@ convertSingleModule m@(P.Module _ coms moduleName _ _) = where comments = convertComments coms declarations = - P.exportedDeclarations + P.exportedDocumentedDeclarations + >>> (reverse . snd . foldl' reassociateKindSignatures (Nothing, [])) >>> mapMaybe (\d -> do - title <- getDeclarationTitle d + title <- either (getDeclarationTitle . snd) getDeclarationTitle d convertDeclaration title d ) >>> augmentDeclarations @@ -103,70 +104,114 @@ getDeclarationTitle (P.ValueFixityDeclaration _ _ _ op) = Just (P.showOp op) getDeclarationTitle _ = Nothing -- | Create a basic Declaration value. -mkDeclaration :: P.SourceAnn -> Text -> DeclarationInfo -> Declaration -mkDeclaration (ss, com) title info = +mkDeclaration :: P.SourceAnn -> Text -> Maybe KindInfo -> DeclarationInfo -> Declaration +mkDeclaration (ss, com) title kindInfo info = Declaration { declTitle = title , declComments = convertComments com , declSourceSpan = Just ss -- TODO: make this non-optional when we next break the format , declChildren = [] , declInfo = info + , declKind = kindInfo } basicDeclaration :: P.SourceAnn -> Text -> DeclarationInfo -> Maybe IntermediateDeclaration -basicDeclaration sa title = Just . Right . mkDeclaration sa title +basicDeclaration sa title = Just . Right . mkDeclaration sa title Nothing + +reassociateKindSignatures + :: (Maybe P.Declaration, [Either (P.Declaration, P.Declaration) P.Declaration]) + -> P.Declaration + -> (Maybe P.Declaration, [Either (P.Declaration, P.Declaration) P.Declaration]) +reassociateKindSignatures (ks, ls) = \case + d@P.KindDeclaration{} -> (Just d, ls) + d@P.DataDeclaration{} -> (Nothing, storeKindSig d) + d@P.TypeSynonymDeclaration{} -> (Nothing, storeKindSig d) + d@P.TypeClassDeclaration{} -> (Nothing, storeKindSig d) + d -> (Nothing, Right d : ls) + where + storeKindSig d = + maybe (Right d : ls) (\kDecl -> Left (kDecl, d) : ls) ks -convertDeclaration :: Text -> P.Declaration -> Maybe IntermediateDeclaration +convertDeclaration + :: Text + -> Either (P.Declaration, P.Declaration) P.Declaration + -> Maybe IntermediateDeclaration convertDeclaration title = \case - P.ValueDecl sa _ _ _ [P.MkUnguarded (P.TypedValue _ _ ty)] -> - basicDeclaration sa title (ValueDeclaration (ty $> ())) - P.ValueDecl sa _ _ _ _ -> - -- If no explicit type declaration was provided, insert a wildcard, so that - -- the actual type will be added during type checking. - basicDeclaration sa title (ValueDeclaration (P.TypeWildcard () Nothing)) - P.ExternDeclaration sa _ ty -> - basicDeclaration sa title (ValueDeclaration (ty $> ())) - P.DataDeclaration sa dtype _ args ctors -> - mkDataDeclaration sa dtype args ctors - P.ExternDataDeclaration sa _ kind' -> - basicDeclaration sa title (ExternDataDeclaration (kind' $> ())) - P.TypeSynonymDeclaration sa _ args ty -> - mkTypeSynonymDeclaration sa args ty - P.TypeClassDeclaration sa _ args implies fundeps ds -> - mkTypeClassDeclaration sa args implies fundeps ds - P.TypeInstanceDeclaration (ss, com) _ _ _ constraints className tys _ -> - Just (Left ((classNameString, AugmentClass) : map (, AugmentType) typeNameStrings, AugmentChild childDecl)) - where - classNameString = unQual className - typeNameStrings = ordNub (concatMap (P.everythingOnTypes (++) extractProperNames) tys) - unQual x = let (P.Qualified _ y) = x in P.runProperName y - - extractProperNames (P.TypeConstructor _ n) = [unQual n] - extractProperNames _ = [] - - childDecl = ChildDeclaration title (convertComments com) (Just ss) (ChildInstance (fmap ($> ()) constraints) (classApp $> ())) - classApp = foldl' P.srcTypeApp (P.srcTypeConstructor (fmap P.coerceProperName className)) tys - P.ValueFixityDeclaration sa fixity (P.Qualified mn alias) _ -> - Just . Right $ mkDeclaration sa title (AliasDeclaration fixity (P.Qualified mn (Right alias))) - P.TypeFixityDeclaration sa fixity (P.Qualified mn alias) _ -> - Just . Right $ mkDeclaration sa title (AliasDeclaration fixity (P.Qualified mn (Left alias))) - _ -> Nothing + Left (kd@P.KindDeclaration{}, decl) -> do + let kindDecl = Just kd + case decl of + P.DataDeclaration sa dtype _ args ctors -> + mkDataDeclaration kindDecl sa dtype args ctors + + P.TypeSynonymDeclaration sa _ args ty -> + mkTypeSynonymDeclaration kindDecl sa args ty + + P.TypeClassDeclaration sa _ args implies fundeps ds -> + mkTypeClassDeclaration kindDecl sa args implies fundeps ds + + _ -> P.internalError "convertDeclarationWithKindSig: something other than data/type/newtype/class declarations stored in Tuple's second entry" + + Left (_, _) -> P.internalError "convertDeclarationWithKindSig: something other than KindDeclaration stored in Tuple's first entry" + Right decl -> case decl of + P.ValueDecl sa _ _ _ [P.MkUnguarded (P.TypedValue _ _ ty)] -> + basicDeclaration sa title (ValueDeclaration (ty $> ())) + P.ValueDecl sa _ _ _ _ -> + -- If no explicit type declaration was provided, insert a wildcard, so that + -- the actual type will be added during type checking. + basicDeclaration sa title (ValueDeclaration (P.TypeWildcard () Nothing)) + P.ExternDeclaration sa _ ty -> + basicDeclaration sa title (ValueDeclaration (ty $> ())) + P.DataDeclaration sa dtype _ args ctors -> + mkDataDeclaration Nothing sa dtype args ctors + P.ExternDataDeclaration sa _ kind' -> + basicDeclaration sa title (ExternDataDeclaration (kind' $> ())) + P.TypeSynonymDeclaration sa _ args ty -> + mkTypeSynonymDeclaration Nothing sa args ty + P.TypeClassDeclaration sa _ args implies fundeps ds -> + mkTypeClassDeclaration Nothing sa args implies fundeps ds + P.TypeInstanceDeclaration (ss, com) _ _ _ constraints className tys _ -> + Just (Left ((classNameString, AugmentClass) : map (, AugmentType) typeNameStrings, AugmentChild childDecl)) + where + classNameString = unQual className + typeNameStrings = ordNub (concatMap (P.everythingOnTypes (++) extractProperNames) tys) + unQual x = let (P.Qualified _ y) = x in P.runProperName y + + extractProperNames (P.TypeConstructor _ n) = [unQual n] + extractProperNames _ = [] + + childDecl = ChildDeclaration title (convertComments com) (Just ss) (ChildInstance (fmap ($> ()) constraints) (classApp $> ())) + classApp = foldl' P.srcTypeApp (P.srcTypeConstructor (fmap P.coerceProperName className)) tys + P.ValueFixityDeclaration sa fixity (P.Qualified mn alias) _ -> + Just . Right $ mkDeclaration sa title Nothing (AliasDeclaration fixity (P.Qualified mn (Right alias))) + P.TypeFixityDeclaration sa fixity (P.Qualified mn alias) _ -> + Just . Right $ mkDeclaration sa title Nothing (AliasDeclaration fixity (P.Qualified mn (Left alias))) + _ -> Nothing where - mkDataDeclaration sa dtype args ctors = - Just (Right (mkDeclaration sa title info) { declChildren = children }) + mkKindSig ann@(sa, comments) = \case + Just (P.KindDeclaration (_, commentsK) kindSig _ ty) -> + ((sa, commentsK ++ comments), Just (KindInfo kindSig (ty $> ()))) + _ -> (ann, Nothing) + + mkDataDeclaration kindDecl sa dtype args ctors = + Just (Right (mkDeclaration sa' title kindSig info) { declChildren = children }) where + (sa', kindSig) = mkKindSig sa kindDecl info = DataDeclaration dtype (fmap (fmap (fmap ($> ()))) args) children = map convertCtor ctors convertCtor :: P.DataConstructorDeclaration -> ChildDeclaration convertCtor P.DataConstructorDeclaration{..} = ChildDeclaration (P.runProperName dataCtorName) (convertComments $ snd dataCtorAnn) Nothing (ChildDataConstructor (fmap (($> ()) . snd) dataCtorFields)) - mkTypeSynonymDeclaration sa args ty = - basicDeclaration sa title (TypeSynonymDeclaration (fmap (fmap (fmap ($> ()))) args) (ty $> ())) + mkTypeSynonymDeclaration kindDecl sa args ty = + Just $ Right $ mkDeclaration sa' title kindSig info + where + (sa', kindSig) = mkKindSig sa kindDecl + info = TypeSynonymDeclaration (fmap (fmap (fmap ($> ()))) args) (ty $> ()) - mkTypeClassDeclaration sa args implies fundeps ds = - Just (Right (mkDeclaration sa title info) { declChildren = children }) + mkTypeClassDeclaration kindDecl sa args implies fundeps ds = + Just (Right (mkDeclaration sa' title kindSig info) { declChildren = children }) where + (sa', kindSig) = mkKindSig sa kindDecl args' = fmap (fmap (fmap ($> ()))) args info = TypeClassDeclaration args' (fmap ($> ()) implies) (convertFundepsToStrings args' fundeps) children = map convertClassMember ds diff --git a/src/Language/PureScript/Docs/Prim.hs b/src/Language/PureScript/Docs/Prim.hs index 3afa0cebf1..bf6b9f2afe 100644 --- a/src/Language/PureScript/Docs/Prim.hs +++ b/src/Language/PureScript/Docs/Prim.hs @@ -183,6 +183,7 @@ primTypeOf gen title comments = Declaration , declSourceSpan = Nothing , declChildren = [] , declInfo = ExternDataDeclaration (lookupPrimTypeKindOf gen title) + , declKind = Nothing } -- | Lookup the TypeClassData of a Prim class. This function is specifically @@ -214,6 +215,7 @@ primClassOf gen title comments = Declaration fundeps = convertFundepsToStrings args (P.typeClassDependencies tcd) in TypeClassDeclaration args superclasses fundeps + , declKind = Nothing } kindType :: Declaration diff --git a/src/Language/PureScript/Docs/Render.hs b/src/Language/PureScript/Docs/Render.hs index a4c0104c47..37097b5d64 100644 --- a/src/Language/PureScript/Docs/Render.hs +++ b/src/Language/PureScript/Docs/Render.hs @@ -20,10 +20,20 @@ import Language.PureScript.Docs.Types import Language.PureScript.Docs.Utils.MonoidExtras import qualified Language.PureScript.AST as P +import Language.PureScript.AST.Declarations (kindSignatureForKeyword) import qualified Language.PureScript.Environment as P import qualified Language.PureScript.Names as P import qualified Language.PureScript.Types as P +renderKindSig :: Text -> KindInfo -> RenderedCode +renderKindSig declTitle (KindInfo ks ty) = + mintersperse sp + [ keyword $ kindSignatureForKeyword ks + , renderType (P.TypeConstructor () (notQualified declTitle)) + , syntax "::" + , renderType ty + ] + renderDeclaration :: Declaration -> RenderedCode renderDeclaration Declaration{..} = mintersperse sp $ case declInfo of diff --git a/src/Language/PureScript/Docs/RenderedCode/Types.hs b/src/Language/PureScript/Docs/RenderedCode/Types.hs index 377858bf9d..7e7f2e0e0d 100644 --- a/src/Language/PureScript/Docs/RenderedCode/Types.hs +++ b/src/Language/PureScript/Docs/RenderedCode/Types.hs @@ -30,6 +30,7 @@ module Language.PureScript.Docs.RenderedCode.Types , keywordFixity , keywordKind , keywordAs + , kindSignatureFor , ident , dataCtor , typeCtor @@ -54,6 +55,7 @@ import qualified Data.Text.Encoding as TE import Language.PureScript.Names import Language.PureScript.AST (Associativity(..)) +import qualified Language.PureScript.AST.Declarations as P -- | Given a list of actions, attempt them all, returning the first success. -- If all the actions fail, 'tryAll' returns the first argument. @@ -307,6 +309,13 @@ keywordKind = keyword "kind" keywordAs :: RenderedCode keywordAs = keyword "as" +kindSignatureFor :: P.KindSignatureFor -> RenderedCode +kindSignatureFor = \case + P.DataSig -> keywordData + P.NewtypeSig -> keywordNewtype + P.TypeSynonymSig -> keywordType + P.ClassSig -> keywordClass + ident :: Qualified Ident -> RenderedCode ident (fromQualified -> (mn, name)) = RC [Symbol ValueLevel (runIdent name) (Link mn)] diff --git a/src/Language/PureScript/Docs/Types.hs b/src/Language/PureScript/Docs/Types.hs index 6dfc30cf4d..ec455b1977 100644 --- a/src/Language/PureScript/Docs/Types.hs +++ b/src/Language/PureScript/Docs/Types.hs @@ -132,6 +132,7 @@ data Declaration = Declaration , declSourceSpan :: Maybe P.SourceSpan , declChildren :: [ChildDeclaration] , declInfo :: DeclarationInfo + , declKind :: Maybe KindInfo } deriving (Show, Eq, Ord, Generic) @@ -184,6 +185,15 @@ data DeclarationInfo instance NFData DeclarationInfo +-- | +-- Wraps enough information to properly render the kind signature +-- of a data/newtype/type/class declaration. +data KindInfo + = KindInfo P.KindSignatureFor Type' + deriving (Show, Eq, Ord, Generic) + +instance NFData KindInfo + convertFundepsToStrings :: [(Text, Maybe Type')] -> [P.FunctionalDependency] -> [([Text], [Text])] convertFundepsToStrings args fundeps = map (\(P.FunctionalDependency from to) -> toArgs from to) fundeps @@ -347,6 +357,7 @@ data PackageError | InvalidFixity | InvalidKind Text | InvalidDataDeclType Text + | InvalidKindSignatureFor Text | InvalidTime deriving (Show, Eq, Ord, Generic) @@ -530,6 +541,8 @@ displayPackageError e = case e of "Invalid kind: \"" <> str <> "\"" InvalidDataDeclType str -> "Invalid data declaration type: \"" <> str <> "\"" + InvalidKindSignatureFor str -> + "Invalid kind signature keyword: \"" <> str <> "\"" InvalidTime -> "Invalid time" @@ -560,6 +573,7 @@ asDeclaration = <*> key "sourceSpan" (perhaps asSourceSpan) <*> key "children" (eachInArray asChildDeclaration) <*> key "info" asDeclarationInfo + <*> keyOrDefault "kind" Nothing (Just <$> asKindInfo) asReExport :: Parse PackageError (InPackage P.ModuleName, [Declaration]) asReExport = @@ -631,6 +645,20 @@ asDeclarationInfo = do other -> throwCustomError (InvalidDeclarationType other) +asKindInfo :: Parse PackageError KindInfo +asKindInfo = + KindInfo <$> key "keyword" asKindSignatureFor + <*> key "ty" asType + +asKindSignatureFor :: Parse PackageError P.KindSignatureFor +asKindSignatureFor = + withText $ \case + "data" -> Right P.DataSig + "newtype" -> Right P.NewtypeSig + "class" -> Right P.ClassSig + "type" -> Right P.TypeSynonymSig + x -> Left (InvalidKindSignatureFor x) + asTypeArguments :: Parse PackageError [(Text, Maybe Type')] asTypeArguments = eachInArray asTypeArgument where @@ -777,8 +805,15 @@ instance A.ToJSON Declaration where , "sourceSpan" .= declSourceSpan , "children" .= declChildren , "info" .= declInfo + , "kind" .= declKind ] +instance A.ToJSON KindInfo where + toJSON (KindInfo kindFor ty) = + A.object [ "keyword" .= P.kindSignatureForKeyword kindFor + , "ty" .= ty + ] + instance A.ToJSON ChildDeclaration where toJSON ChildDeclaration{..} = A.object [ "title" .= cdeclTitle From d0f46387c6b81f0be34f4ec4dace561ae1fa461a Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 15 Jun 2021 06:40:56 -0700 Subject: [PATCH 06/33] Fix type mismatch between object and null --- src/Language/PureScript/Docs/Types.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/PureScript/Docs/Types.hs b/src/Language/PureScript/Docs/Types.hs index ec455b1977..f071b01794 100644 --- a/src/Language/PureScript/Docs/Types.hs +++ b/src/Language/PureScript/Docs/Types.hs @@ -573,7 +573,7 @@ asDeclaration = <*> key "sourceSpan" (perhaps asSourceSpan) <*> key "children" (eachInArray asChildDeclaration) <*> key "info" asDeclarationInfo - <*> keyOrDefault "kind" Nothing (Just <$> asKindInfo) + <*> keyOrDefault "kind" Nothing (perhaps asKindInfo) asReExport :: Parse PackageError (InPackage P.ModuleName, [Declaration]) asReExport = From ac4f1d1c94f681915b8e93f0622a7f859258ef13 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 15 Jun 2021 17:49:09 -0700 Subject: [PATCH 07/33] Check both versions of a kind declaration's name --- .../src/Language/PureScript/AST/Exported.hs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs b/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs index c7369cfaf1..66b1466d91 100644 --- a/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs +++ b/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs @@ -8,6 +8,7 @@ import Prelude.Compat import Protolude (sortOn) import Control.Category ((>>>)) +import Control.Applicative ((<|>)) import Data.Maybe (mapMaybe) import Data.Foldable (foldl') @@ -190,5 +191,13 @@ reorderForDocs refs = where refIndices = M.fromList $ zip (map declRefName refs) [(0::Int)..] - refIndex decl = - declDocName decl >>= flip M.lookup refIndices + refIndex = \case + KindDeclaration _ _ n _ -> + M.lookup (TyName n) refIndices <|> M.lookup (TyClassName (tyToClassName n)) refIndices + decl -> declDocName decl >>= flip M.lookup refIndices + + -- Workaround to the fact that the kind's name's ProperNameType + -- isn't the same as the declaration's ProperNameType + -- when that declaration is a type class + tyToClassName :: ProperName 'TypeName -> ProperName 'ClassName + tyToClassName = coerceProperName From 2a6a7fc5d7fc5651435feca0ef0f0c7230e975d1 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 15 Jun 2021 17:59:14 -0700 Subject: [PATCH 08/33] Make small stylistic change for readability --- src/Language/PureScript/Docs/Convert/Single.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index 30385830ca..9be9b4b4fc 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -189,7 +189,9 @@ convertDeclaration title = \case where mkKindSig ann@(sa, comments) = \case Just (P.KindDeclaration (_, commentsK) kindSig _ ty) -> - ((sa, commentsK ++ comments), Just (KindInfo kindSig (ty $> ()))) + ( (sa, commentsK ++ comments) + , Just $ KindInfo kindSig (ty $> ()) + ) _ -> (ann, Nothing) mkDataDeclaration kindDecl sa dtype args ctors = From b82df5e352791104e63e392f2065479877f98a11 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 15 Jun 2021 17:59:41 -0700 Subject: [PATCH 09/33] Add a line separator between kind sig docs and data decl docs --- src/Language/PureScript/Docs/Convert/Single.hs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index 9be9b4b4fc..2c3fdbdfca 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -189,7 +189,10 @@ convertDeclaration title = \case where mkKindSig ann@(sa, comments) = \case Just (P.KindDeclaration (_, commentsK) kindSig _ ty) -> - ( (sa, commentsK ++ comments) + -- The `LineComment " | "` functionally adds a newline character + -- between the docs on the kind signature and the docs on + -- the declaration. + ( (sa, commentsK ++ P.LineComment " | " : comments) , Just $ KindInfo kindSig (ty $> ()) ) _ -> (ann, Nothing) From 25fb1964fdbb71e50b3ac2f5c6a559235e10d319 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 15 Jun 2021 18:07:54 -0700 Subject: [PATCH 10/33] Remove temporary duplicates of functions now that process works The temporary variants existed in case the functions were used elsewhere. I wasn't sure if changing their implementation might cause bugs elsewhere. --- .../Language/PureScript/AST/Declarations.hs | 23 ++----------- .../src/Language/PureScript/AST/Exported.hs | 33 +++---------------- .../PureScript/Docs/Convert/Single.hs | 2 +- 3 files changed, 8 insertions(+), 50 deletions(-) diff --git a/lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs b/lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs index dee23cf940..de9876dec0 100644 --- a/lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs +++ b/lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs @@ -504,6 +504,9 @@ declSourceAnn (TypeInstanceDeclaration sa _ _ _ _ _ _ _) = sa declSourceSpan :: Declaration -> SourceSpan declSourceSpan = fst . declSourceAnn +-- Note: Kind Declarations' names can refer to either a `TyClassName` +-- or a `TypeName`. Use a helper function for handling `KindDeclaration`s +-- specifically in the context in which it is needed. declName :: Declaration -> Maybe Name declName (DataDeclaration _ _ n _ _) = Just (TyName n) declName (TypeSynonymDeclaration _ n _ _) = Just (TyName n) @@ -522,26 +525,6 @@ declName KindDeclaration{} = Nothing declName TypeDeclaration{} = Nothing declName RoleDeclaration{} = Nothing --- | Same as @declName@ except that KindDeclaration's names --- are also included -declDocName :: Declaration -> Maybe Name -declDocName (DataDeclaration _ _ n _ _) = Just (TyName n) -declDocName (TypeSynonymDeclaration _ n _ _) = Just (TyName n) -declDocName (ValueDeclaration vd) = Just (IdentName (valdeclIdent vd)) -declDocName (ExternDeclaration _ n _) = Just (IdentName n) -declDocName (ExternDataDeclaration _ n _) = Just (TyName n) -declDocName (FixityDeclaration _ (Left (ValueFixity _ _ n))) = Just (ValOpName n) -declDocName (FixityDeclaration _ (Right (TypeFixity _ _ n))) = Just (TyOpName n) -declDocName (TypeClassDeclaration _ n _ _ _ _) = Just (TyClassName n) -declDocName (TypeInstanceDeclaration _ _ _ n _ _ _ _) = IdentName <$> hush n -declDocName (KindDeclaration _ _ n _) = Just (TyName n) -declDocName ImportDeclaration{} = Nothing -declDocName BindingGroupDeclaration{} = Nothing -declDocName DataBindingGroupDeclaration{} = Nothing -declDocName BoundValueDeclaration{} = Nothing -declDocName TypeDeclaration{} = Nothing -declDocName RoleDeclaration{} = Nothing - -- | -- Test if a declaration is a value declaration -- diff --git a/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs b/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs index 66b1466d91..37042e9fd9 100644 --- a/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs +++ b/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs @@ -1,6 +1,5 @@ module Language.PureScript.AST.Exported ( exportedDeclarations - , exportedDocumentedDeclarations , isExported ) where @@ -33,27 +32,16 @@ import Language.PureScript.Names -- list, unless there is no export list, in which case they appear in the same -- order as they do in the source file. -- +-- Kind signatures declarations are also exported if their associated +-- declaration is exported. exportedDeclarations :: Module -> [Declaration] exportedDeclarations (Module _ _ mn decls exps) = go decls - where - go = flattenDecls - >>> filter (isExported exps) - >>> map (filterDataConstructors exps) - >>> filterInstances mn exps - >>> maybe id reorder exps - --- | This function is intended to be used solely for creating a module's --- documentation. It functions exactly like @exportedDeclarations@, --- except that @KindDeclaration@s are also exported if the corresponding --- declaration is exported. -exportedDocumentedDeclarations :: Module -> [Declaration] -exportedDocumentedDeclarations (Module _ _ mn decls exps) = go decls where go = flattenDecls >>> reverse . snd . foldl' (f exps) (Nothing, []) >>> map (filterDataConstructors exps) >>> filterInstances mn exps - >>> maybe id reorderForDocs exps + >>> maybe id reorder exps f :: Maybe [DeclarationRef] -> (Maybe Declaration, [Declaration]) -> Declaration -> (Maybe Declaration, [Declaration]) f _ (_, ls) d@KindDeclaration{} = (Just d, ls) @@ -174,19 +162,6 @@ isDctorExported ident (Just exps) ctor = test `any` exps -- reorder :: [DeclarationRef] -> [Declaration] -> [Declaration] reorder refs = - sortOn refIndex - where - refIndices = - M.fromList $ zip (map declRefName refs) [(0::Int)..] - refIndex decl = - declName decl >>= flip M.lookup refIndices - --- | --- Same as @reorder@ except KindDeclarations are included --- when reordering --- -reorderForDocs :: [DeclarationRef] -> [Declaration] -> [Declaration] -reorderForDocs refs = sortOn refIndex where refIndices = @@ -194,7 +169,7 @@ reorderForDocs refs = refIndex = \case KindDeclaration _ _ n _ -> M.lookup (TyName n) refIndices <|> M.lookup (TyClassName (tyToClassName n)) refIndices - decl -> declDocName decl >>= flip M.lookup refIndices + decl -> declName decl >>= flip M.lookup refIndices -- Workaround to the fact that the kind's name's ProperNameType -- isn't the same as the declaration's ProperNameType diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index 2c3fdbdfca..64854af8bf 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -27,7 +27,7 @@ convertSingleModule m@(P.Module _ coms moduleName _ _) = where comments = convertComments coms declarations = - P.exportedDocumentedDeclarations + P.exportedDeclarations >>> (reverse . snd . foldl' reassociateKindSignatures (Nothing, [])) >>> mapMaybe (\d -> do title <- either (getDeclarationTitle . snd) getDeclarationTitle d From dcb754b71f09e0ed6848ed35ea020a3519c10d3d Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 16 Jun 2021 06:18:41 -0700 Subject: [PATCH 11/33] Only add newline separator between comments if both are non-empty --- src/Language/PureScript/Docs/Convert/Single.hs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index 64854af8bf..dee8df87ec 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -187,14 +187,19 @@ convertDeclaration title = \case _ -> Nothing where - mkKindSig ann@(sa, comments) = \case - Just (P.KindDeclaration (_, commentsK) kindSig _ ty) -> - -- The `LineComment " | "` functionally adds a newline character - -- between the docs on the kind signature and the docs on - -- the declaration. - ( (sa, commentsK ++ P.LineComment " | " : comments) + mkKindSig ann@(sa, declComments) = \case + Just (P.KindDeclaration (_, ksComments) kindSig _ ty) -> + ( (sa, mergeComments ksComments declComments) , Just $ KindInfo kindSig (ty $> ()) ) + where + -- The `LineComment " | "` functionally adds a newline character + -- between the docs on the kind signature and the docs on + -- the declaration, but only if both declarations + -- have comments. + mergeComments ks [] = ks + mergeComments [] decl = decl + mergeComments ks decl = ks ++ P.LineComment " | " : decl _ -> (ann, Nothing) mkDataDeclaration kindDecl sa dtype args ctors = From e7996c1731713d52ef873adecb7581b62fe04391 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 16 Jun 2021 13:30:50 -0700 Subject: [PATCH 12/33] Move kindSignatureForKeyword into Docs.Types --- .../src/Language/PureScript/AST/Declarations.hs | 7 ------- src/Language/PureScript/Docs/Render.hs | 1 - src/Language/PureScript/Docs/Types.hs | 9 ++++++++- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs b/lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs index de9876dec0..c2d0c85d86 100644 --- a/lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs +++ b/lib/purescript-cst/src/Language/PureScript/AST/Declarations.hs @@ -477,13 +477,6 @@ data KindSignatureFor instance NFData KindSignatureFor -kindSignatureForKeyword :: KindSignatureFor -> Text -kindSignatureForKeyword = \case - DataSig -> "data" - NewtypeSig -> "newtype" - TypeSynonymSig -> "type" - ClassSig -> "class" - declSourceAnn :: Declaration -> SourceAnn declSourceAnn (DataDeclaration sa _ _ _ _) = sa declSourceAnn (DataBindingGroupDeclaration ds) = declSourceAnn (NEL.head ds) diff --git a/src/Language/PureScript/Docs/Render.hs b/src/Language/PureScript/Docs/Render.hs index 37097b5d64..37beaebe07 100644 --- a/src/Language/PureScript/Docs/Render.hs +++ b/src/Language/PureScript/Docs/Render.hs @@ -20,7 +20,6 @@ import Language.PureScript.Docs.Types import Language.PureScript.Docs.Utils.MonoidExtras import qualified Language.PureScript.AST as P -import Language.PureScript.AST.Declarations (kindSignatureForKeyword) import qualified Language.PureScript.Environment as P import qualified Language.PureScript.Names as P import qualified Language.PureScript.Types as P diff --git a/src/Language/PureScript/Docs/Types.hs b/src/Language/PureScript/Docs/Types.hs index f071b01794..6b074ae0b4 100644 --- a/src/Language/PureScript/Docs/Types.hs +++ b/src/Language/PureScript/Docs/Types.hs @@ -810,10 +810,17 @@ instance A.ToJSON Declaration where instance A.ToJSON KindInfo where toJSON (KindInfo kindFor ty) = - A.object [ "keyword" .= P.kindSignatureForKeyword kindFor + A.object [ "keyword" .= kindSignatureForKeyword kindFor , "ty" .= ty ] +kindSignatureForKeyword :: P.KindSignatureFor -> Text +kindSignatureForKeyword = \case + P.DataSig -> "data" + P.NewtypeSig -> "newtype" + P.TypeSynonymSig -> "type" + P.ClassSig -> "class" + instance A.ToJSON ChildDeclaration where toJSON ChildDeclaration{..} = A.object [ "title" .= cdeclTitle From ada16b69d69d6b45db1bd8c72e1e8ff54a4bd500 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 16 Jun 2021 13:31:25 -0700 Subject: [PATCH 13/33] Change KindInfo into record --- src/Language/PureScript/Docs/Convert/Single.hs | 2 +- src/Language/PureScript/Docs/Render.hs | 6 +++--- src/Language/PureScript/Docs/Types.hs | 12 +++++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index dee8df87ec..b872a4d119 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -190,7 +190,7 @@ convertDeclaration title = \case mkKindSig ann@(sa, declComments) = \case Just (P.KindDeclaration (_, ksComments) kindSig _ ty) -> ( (sa, mergeComments ksComments declComments) - , Just $ KindInfo kindSig (ty $> ()) + , Just $ KindInfo { kiKindSigFor = kindSig, kiType = ty $> () } ) where -- The `LineComment " | "` functionally adds a newline character diff --git a/src/Language/PureScript/Docs/Render.hs b/src/Language/PureScript/Docs/Render.hs index 37beaebe07..c79719e5a8 100644 --- a/src/Language/PureScript/Docs/Render.hs +++ b/src/Language/PureScript/Docs/Render.hs @@ -25,12 +25,12 @@ import qualified Language.PureScript.Names as P import qualified Language.PureScript.Types as P renderKindSig :: Text -> KindInfo -> RenderedCode -renderKindSig declTitle (KindInfo ks ty) = +renderKindSig declTitle KindInfo{..} = mintersperse sp - [ keyword $ kindSignatureForKeyword ks + [ keyword $ kindSignatureForKeyword kiKindSigFor , renderType (P.TypeConstructor () (notQualified declTitle)) , syntax "::" - , renderType ty + , renderType kiType ] renderDeclaration :: Declaration -> RenderedCode diff --git a/src/Language/PureScript/Docs/Types.hs b/src/Language/PureScript/Docs/Types.hs index 6b074ae0b4..d0f3f62d8b 100644 --- a/src/Language/PureScript/Docs/Types.hs +++ b/src/Language/PureScript/Docs/Types.hs @@ -188,8 +188,10 @@ instance NFData DeclarationInfo -- | -- Wraps enough information to properly render the kind signature -- of a data/newtype/type/class declaration. -data KindInfo - = KindInfo P.KindSignatureFor Type' +data KindInfo = KindInfo + { kiKindSigFor :: P.KindSignatureFor + , kiType :: Type' + } deriving (Show, Eq, Ord, Generic) instance NFData KindInfo @@ -809,9 +811,9 @@ instance A.ToJSON Declaration where ] instance A.ToJSON KindInfo where - toJSON (KindInfo kindFor ty) = - A.object [ "keyword" .= kindSignatureForKeyword kindFor - , "ty" .= ty + toJSON KindInfo{..} = + A.object [ "keyword" .= kindSignatureForKeyword kiKindSigFor + , "ty" .= kiType ] kindSignatureForKeyword :: P.KindSignatureFor -> Text From b381f41419dfa97537bbb87bca526c5ba1704a23 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 16 Jun 2021 13:58:55 -0700 Subject: [PATCH 14/33] Move tyToClassName into where cause under KindDeclaration path --- .../src/Language/PureScript/AST/Exported.hs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs b/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs index 37042e9fd9..852459024e 100644 --- a/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs +++ b/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs @@ -169,10 +169,11 @@ reorder refs = refIndex = \case KindDeclaration _ _ n _ -> M.lookup (TyName n) refIndices <|> M.lookup (TyClassName (tyToClassName n)) refIndices - decl -> declName decl >>= flip M.lookup refIndices + where + -- Workaround to the fact that the kind's name's ProperNameType + -- isn't the same as the declaration's ProperNameType + -- when that declaration is a type class + tyToClassName :: ProperName 'TypeName -> ProperName 'ClassName + tyToClassName = coerceProperName - -- Workaround to the fact that the kind's name's ProperNameType - -- isn't the same as the declaration's ProperNameType - -- when that declaration is a type class - tyToClassName :: ProperName 'TypeName -> ProperName 'ClassName - tyToClassName = coerceProperName + decl -> declName decl >>= flip M.lookup refIndices From 9f17caa1c6f57ffc55883d2c131f928ad788f92c Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 17 Jun 2021 05:44:40 -0700 Subject: [PATCH 15/33] Update isExported to include kind signatures via simpler approach --- .../src/Language/PureScript/AST/Exported.hs | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs b/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs index 852459024e..831149d8ef 100644 --- a/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs +++ b/lib/purescript-cst/src/Language/PureScript/AST/Exported.hs @@ -10,7 +10,6 @@ import Control.Category ((>>>)) import Control.Applicative ((<|>)) import Data.Maybe (mapMaybe) -import Data.Foldable (foldl') import qualified Data.Map as M import Language.PureScript.AST.Declarations @@ -38,21 +37,11 @@ exportedDeclarations :: Module -> [Declaration] exportedDeclarations (Module _ _ mn decls exps) = go decls where go = flattenDecls - >>> reverse . snd . foldl' (f exps) (Nothing, []) + >>> filter (isExported exps) >>> map (filterDataConstructors exps) >>> filterInstances mn exps >>> maybe id reorder exps - f :: Maybe [DeclarationRef] -> (Maybe Declaration, [Declaration]) -> Declaration -> (Maybe Declaration, [Declaration]) - f _ (_, ls) d@KindDeclaration{} = (Just d, ls) - f Nothing (_, ls) d = (Nothing, d : ls) - f _ (_, ls) d@TypeInstanceDeclaration{} = (Nothing, d : ls) - f (Just exps') (ks, ls) d - | any matches exps' = (Nothing, maybe (d : ls) (\kd -> d : kd : ls) ks) - | otherwise = (Nothing, ls) - where - matches declRef = declName d == Just (declRefName declRef) - -- | -- Filter out all data constructors from a declaration which are not exported. -- If the supplied declaration is not a data declaration, this function returns @@ -140,6 +129,11 @@ typeInstanceConstituents _ = [] isExported :: Maybe [DeclarationRef] -> Declaration -> Bool isExported Nothing _ = True isExported _ TypeInstanceDeclaration{} = True +isExported (Just exps) (KindDeclaration _ _ n _) = any matches exps + where + matches declRef = do + let refName = declRefName declRef + TyName n == refName || TyClassName (tyToClassName n) == refName isExported (Just exps) decl = any matches exps where matches declRef = declName decl == Just (declRefName declRef) @@ -169,11 +163,11 @@ reorder refs = refIndex = \case KindDeclaration _ _ n _ -> M.lookup (TyName n) refIndices <|> M.lookup (TyClassName (tyToClassName n)) refIndices - where - -- Workaround to the fact that the kind's name's ProperNameType - -- isn't the same as the declaration's ProperNameType - -- when that declaration is a type class - tyToClassName :: ProperName 'TypeName -> ProperName 'ClassName - tyToClassName = coerceProperName decl -> declName decl >>= flip M.lookup refIndices + +-- | +-- Workaround to the fact that a `KindDeclaration`'s name's `ProperNameType` +-- isn't the same as the corresponding `TypeClassDeclaration`'s `ProperNameType` +tyToClassName :: ProperName 'TypeName -> ProperName 'ClassName +tyToClassName = coerceProperName From 6e9aaa5c12a4000915f1d31dfeb95356be718891 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 17 Jun 2021 06:00:15 -0700 Subject: [PATCH 16/33] Revert convertDeclaration and use augment to add kind signature --- .../PureScript/Docs/Convert/Single.hs | 191 +++++++----------- 1 file changed, 71 insertions(+), 120 deletions(-) diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index b872a4d119..c212200870 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -28,11 +28,7 @@ convertSingleModule m@(P.Module _ coms moduleName _ _) = comments = convertComments coms declarations = P.exportedDeclarations - >>> (reverse . snd . foldl' reassociateKindSignatures (Nothing, [])) - >>> mapMaybe (\d -> do - title <- either (getDeclarationTitle . snd) getDeclarationTitle d - convertDeclaration title d - ) + >>> mapMaybe (\d -> getDeclarationTitle d >>= convertDeclaration d) >>> augmentDeclarations -- | Different declarations we can augment @@ -70,8 +66,13 @@ type IntermediateDeclaration -- since they appear at the top level in the AST, and since they might need to -- appear as children in two places (for example, if a data type defined in a -- module is an instance of a type class also defined in that module). +-- +-- The AugmentKindSig constructor allows us to add a kind signature +-- to its corresponding declaration. Comments for both declarations +-- are also merged together. data DeclarationAugment = AugmentChild ChildDeclaration + | AugmentKindSig (Maybe Text) P.KindSignatureFor Type' -- | Augment top-level declarations; the second pass. See the comments under -- the type synonym IntermediateDeclaration for more information. @@ -90,6 +91,15 @@ augmentDeclarations (partitionEithers -> (augments, toplevels)) = augmentWith (AugmentChild child) d = d { declChildren = declChildren d ++ [child] } + augmentWith (AugmentKindSig comms kindSig ty) d = + d { declComments = mergeComments comms $ declComments d + , declKind = Just $ KindInfo { kiKindSigFor = kindSig, kiType = ty } + } + where + mergeComments Nothing dc = dc + mergeComments kc Nothing = kc + mergeComments (Just kcoms) (Just dcoms) = + Just $ kcoms <> "\n" <> dcoms getDeclarationTitle :: P.Declaration -> Maybe Text getDeclarationTitle (P.ValueDeclaration vd) = Just (P.showIdent (P.valdeclIdent vd)) @@ -101,134 +111,75 @@ getDeclarationTitle (P.TypeClassDeclaration _ name _ _ _ _) = Just (P.runProperN getDeclarationTitle (P.TypeInstanceDeclaration _ _ _ name _ _ _ _) = Just $ either (const "") P.showIdent name getDeclarationTitle (P.TypeFixityDeclaration _ _ _ op) = Just ("type " <> P.showOp op) getDeclarationTitle (P.ValueFixityDeclaration _ _ _ op) = Just (P.showOp op) +getDeclarationTitle (P.KindDeclaration _ _ n _) = Just (P.runProperName n) getDeclarationTitle _ = Nothing -- | Create a basic Declaration value. -mkDeclaration :: P.SourceAnn -> Text -> Maybe KindInfo -> DeclarationInfo -> Declaration -mkDeclaration (ss, com) title kindInfo info = +mkDeclaration :: P.SourceAnn -> Text -> DeclarationInfo -> Declaration +mkDeclaration (ss, com) title info = Declaration { declTitle = title , declComments = convertComments com , declSourceSpan = Just ss -- TODO: make this non-optional when we next break the format , declChildren = [] , declInfo = info - , declKind = kindInfo + , declKind = Nothing -- kind sigs are added in augment pass } basicDeclaration :: P.SourceAnn -> Text -> DeclarationInfo -> Maybe IntermediateDeclaration -basicDeclaration sa title = Just . Right . mkDeclaration sa title Nothing - -reassociateKindSignatures - :: (Maybe P.Declaration, [Either (P.Declaration, P.Declaration) P.Declaration]) - -> P.Declaration - -> (Maybe P.Declaration, [Either (P.Declaration, P.Declaration) P.Declaration]) -reassociateKindSignatures (ks, ls) = \case - d@P.KindDeclaration{} -> (Just d, ls) - d@P.DataDeclaration{} -> (Nothing, storeKindSig d) - d@P.TypeSynonymDeclaration{} -> (Nothing, storeKindSig d) - d@P.TypeClassDeclaration{} -> (Nothing, storeKindSig d) - d -> (Nothing, Right d : ls) +basicDeclaration sa title = Just . Right . mkDeclaration sa title + +convertDeclaration :: P.Declaration -> Text -> Maybe IntermediateDeclaration +convertDeclaration (P.ValueDecl sa _ _ _ [P.MkUnguarded (P.TypedValue _ _ ty)]) title = + basicDeclaration sa title (ValueDeclaration (ty $> ())) +convertDeclaration (P.ValueDecl sa _ _ _ _) title = + -- If no explicit type declaration was provided, insert a wildcard, so that + -- the actual type will be added during type checking. + basicDeclaration sa title (ValueDeclaration (P.TypeWildcard () Nothing)) +convertDeclaration (P.ExternDeclaration sa _ ty) title = + basicDeclaration sa title (ValueDeclaration (ty $> ())) +convertDeclaration (P.DataDeclaration sa dtype _ args ctors) title = + Just (Right (mkDeclaration sa title info) { declChildren = children }) where - storeKindSig d = - maybe (Right d : ls) (\kDecl -> Left (kDecl, d) : ls) ks - -convertDeclaration - :: Text - -> Either (P.Declaration, P.Declaration) P.Declaration - -> Maybe IntermediateDeclaration -convertDeclaration title = \case - Left (kd@P.KindDeclaration{}, decl) -> do - let kindDecl = Just kd - case decl of - P.DataDeclaration sa dtype _ args ctors -> - mkDataDeclaration kindDecl sa dtype args ctors - - P.TypeSynonymDeclaration sa _ args ty -> - mkTypeSynonymDeclaration kindDecl sa args ty - - P.TypeClassDeclaration sa _ args implies fundeps ds -> - mkTypeClassDeclaration kindDecl sa args implies fundeps ds - - _ -> P.internalError "convertDeclarationWithKindSig: something other than data/type/newtype/class declarations stored in Tuple's second entry" - - Left (_, _) -> P.internalError "convertDeclarationWithKindSig: something other than KindDeclaration stored in Tuple's first entry" - Right decl -> case decl of - P.ValueDecl sa _ _ _ [P.MkUnguarded (P.TypedValue _ _ ty)] -> - basicDeclaration sa title (ValueDeclaration (ty $> ())) - P.ValueDecl sa _ _ _ _ -> - -- If no explicit type declaration was provided, insert a wildcard, so that - -- the actual type will be added during type checking. - basicDeclaration sa title (ValueDeclaration (P.TypeWildcard () Nothing)) - P.ExternDeclaration sa _ ty -> - basicDeclaration sa title (ValueDeclaration (ty $> ())) - P.DataDeclaration sa dtype _ args ctors -> - mkDataDeclaration Nothing sa dtype args ctors - P.ExternDataDeclaration sa _ kind' -> - basicDeclaration sa title (ExternDataDeclaration (kind' $> ())) - P.TypeSynonymDeclaration sa _ args ty -> - mkTypeSynonymDeclaration Nothing sa args ty - P.TypeClassDeclaration sa _ args implies fundeps ds -> - mkTypeClassDeclaration Nothing sa args implies fundeps ds - P.TypeInstanceDeclaration (ss, com) _ _ _ constraints className tys _ -> - Just (Left ((classNameString, AugmentClass) : map (, AugmentType) typeNameStrings, AugmentChild childDecl)) - where - classNameString = unQual className - typeNameStrings = ordNub (concatMap (P.everythingOnTypes (++) extractProperNames) tys) - unQual x = let (P.Qualified _ y) = x in P.runProperName y - - extractProperNames (P.TypeConstructor _ n) = [unQual n] - extractProperNames _ = [] - - childDecl = ChildDeclaration title (convertComments com) (Just ss) (ChildInstance (fmap ($> ()) constraints) (classApp $> ())) - classApp = foldl' P.srcTypeApp (P.srcTypeConstructor (fmap P.coerceProperName className)) tys - P.ValueFixityDeclaration sa fixity (P.Qualified mn alias) _ -> - Just . Right $ mkDeclaration sa title Nothing (AliasDeclaration fixity (P.Qualified mn (Right alias))) - P.TypeFixityDeclaration sa fixity (P.Qualified mn alias) _ -> - Just . Right $ mkDeclaration sa title Nothing (AliasDeclaration fixity (P.Qualified mn (Left alias))) - _ -> Nothing - + info = DataDeclaration dtype (fmap (fmap (fmap ($> ()))) args) + children = map convertCtor ctors + convertCtor :: P.DataConstructorDeclaration -> ChildDeclaration + convertCtor P.DataConstructorDeclaration{..} = + ChildDeclaration (P.runProperName dataCtorName) (convertComments $ snd dataCtorAnn) Nothing (ChildDataConstructor (fmap (($> ()) . snd) dataCtorFields)) +convertDeclaration (P.ExternDataDeclaration sa _ kind') title = + basicDeclaration sa title (ExternDataDeclaration (kind' $> ())) +convertDeclaration (P.TypeSynonymDeclaration sa _ args ty) title = + basicDeclaration sa title (TypeSynonymDeclaration (fmap (fmap (fmap ($> ()))) args) (ty $> ())) +convertDeclaration (P.TypeClassDeclaration sa _ args implies fundeps ds) title = + Just (Right (mkDeclaration sa title info) { declChildren = children }) + where + args' = fmap (fmap (fmap ($> ()))) args + info = TypeClassDeclaration args' (fmap ($> ()) implies) (convertFundepsToStrings args' fundeps) + children = map convertClassMember ds + convertClassMember (P.TypeDeclaration (P.TypeDeclarationData (ss, com) ident' ty)) = + ChildDeclaration (P.showIdent ident') (convertComments com) (Just ss) (ChildTypeClassMember (ty $> ())) + convertClassMember _ = + P.internalError "convertDeclaration: Invalid argument to convertClassMember." +convertDeclaration (P.TypeInstanceDeclaration (ss, com) _ _ _ constraints className tys _) title = + Just (Left ((classNameString, AugmentClass) : map (, AugmentType) typeNameStrings, AugmentChild childDecl)) + where + classNameString = unQual className + typeNameStrings = ordNub (concatMap (P.everythingOnTypes (++) extractProperNames) tys) + unQual x = let (P.Qualified _ y) = x in P.runProperName y + + extractProperNames (P.TypeConstructor _ n) = [unQual n] + extractProperNames _ = [] + + childDecl = ChildDeclaration title (convertComments com) (Just ss) (ChildInstance (fmap ($> ()) constraints) (classApp $> ())) + classApp = foldl' P.srcTypeApp (P.srcTypeConstructor (fmap P.coerceProperName className)) tys +convertDeclaration (P.ValueFixityDeclaration sa fixity (P.Qualified mn alias) _) title = + Just . Right $ mkDeclaration sa title (AliasDeclaration fixity (P.Qualified mn (Right alias))) +convertDeclaration (P.TypeFixityDeclaration sa fixity (P.Qualified mn alias) _) title = + Just . Right $ mkDeclaration sa title (AliasDeclaration fixity (P.Qualified mn (Left alias))) +convertDeclaration (P.KindDeclaration sa kindSig _ tys) title = + Just $ Left ([(title, AugmentType), (title, AugmentClass)], AugmentKindSig comms kindSig (tys $> ())) where - mkKindSig ann@(sa, declComments) = \case - Just (P.KindDeclaration (_, ksComments) kindSig _ ty) -> - ( (sa, mergeComments ksComments declComments) - , Just $ KindInfo { kiKindSigFor = kindSig, kiType = ty $> () } - ) - where - -- The `LineComment " | "` functionally adds a newline character - -- between the docs on the kind signature and the docs on - -- the declaration, but only if both declarations - -- have comments. - mergeComments ks [] = ks - mergeComments [] decl = decl - mergeComments ks decl = ks ++ P.LineComment " | " : decl - _ -> (ann, Nothing) - - mkDataDeclaration kindDecl sa dtype args ctors = - Just (Right (mkDeclaration sa' title kindSig info) { declChildren = children }) - where - (sa', kindSig) = mkKindSig sa kindDecl - info = DataDeclaration dtype (fmap (fmap (fmap ($> ()))) args) - children = map convertCtor ctors - convertCtor :: P.DataConstructorDeclaration -> ChildDeclaration - convertCtor P.DataConstructorDeclaration{..} = - ChildDeclaration (P.runProperName dataCtorName) (convertComments $ snd dataCtorAnn) Nothing (ChildDataConstructor (fmap (($> ()) . snd) dataCtorFields)) - - mkTypeSynonymDeclaration kindDecl sa args ty = - Just $ Right $ mkDeclaration sa' title kindSig info - where - (sa', kindSig) = mkKindSig sa kindDecl - info = TypeSynonymDeclaration (fmap (fmap (fmap ($> ()))) args) (ty $> ()) - - mkTypeClassDeclaration kindDecl sa args implies fundeps ds = - Just (Right (mkDeclaration sa' title kindSig info) { declChildren = children }) - where - (sa', kindSig) = mkKindSig sa kindDecl - args' = fmap (fmap (fmap ($> ()))) args - info = TypeClassDeclaration args' (fmap ($> ()) implies) (convertFundepsToStrings args' fundeps) - children = map convertClassMember ds - convertClassMember (P.TypeDeclaration (P.TypeDeclarationData (ss, com) ident' ty)) = - ChildDeclaration (P.showIdent ident') (convertComments com) (Just ss) (ChildTypeClassMember (ty $> ())) - convertClassMember _ = - P.internalError "convertDeclaration: Invalid argument to convertClassMember." + comms = convertComments $ snd sa +convertDeclaration _ _ = Nothing convertComments :: [P.Comment] -> Maybe Text convertComments cs = do From 439354661f7581841ff850e38608dc5079ccde06 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 17 Jun 2021 12:38:40 -0700 Subject: [PATCH 17/33] Convert AugmentKind args into a record type: KindSignatureInfo --- src/Language/PureScript/Docs/Convert/Single.hs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index c212200870..74c6a0f445 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -72,7 +72,13 @@ type IntermediateDeclaration -- are also merged together. data DeclarationAugment = AugmentChild ChildDeclaration - | AugmentKindSig (Maybe Text) P.KindSignatureFor Type' + | AugmentKindSig KindSignatureInfo + +data KindSignatureInfo = KindSignatureInfo + { ksiComments :: Maybe Text + , ksiKindSignatureFor :: P.KindSignatureFor + , ksiType :: Type' + } -- | Augment top-level declarations; the second pass. See the comments under -- the type synonym IntermediateDeclaration for more information. @@ -91,9 +97,9 @@ augmentDeclarations (partitionEithers -> (augments, toplevels)) = augmentWith (AugmentChild child) d = d { declChildren = declChildren d ++ [child] } - augmentWith (AugmentKindSig comms kindSig ty) d = - d { declComments = mergeComments comms $ declComments d - , declKind = Just $ KindInfo { kiKindSigFor = kindSig, kiType = ty } + augmentWith (AugmentKindSig KindSignatureInfo{..}) d = + d { declComments = mergeComments ksiComments $ declComments d + , declKind = Just $ KindInfo { kiKindSigFor = ksiKindSignatureFor, kiType = ksiType } } where mergeComments Nothing dc = dc @@ -176,9 +182,10 @@ convertDeclaration (P.ValueFixityDeclaration sa fixity (P.Qualified mn alias) _) convertDeclaration (P.TypeFixityDeclaration sa fixity (P.Qualified mn alias) _) title = Just . Right $ mkDeclaration sa title (AliasDeclaration fixity (P.Qualified mn (Left alias))) convertDeclaration (P.KindDeclaration sa kindSig _ tys) title = - Just $ Left ([(title, AugmentType), (title, AugmentClass)], AugmentKindSig comms kindSig (tys $> ())) + Just $ Left ([(title, AugmentType), (title, AugmentClass)], AugmentKindSig ksi) where comms = convertComments $ snd sa + ksi = KindSignatureInfo { ksiComments = comms, ksiKindSignatureFor = kindSig, ksiType = tys $> () } convertDeclaration _ _ = Nothing convertComments :: [P.Comment] -> Maybe Text From 01f718e6afbc3f6103dbf8131e1dd1aefef83415 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 18 Jun 2021 05:12:45 -0700 Subject: [PATCH 18/33] Update changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f16116729d..36adc2ea32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ Bugfixes: * Ensure unnamed instances appear in documentation (#4109 by @JordanMartinez) +* Display kind signatures and their comments in documentation (#4100 by JordanMartinez) + Internal: * Fix for Haddock (#4072 by @ncaq and @JordanMartinez) From 64ba0149f701981297dfe155067bbfe508a93c9a Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 18 Jun 2021 06:34:19 -0700 Subject: [PATCH 19/33] Rename ty/Type to kind; change kindSignatureFor to keyword --- src/Language/PureScript/Docs/Convert/Single.hs | 10 +++++----- src/Language/PureScript/Docs/Render.hs | 4 ++-- src/Language/PureScript/Docs/Types.hs | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Language/PureScript/Docs/Convert/Single.hs b/src/Language/PureScript/Docs/Convert/Single.hs index 74c6a0f445..d27f5d971a 100644 --- a/src/Language/PureScript/Docs/Convert/Single.hs +++ b/src/Language/PureScript/Docs/Convert/Single.hs @@ -76,8 +76,8 @@ data DeclarationAugment data KindSignatureInfo = KindSignatureInfo { ksiComments :: Maybe Text - , ksiKindSignatureFor :: P.KindSignatureFor - , ksiType :: Type' + , ksiKeyword :: P.KindSignatureFor + , ksiKind :: Type' } -- | Augment top-level declarations; the second pass. See the comments under @@ -99,7 +99,7 @@ augmentDeclarations (partitionEithers -> (augments, toplevels)) = d { declChildren = declChildren d ++ [child] } augmentWith (AugmentKindSig KindSignatureInfo{..}) d = d { declComments = mergeComments ksiComments $ declComments d - , declKind = Just $ KindInfo { kiKindSigFor = ksiKindSignatureFor, kiType = ksiType } + , declKind = Just $ KindInfo { kiKeyword = ksiKeyword, kiKind = ksiKind } } where mergeComments Nothing dc = dc @@ -181,11 +181,11 @@ convertDeclaration (P.ValueFixityDeclaration sa fixity (P.Qualified mn alias) _) Just . Right $ mkDeclaration sa title (AliasDeclaration fixity (P.Qualified mn (Right alias))) convertDeclaration (P.TypeFixityDeclaration sa fixity (P.Qualified mn alias) _) title = Just . Right $ mkDeclaration sa title (AliasDeclaration fixity (P.Qualified mn (Left alias))) -convertDeclaration (P.KindDeclaration sa kindSig _ tys) title = +convertDeclaration (P.KindDeclaration sa keyword _ kind) title = Just $ Left ([(title, AugmentType), (title, AugmentClass)], AugmentKindSig ksi) where comms = convertComments $ snd sa - ksi = KindSignatureInfo { ksiComments = comms, ksiKindSignatureFor = kindSig, ksiType = tys $> () } + ksi = KindSignatureInfo { ksiComments = comms, ksiKeyword = keyword, ksiKind = kind $> () } convertDeclaration _ _ = Nothing convertComments :: [P.Comment] -> Maybe Text diff --git a/src/Language/PureScript/Docs/Render.hs b/src/Language/PureScript/Docs/Render.hs index c79719e5a8..fda917dfb5 100644 --- a/src/Language/PureScript/Docs/Render.hs +++ b/src/Language/PureScript/Docs/Render.hs @@ -27,10 +27,10 @@ import qualified Language.PureScript.Types as P renderKindSig :: Text -> KindInfo -> RenderedCode renderKindSig declTitle KindInfo{..} = mintersperse sp - [ keyword $ kindSignatureForKeyword kiKindSigFor + [ keyword $ kindSignatureForKeyword kiKeyword , renderType (P.TypeConstructor () (notQualified declTitle)) , syntax "::" - , renderType kiType + , renderType kiKind ] renderDeclaration :: Declaration -> RenderedCode diff --git a/src/Language/PureScript/Docs/Types.hs b/src/Language/PureScript/Docs/Types.hs index d0f3f62d8b..ee2aff8ea3 100644 --- a/src/Language/PureScript/Docs/Types.hs +++ b/src/Language/PureScript/Docs/Types.hs @@ -189,8 +189,8 @@ instance NFData DeclarationInfo -- Wraps enough information to properly render the kind signature -- of a data/newtype/type/class declaration. data KindInfo = KindInfo - { kiKindSigFor :: P.KindSignatureFor - , kiType :: Type' + { kiKeyword :: P.KindSignatureFor + , kiKind :: Type' } deriving (Show, Eq, Ord, Generic) @@ -650,7 +650,7 @@ asDeclarationInfo = do asKindInfo :: Parse PackageError KindInfo asKindInfo = KindInfo <$> key "keyword" asKindSignatureFor - <*> key "ty" asType + <*> key "kind" asType asKindSignatureFor :: Parse PackageError P.KindSignatureFor asKindSignatureFor = @@ -812,8 +812,8 @@ instance A.ToJSON Declaration where instance A.ToJSON KindInfo where toJSON KindInfo{..} = - A.object [ "keyword" .= kindSignatureForKeyword kiKindSigFor - , "ty" .= kiType + A.object [ "keyword" .= kindSignatureForKeyword kiKeyword + , "kind" .= kiKind ] kindSignatureForKeyword :: P.KindSignatureFor -> Text From cadc3ebe0f5caa49adb4535791f7b2a2a3709ddb Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 18 Jun 2021 12:44:00 -0700 Subject: [PATCH 20/33] Test that kind sigs appear in docs of declarations with kind sigs --- tests/TestDocs.hs | 36 +++++++++++++ tests/purs/docs/src/KindSignatureDocs.purs | 60 ++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 tests/purs/docs/src/KindSignatureDocs.purs diff --git a/tests/TestDocs.hs b/tests/TestDocs.hs index 0ff54b09ea..5dce872c6f 100644 --- a/tests/TestDocs.hs +++ b/tests/TestDocs.hs @@ -106,6 +106,8 @@ data DocsAssertion | ShouldHaveLink P.ModuleName Text Text Docs.Namespace Docs.LinkLocation -- | Assert that a given declaration comes before another in the output | ShouldComeBefore P.ModuleName Text Text + -- | Assert that a given declaration has a kind signature + | ShouldHaveKindSignature P.ModuleName Text data TagsAssertion -- | Assert that a particular declaration is tagged @@ -161,6 +163,8 @@ displayAssertion = \case ShouldComeBefore mn declA declB -> showQual mn declA <> " should come before " <> showQual mn declB <> " in the docs" + ShouldHaveKindSignature mn decl -> + showQual mn decl <> " should have a kind signature." displayTagsAssertion :: TagsAssertion -> Text displayTagsAssertion = \case @@ -215,6 +219,9 @@ data DocsAssertionFailure | BadLinkLocation P.ModuleName Text Text Docs.LinkLocation Docs.LinkLocation -- | Declarations were in the wrong order | WrongOrder P.ModuleName Text Text + -- | Expected a kind signature for a declaration, but did not find one + -- Fields: module name, declaration title. + | KindSignatureMissing P.ModuleName Text data TagsAssertionFailure -- | A declaration was not tagged, but should have been @@ -265,6 +272,8 @@ displayAssertionFailure = \case " got " <> T.pack (show actual) WrongOrder _ before' after' -> "expected to see " <> before' <> " before " <> after' + KindSignatureMissing _ decl -> + "the kind signature for " <> decl <> " is missing." displayTagsAssertionFailure :: TagsAssertionFailure -> Text displayTagsAssertionFailure = \case @@ -436,6 +445,11 @@ runAssertion assertion linksCtx Docs.Module{..} = (_, Nothing) -> Fail (NotDocumented mn after') + ShouldHaveKindSignature mn decl -> + findDeclKinds mn decl $ \case + Just _ -> Pass + Nothing -> Fail (KindSignatureMissing mn decl) + where declarationsFor mn = if mn == modName @@ -452,6 +466,13 @@ runAssertion assertion linksCtx Docs.Module{..} = Just decl -> f decl + findDeclKinds mn title f = + case find ((==) title . Docs.declTitle) (declarationsFor mn) of + Nothing -> + Fail (NotDocumented mn title) + Just Docs.Declaration{..} -> + f declKind + findDeclChildren mn title child f = findDecl mn title $ \Docs.Declaration{..} -> case find ((==) child . Docs.cdeclTitle) declChildren of @@ -667,6 +688,21 @@ testCases = [ ShouldBeDocumented (n "TypeSynonymInstance") "MyNT" ["MyNT", "ntMyNT"] ] ) + , ("KindSignatureDocs", + [ ShouldHaveKindSignature (n "KindSignatureDocs") "DKindAndType" + , ShouldHaveKindSignature (n "KindSignatureDocs") "TKindAndType" + , ShouldHaveKindSignature (n "KindSignatureDocs") "NKindAndType" + , ShouldHaveKindSignature (n "KindSignatureDocs") "CKindAndType" + , ShouldHaveKindSignature (n "KindSignatureDocs") "DKindOnly" + , ShouldHaveKindSignature (n "KindSignatureDocs") "TKindOnly" + , ShouldHaveKindSignature (n "KindSignatureDocs") "NKindOnly" + , ShouldHaveKindSignature (n "KindSignatureDocs") "CKindOnly" + , ShouldHaveKindSignature (n "KindSignatureDocs") "DTypeOnly" + , ShouldHaveKindSignature (n "KindSignatureDocs") "TTypeOnly" + , ShouldHaveKindSignature (n "KindSignatureDocs") "NTypeOnly" + , ShouldHaveKindSignature (n "KindSignatureDocs") "CTypeOnly" + ] + ) ] where diff --git a/tests/purs/docs/src/KindSignatureDocs.purs b/tests/purs/docs/src/KindSignatureDocs.purs new file mode 100644 index 0000000000..906e3e489e --- /dev/null +++ b/tests/purs/docs/src/KindSignatureDocs.purs @@ -0,0 +1,60 @@ +module KindSignatureDocs where + +-- | DKindAndType - kind docs +data DKindAndType :: forall k. k -> Type +-- | DKindAndType - type docs +data DKindAndType a = DKindAndType + +-- | TKindAndType - kind docs +type TKindAndType :: forall k. k -> Type +-- | TKindAndType - type docs +type TKindAndType a = Int + +-- | NKindAndType - kind docs +newtype NKindAndType :: forall k. k -> Type +-- | NKindAndType - type docs +newtype NKindAndType a = NKindAndType Int + +-- | CKindAndType - kind docs +class CKindAndType :: Type -> Constraint +-- | CKindAndType - type docs +class CKindAndType a where + fooKindAndType :: a -> String + +---------- + +-- | DKindOnly - kind docs +data DKindOnly :: forall k. k -> Type +data DKindOnly a = DKindOnly + +-- | TKindOnly - kind docs +type TKindOnly :: forall k. k -> Type +type TKindOnly a = Int + +-- | NKindOnly - kind docs +newtype NKindOnly :: forall k. k -> Type +newtype NKindOnly a = NKindOnly Int + +-- | CKindOnly - kind docs +class CKindOnly :: Type -> Constraint +class CKindOnly a where + fooKindOnly :: a -> String + +---------- + +data DTypeOnly :: forall k. k -> Type +-- | DTypeOnly - type docs +data DTypeOnly a = DTypeOnly + +type TTypeOnly :: forall k. k -> Type +-- | TTypeOnly - type docs +type TTypeOnly a = Int + +newtype NTypeOnly :: forall k. k -> Type +-- | NTypeOnly - type docs +newtype NTypeOnly a = NTypeOnly Int + +class CTypeOnly :: Type -> Constraint +-- | CTypeOnly - type docs +class CTypeOnly a where + fooTypeOnly :: a -> String From 1620dec81de76b02996ec58e638ebb8341de402a Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 18 Jun 2021 17:50:20 -0700 Subject: [PATCH 21/33] In kind sig doc tests, make one type parameter in class polymorphic --- tests/purs/docs/src/KindSignatureDocs.purs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/purs/docs/src/KindSignatureDocs.purs b/tests/purs/docs/src/KindSignatureDocs.purs index 906e3e489e..884370093c 100644 --- a/tests/purs/docs/src/KindSignatureDocs.purs +++ b/tests/purs/docs/src/KindSignatureDocs.purs @@ -16,10 +16,10 @@ newtype NKindAndType :: forall k. k -> Type newtype NKindAndType a = NKindAndType Int -- | CKindAndType - kind docs -class CKindAndType :: Type -> Constraint -- | CKindAndType - type docs -class CKindAndType a where - fooKindAndType :: a -> String +class CKindAndType :: forall k. (k -> Type) -> k -> Constraint +class CKindAndType a k where + fooKindAndType :: a k -> String ---------- @@ -36,9 +36,9 @@ newtype NKindOnly :: forall k. k -> Type newtype NKindOnly a = NKindOnly Int -- | CKindOnly - kind docs -class CKindOnly :: Type -> Constraint -class CKindOnly a where - fooKindOnly :: a -> String +class CKindOnly :: forall k. (k -> Type) -> k -> Constraint +class CKindOnly a k where + fooKindOnly :: a k -> String ---------- @@ -54,7 +54,7 @@ newtype NTypeOnly :: forall k. k -> Type -- | NTypeOnly - type docs newtype NTypeOnly a = NTypeOnly Int -class CTypeOnly :: Type -> Constraint -- | CTypeOnly - type docs -class CTypeOnly a where - fooTypeOnly :: a -> String +class CTypeOnly :: forall k. (k -> Type) -> k -> Constraint +class CTypeOnly a k where + fooTypeOnly :: a k -> String From b16a01c9a0f9223030ab6a464cd04d388c29100d Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 18 Jun 2021 17:51:34 -0700 Subject: [PATCH 22/33] Also test that expected kind signature matches the actual one --- tests/TestDocs.hs | 52 +++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/tests/TestDocs.hs b/tests/TestDocs.hs index 5dce872c6f..07cd9b655a 100644 --- a/tests/TestDocs.hs +++ b/tests/TestDocs.hs @@ -106,8 +106,8 @@ data DocsAssertion | ShouldHaveLink P.ModuleName Text Text Docs.Namespace Docs.LinkLocation -- | Assert that a given declaration comes before another in the output | ShouldComeBefore P.ModuleName Text Text - -- | Assert that a given declaration has a kind signature - | ShouldHaveKindSignature P.ModuleName Text + -- | Assert that a given declaration has the given kind signature + | ShouldHaveKindSignature P.ModuleName Text Text data TagsAssertion -- | Assert that a particular declaration is tagged @@ -163,8 +163,8 @@ displayAssertion = \case ShouldComeBefore mn declA declB -> showQual mn declA <> " should come before " <> showQual mn declB <> " in the docs" - ShouldHaveKindSignature mn decl -> - showQual mn decl <> " should have a kind signature." + ShouldHaveKindSignature mn decl expected -> + showQual mn decl <> " should have the kind signature `" <> expected <> "`" displayTagsAssertion :: TagsAssertion -> Text displayTagsAssertion = \case @@ -222,6 +222,10 @@ data DocsAssertionFailure -- | Expected a kind signature for a declaration, but did not find one -- Fields: module name, declaration title. | KindSignatureMissing P.ModuleName Text + -- | The rendered kind signature did not match the expected one. + -- Fields: module name, declaration title, expected kind signature, + -- actual kind signature + | KindSignatureMismatch P.ModuleName Text Text Text data TagsAssertionFailure -- | A declaration was not tagged, but should have been @@ -274,6 +278,9 @@ displayAssertionFailure = \case "expected to see " <> before' <> " before " <> after' KindSignatureMissing _ decl -> "the kind signature for " <> decl <> " is missing." + KindSignatureMismatch _ decl expected actual -> + "expected the kind signature for " <> decl <> " to be " <> expected <> + "; got " <> actual displayTagsAssertionFailure :: TagsAssertionFailure -> Text displayTagsAssertionFailure = \case @@ -445,9 +452,15 @@ runAssertion assertion linksCtx Docs.Module{..} = (_, Nothing) -> Fail (NotDocumented mn after') - ShouldHaveKindSignature mn decl -> + ShouldHaveKindSignature mn decl expected -> findDeclKinds mn decl $ \case - Just _ -> Pass + Just Docs.KindInfo{..} -> + if expected /= actual + then Fail (KindSignatureMismatch mn decl expected actual) + else Pass + where + actual = codeToString $ Docs.renderKindSig decl $ + Docs.KindInfo kiKeyword kiKind Nothing -> Fail (KindSignatureMissing mn decl) where @@ -689,18 +702,21 @@ testCases = ] ) , ("KindSignatureDocs", - [ ShouldHaveKindSignature (n "KindSignatureDocs") "DKindAndType" - , ShouldHaveKindSignature (n "KindSignatureDocs") "TKindAndType" - , ShouldHaveKindSignature (n "KindSignatureDocs") "NKindAndType" - , ShouldHaveKindSignature (n "KindSignatureDocs") "CKindAndType" - , ShouldHaveKindSignature (n "KindSignatureDocs") "DKindOnly" - , ShouldHaveKindSignature (n "KindSignatureDocs") "TKindOnly" - , ShouldHaveKindSignature (n "KindSignatureDocs") "NKindOnly" - , ShouldHaveKindSignature (n "KindSignatureDocs") "CKindOnly" - , ShouldHaveKindSignature (n "KindSignatureDocs") "DTypeOnly" - , ShouldHaveKindSignature (n "KindSignatureDocs") "TTypeOnly" - , ShouldHaveKindSignature (n "KindSignatureDocs") "NTypeOnly" - , ShouldHaveKindSignature (n "KindSignatureDocs") "CTypeOnly" + -- expected kind signatures + [ ShouldHaveKindSignature (n "KindSignatureDocs") "DKindAndType" "data DKindAndType :: forall k. k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "TKindAndType" "type TKindAndType :: forall k. k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "NKindAndType" "newtype NKindAndType :: forall k. k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "CKindAndType" "class CKindAndType :: forall k. (k -> Type) -> k -> Constraint" + + , ShouldHaveKindSignature (n "KindSignatureDocs") "DKindOnly" "data DKindOnly :: forall k. k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "TKindOnly" "type TKindOnly :: forall k. k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "NKindOnly" "newtype NKindOnly :: forall k. k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "CKindOnly" "class CKindOnly :: forall k. (k -> Type) -> k -> Constraint" + + , ShouldHaveKindSignature (n "KindSignatureDocs") "DTypeOnly" "data DTypeOnly :: forall k. k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "TTypeOnly" "type TTypeOnly :: forall k. k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "NTypeOnly" "newtype NTypeOnly :: forall k. k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "CTypeOnly" "class CTypeOnly :: forall k. (k -> Type) -> k -> Constraint" ] ) ] From 1333269a8edfda777479912031bfe559ad4fbdfd Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 18 Jun 2021 17:54:02 -0700 Subject: [PATCH 23/33] Verify that doc-comment merging is done correctly --- tests/TestDocs.hs | 37 ++++++++++++++++++++++ tests/purs/docs/src/KindSignatureDocs.purs | 32 +++++++++---------- 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/tests/TestDocs.hs b/tests/TestDocs.hs index 07cd9b655a..1d244a18b6 100644 --- a/tests/TestDocs.hs +++ b/tests/TestDocs.hs @@ -108,6 +108,10 @@ data DocsAssertion | ShouldComeBefore P.ModuleName Text Text -- | Assert that a given declaration has the given kind signature | ShouldHaveKindSignature P.ModuleName Text Text + -- | Assert that a given declaration with doc-comments on its + -- kind signature and type declaration are properly merged into one + -- doc-comment. + | ShouldMergeDocComments P.ModuleName Text (Maybe Text) data TagsAssertion -- | Assert that a particular declaration is tagged @@ -165,6 +169,8 @@ displayAssertion = \case " in the docs" ShouldHaveKindSignature mn decl expected -> showQual mn decl <> " should have the kind signature `" <> expected <> "`" + ShouldMergeDocComments mn decl _ -> + showQual mn decl <> " should merge its kind declaration and type declaration's doc-comments" displayTagsAssertion :: TagsAssertion -> Text displayTagsAssertion = \case @@ -226,6 +232,11 @@ data DocsAssertionFailure -- Fields: module name, declaration title, expected kind signature, -- actual kind signature | KindSignatureMismatch P.ModuleName Text Text Text + -- | The doc comments for the kind signature and type declaration were + -- not properly merged into the expected one. + -- Fields: module name, declaration title, expected doc-comments, + -- actual doc-comments + | DocCommentMergeFailure P.ModuleName Text Text Text data TagsAssertionFailure -- | A declaration was not tagged, but should have been @@ -281,6 +292,9 @@ displayAssertionFailure = \case KindSignatureMismatch _ decl expected actual -> "expected the kind signature for " <> decl <> " to be " <> expected <> "; got " <> actual + DocCommentMergeFailure _ decl expected actual -> + "Expected the doc-comment for " <> decl <> " to merge comments and be `" <> + expected <> "`; got `" <> actual <> "`" displayTagsAssertionFailure :: TagsAssertionFailure -> Text displayTagsAssertionFailure = \case @@ -463,6 +477,13 @@ runAssertion assertion linksCtx Docs.Module{..} = Docs.KindInfo kiKeyword kiKind Nothing -> Fail (KindSignatureMissing mn decl) + ShouldMergeDocComments mn decl expected -> + findDecl mn decl $ \Docs.Declaration{..} -> + if expected == declComments + then Pass + else Fail (DocCommentMergeFailure mn decl (display expected) (display declComments)) + where + display = fromMaybe "" where declarationsFor mn = if mn == modName @@ -717,6 +738,22 @@ testCases = , ShouldHaveKindSignature (n "KindSignatureDocs") "TTypeOnly" "type TTypeOnly :: forall k. k -> Type" , ShouldHaveKindSignature (n "KindSignatureDocs") "NTypeOnly" "newtype NTypeOnly :: forall k. k -> Type" , ShouldHaveKindSignature (n "KindSignatureDocs") "CTypeOnly" "class CTypeOnly :: forall k. (k -> Type) -> k -> Constraint" + + -- expected docs + , ShouldMergeDocComments (n "KindSignatureDocs") "DKindAndType" $ Just "dkatk\n\ndkatt\n" + , ShouldMergeDocComments (n "KindSignatureDocs") "TKindAndType" $ Just "tkatk\n\ntkatt\n" + , ShouldMergeDocComments (n "KindSignatureDocs") "NKindAndType" $ Just "nkatk\n\nnkatt\n" + , ShouldMergeDocComments (n "KindSignatureDocs") "CKindAndType" $ Just "ckatk\n\nckatt\n" + + , ShouldMergeDocComments (n "KindSignatureDocs") "DKindOnly" $ Just "dkok\n" + , ShouldMergeDocComments (n "KindSignatureDocs") "TKindOnly" $ Just "tkok\n" + , ShouldMergeDocComments (n "KindSignatureDocs") "NKindOnly" $ Just "nkok\n" + , ShouldMergeDocComments (n "KindSignatureDocs") "CKindOnly" $ Just "ckok\n" + + , ShouldMergeDocComments (n "KindSignatureDocs") "DTypeOnly" $ Just "dtot\n" + , ShouldMergeDocComments (n "KindSignatureDocs") "TTypeOnly" $ Just "ttot\n" + , ShouldMergeDocComments (n "KindSignatureDocs") "NTypeOnly" $ Just "ntot\n" + , ShouldMergeDocComments (n "KindSignatureDocs") "CTypeOnly" $ Just "ctot\n" ] ) ] diff --git a/tests/purs/docs/src/KindSignatureDocs.purs b/tests/purs/docs/src/KindSignatureDocs.purs index 884370093c..d7e693e47a 100644 --- a/tests/purs/docs/src/KindSignatureDocs.purs +++ b/tests/purs/docs/src/KindSignatureDocs.purs @@ -1,41 +1,41 @@ module KindSignatureDocs where --- | DKindAndType - kind docs +-- | dkatk data DKindAndType :: forall k. k -> Type --- | DKindAndType - type docs +-- | dkatt data DKindAndType a = DKindAndType --- | TKindAndType - kind docs +-- | tkatk type TKindAndType :: forall k. k -> Type --- | TKindAndType - type docs +-- | tkatt type TKindAndType a = Int --- | NKindAndType - kind docs +-- | nkatk newtype NKindAndType :: forall k. k -> Type --- | NKindAndType - type docs +-- | nkatt newtype NKindAndType a = NKindAndType Int --- | CKindAndType - kind docs --- | CKindAndType - type docs +-- | ckatk class CKindAndType :: forall k. (k -> Type) -> k -> Constraint +-- | ckatt class CKindAndType a k where fooKindAndType :: a k -> String ---------- --- | DKindOnly - kind docs +-- | dkok data DKindOnly :: forall k. k -> Type data DKindOnly a = DKindOnly --- | TKindOnly - kind docs +-- | tkok type TKindOnly :: forall k. k -> Type type TKindOnly a = Int --- | NKindOnly - kind docs +-- | nkok newtype NKindOnly :: forall k. k -> Type newtype NKindOnly a = NKindOnly Int --- | CKindOnly - kind docs +-- | ckok class CKindOnly :: forall k. (k -> Type) -> k -> Constraint class CKindOnly a k where fooKindOnly :: a k -> String @@ -43,18 +43,18 @@ class CKindOnly a k where ---------- data DTypeOnly :: forall k. k -> Type --- | DTypeOnly - type docs +-- | dtot data DTypeOnly a = DTypeOnly type TTypeOnly :: forall k. k -> Type --- | TTypeOnly - type docs +-- | ttot type TTypeOnly a = Int newtype NTypeOnly :: forall k. k -> Type --- | NTypeOnly - type docs +-- | ntot newtype NTypeOnly a = NTypeOnly Int --- | CTypeOnly - type docs class CTypeOnly :: forall k. (k -> Type) -> k -> Constraint +-- | ctot class CTypeOnly a k where fooTypeOnly :: a k -> String From 645d7d63c9969151df857a4c316fc9bc34d37f35 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 18 Jun 2021 17:54:41 -0700 Subject: [PATCH 24/33] Test doc-comments of declarations without kind signature --- tests/TestDocs.hs | 5 +++++ tests/purs/docs/src/KindSignatureDocs.purs | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/tests/TestDocs.hs b/tests/TestDocs.hs index 1d244a18b6..3bacc4aa47 100644 --- a/tests/TestDocs.hs +++ b/tests/TestDocs.hs @@ -754,6 +754,11 @@ testCases = , ShouldMergeDocComments (n "KindSignatureDocs") "TTypeOnly" $ Just "ttot\n" , ShouldMergeDocComments (n "KindSignatureDocs") "NTypeOnly" $ Just "ntot\n" , ShouldMergeDocComments (n "KindSignatureDocs") "CTypeOnly" $ Just "ctot\n" + + , ShouldMergeDocComments (n "KindSignatureDocs") "DImplicit" $ Just "dit\n" + , ShouldMergeDocComments (n "KindSignatureDocs") "TImplicit" $ Just "tit\n" + , ShouldMergeDocComments (n "KindSignatureDocs") "NImplicit" $ Just "nit\n" + , ShouldMergeDocComments (n "KindSignatureDocs") "CImplicit" $ Just "cit\n" ] ) ] diff --git a/tests/purs/docs/src/KindSignatureDocs.purs b/tests/purs/docs/src/KindSignatureDocs.purs index d7e693e47a..37dcd44531 100644 --- a/tests/purs/docs/src/KindSignatureDocs.purs +++ b/tests/purs/docs/src/KindSignatureDocs.purs @@ -58,3 +58,18 @@ class CTypeOnly :: forall k. (k -> Type) -> k -> Constraint -- | ctot class CTypeOnly a k where fooTypeOnly :: a k -> String + +---------- + +-- | dit +data DImplicit a = DImplicit + +-- | tit +type TImplicit a = Int + +-- | nit +newtype NImplicit a = NImplicit Int + +-- | cit +class CImplicit a k where + fooImplicit :: a k -> String From 21d0e26c53366008771393a1fb6a7cc660147c76 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 18 Jun 2021 17:55:55 -0700 Subject: [PATCH 25/33] Test that declarations with no explicit kind sig still have one in docs --- tests/TestDocs.hs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/TestDocs.hs b/tests/TestDocs.hs index 3bacc4aa47..c5263dce57 100644 --- a/tests/TestDocs.hs +++ b/tests/TestDocs.hs @@ -739,6 +739,12 @@ testCases = , ShouldHaveKindSignature (n "KindSignatureDocs") "NTypeOnly" "newtype NTypeOnly :: forall k. k -> Type" , ShouldHaveKindSignature (n "KindSignatureDocs") "CTypeOnly" "class CTypeOnly :: forall k. (k -> Type) -> k -> Constraint" + -- Declarations with no explicit kind signatures should stlil have them implicitly. + , ShouldHaveKindSignature (n "KindSignatureDocs") "DImplicit" "data DImplicit :: forall k. k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "TImplicit" "type TImplicit :: forall k. k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "NImplicit" "newtype NImplicit :: forall k. k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "CImplicit" "class CImplicit :: forall k1. (k1 -> Type) -> k1 -> Constraint" + -- expected docs , ShouldMergeDocComments (n "KindSignatureDocs") "DKindAndType" $ Just "dkatk\n\ndkatt\n" , ShouldMergeDocComments (n "KindSignatureDocs") "TKindAndType" $ Just "tkatk\n\ntkatt\n" From 59009d76cc659971a931d5768f8ad6dcbeae1413 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 18 Jun 2021 18:31:23 -0700 Subject: [PATCH 26/33] Add a single line between kind signature and type declaration --- app/static/pursuit.css | 3 +++ app/static/pursuit.less | 4 ++++ src/Language/PureScript/Docs/AsHtml.hs | 10 +++++----- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/static/pursuit.css b/app/static/pursuit.css index dd4671995f..6b40db3368 100644 --- a/app/static/pursuit.css +++ b/app/static/pursuit.css @@ -412,6 +412,9 @@ ol li { text-indent: -2.441em; white-space: normal; } +.decl__kind { + border-bottom: 1px solid #cccccc; +} :target .decl__signature, :target .decl__signature code { /* We want the background to be transparent, even when the parent is a target */ diff --git a/app/static/pursuit.less b/app/static/pursuit.less index 1b064b2c5f..ddcadc9093 100644 --- a/app/static/pursuit.less +++ b/app/static/pursuit.less @@ -495,6 +495,10 @@ ol li { white-space: normal; } +.decl__kind { + border-bottom: 1px solid darken(@background, 20%); +} + :target .decl__signature, :target .decl__signature code { /* We want the background to be transparent, even when the parent is a target */ diff --git a/src/Language/PureScript/Docs/AsHtml.hs b/src/Language/PureScript/Docs/AsHtml.hs index 2f649135c3..3ff4c6102e 100644 --- a/src/Language/PureScript/Docs/AsHtml.hs +++ b/src/Language/PureScript/Docs/AsHtml.hs @@ -146,11 +146,11 @@ declAsHtml r d@Declaration{..} = do AliasDeclaration fixity alias_ -> renderAlias fixity alias_ _ -> do - for_ declKind $ \kindInfo -> do - pre ! A.class_ "decl__signature" $ code $ - codeAsHtml r (Render.renderKindSig declTitle kindInfo) - pre ! A.class_ "decl__signature" $ code $ - codeAsHtml r (Render.renderDeclaration d) + pre ! A.class_ "decl__signature" $ do + for_ declKind $ \kindInfo -> do + code ! A.class_ "decl__kind" $ do + codeAsHtml r (Render.renderKindSig declTitle kindInfo) + code $ codeAsHtml r (Render.renderDeclaration d) for_ declComments renderMarkdown From 62e2d945975a8dbee82edb6ea8836e56513d07a6 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 19 Jun 2021 06:04:17 -0700 Subject: [PATCH 27/33] Fix vertical spacing above/below line separating kind sig from type decl --- app/static/pursuit.css | 3 ++- app/static/pursuit.less | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/static/pursuit.css b/app/static/pursuit.css index 6b40db3368..709b859b54 100644 --- a/app/static/pursuit.css +++ b/app/static/pursuit.css @@ -404,10 +404,11 @@ ol li { border-radius: 0; border-top: 1px solid #cccccc; border-bottom: 1px solid #cccccc; - padding: 0.328em 0; + padding: 0; } .decl__signature code { display: block; + padding: 0.328em 0; padding-left: 2.441em; text-indent: -2.441em; white-space: normal; diff --git a/app/static/pursuit.less b/app/static/pursuit.less index ddcadc9093..7a9629f494 100644 --- a/app/static/pursuit.less +++ b/app/static/pursuit.less @@ -485,11 +485,12 @@ ol li { border-radius: 0; border-top: 1px solid darken(@background, 20%); border-bottom: 1px solid darken(@background, 20%); - padding: 0.328em 0; + padding: 0; } .decl__signature code { display: block; + padding: 0.328em 0; padding-left: 2.441em; text-indent: -2.441em; white-space: normal; From 24f15e1931cf8ac568512a95715453e8861e2ff8 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 19 Jun 2021 17:47:51 -0700 Subject: [PATCH 28/33] Insert inferred kind signatures into docs' declarations --- src/Language/PureScript/Docs/Convert.hs | 35 ++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/Language/PureScript/Docs/Convert.hs b/src/Language/PureScript/Docs/Convert.hs index a91440d07c..40904ac1bc 100644 --- a/src/Language/PureScript/Docs/Convert.hs +++ b/src/Language/PureScript/Docs/Convert.hs @@ -39,23 +39,44 @@ convertModule :: P.Module -> m Module convertModule externs env checkEnv = - fmap (insertValueTypes checkEnv . convertSingleModule) . partiallyDesugar externs env + fmap (insertValueTypesAndInferredKinds checkEnv . convertSingleModule) . partiallyDesugar externs env -- | -- Updates all the types of the ValueDeclarations inside the module based on -- their types inside the given Environment. -- -insertValueTypes :: +-- Also inserts inferred kind signatures into the corresponding declarations +-- if no kind signatures were declared explicitly. +-- +insertValueTypesAndInferredKinds :: P.Environment -> Module -> Module -insertValueTypes env m = +insertValueTypesAndInferredKinds env m = m { modDeclarations = map go (modDeclarations m) } where + -- insert value types go d@Declaration { declInfo = ValueDeclaration P.TypeWildcard{} } = let ident = P.Ident . CST.getIdent . CST.nameValue . parseIdent $ declTitle d ty = lookupName ident in d { declInfo = ValueDeclaration (ty $> ()) } + + -- insert inferred kinds + go d@Declaration{..} | isNothing declKind = case declInfo of + DataDeclaration dataDeclType _ -> do + let keyword = case dataDeclType of + P.Data -> P.DataSig + P.Newtype -> P.NewtypeSig + d { declKind = Just $ KindInfo { kiKeyword = keyword, kiKind = () <$ lookupKind declTitle } } + + TypeSynonymDeclaration _ _ -> + d { declKind = Just $ KindInfo { kiKeyword = P.TypeSynonymSig, kiKind = () <$ lookupKind declTitle } } + + TypeClassDeclaration _ _ _ -> + d { declKind = Just $ KindInfo { kiKeyword = P.ClassSig , kiKind = () <$ lookupKind declTitle } } + + _ -> d + go other = other @@ -70,6 +91,14 @@ insertValueTypes env m = Nothing -> err ("name not found: " ++ show key) + lookupKind name = + let key = P.Qualified (Just (modName m)) (P.ProperName name) + in case Map.lookup key (P.types env) of + Just (kind, _) -> + kind + Nothing -> + err ("type not found: " ++ show key) + err msg = P.internalError ("Docs.Convert.insertValueTypes: " ++ msg) From 117459563c9d7b5ec1ba2a4c500aa8a4ff63711b Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 19 Jun 2021 17:48:09 -0700 Subject: [PATCH 29/33] Update tests to better show the expected and actual inferred kind sigs --- tests/TestDocs.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/TestDocs.hs b/tests/TestDocs.hs index c5263dce57..ad4c62ab62 100644 --- a/tests/TestDocs.hs +++ b/tests/TestDocs.hs @@ -290,8 +290,9 @@ displayAssertionFailure = \case KindSignatureMissing _ decl -> "the kind signature for " <> decl <> " is missing." KindSignatureMismatch _ decl expected actual -> - "expected the kind signature for " <> decl <> " to be " <> expected <> - "; got " <> actual + "expected the kind signature for " <> decl <> "\n" <> + "to be `" <> expected <> "`\n" <> + " got `" <> actual <> "`" DocCommentMergeFailure _ decl expected actual -> "Expected the doc-comment for " <> decl <> " to merge comments and be `" <> expected <> "`; got `" <> actual <> "`" From e526ce2fe9a436a60e4c2e475e1e4953ffe4992a Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 19 Jun 2021 19:22:19 -0700 Subject: [PATCH 30/33] Refactor code to increase readability by making KindInfo in function --- src/Language/PureScript/Docs/Convert.hs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Language/PureScript/Docs/Convert.hs b/src/Language/PureScript/Docs/Convert.hs index 40904ac1bc..05a4b333bc 100644 --- a/src/Language/PureScript/Docs/Convert.hs +++ b/src/Language/PureScript/Docs/Convert.hs @@ -64,16 +64,13 @@ insertValueTypesAndInferredKinds env m = -- insert inferred kinds go d@Declaration{..} | isNothing declKind = case declInfo of DataDeclaration dataDeclType _ -> do - let keyword = case dataDeclType of - P.Data -> P.DataSig - P.Newtype -> P.NewtypeSig - d { declKind = Just $ KindInfo { kiKeyword = keyword, kiKind = () <$ lookupKind declTitle } } + d { declKind = mkInferredKindInfo declTitle $ toKindSignatureFor dataDeclType } TypeSynonymDeclaration _ _ -> - d { declKind = Just $ KindInfo { kiKeyword = P.TypeSynonymSig, kiKind = () <$ lookupKind declTitle } } + d { declKind = mkInferredKindInfo declTitle P.TypeSynonymSig } TypeClassDeclaration _ _ _ -> - d { declKind = Just $ KindInfo { kiKeyword = P.ClassSig , kiKind = () <$ lookupKind declTitle } } + d { declKind = mkInferredKindInfo declTitle P.ClassSig } _ -> d @@ -91,11 +88,17 @@ insertValueTypesAndInferredKinds env m = Nothing -> err ("name not found: " ++ show key) - lookupKind name = + toKindSignatureFor :: P.DataDeclType -> P.KindSignatureFor + toKindSignatureFor = \case + P.Data -> P.DataSig + P.Newtype -> P.NewtypeSig + + mkInferredKindInfo :: Text -> P.KindSignatureFor -> Maybe KindInfo + mkInferredKindInfo name keyword = let key = P.Qualified (Just (modName m)) (P.ProperName name) in case Map.lookup key (P.types env) of - Just (kind, _) -> - kind + Just (inferredKind, _) -> + Just $ KindInfo { kiKeyword = keyword, kiKind = () <$ inferredKind } Nothing -> err ("type not found: " ++ show key) From dcd2b826aa9a7ea0ef6d1e23a02b970400a15519 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sat, 19 Jun 2021 19:24:32 -0700 Subject: [PATCH 31/33] Update expected kind signatures to match compiler-inferred ones --- tests/TestDocs.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/TestDocs.hs b/tests/TestDocs.hs index ad4c62ab62..df3bd3b32a 100644 --- a/tests/TestDocs.hs +++ b/tests/TestDocs.hs @@ -741,10 +741,10 @@ testCases = , ShouldHaveKindSignature (n "KindSignatureDocs") "CTypeOnly" "class CTypeOnly :: forall k. (k -> Type) -> k -> Constraint" -- Declarations with no explicit kind signatures should stlil have them implicitly. - , ShouldHaveKindSignature (n "KindSignatureDocs") "DImplicit" "data DImplicit :: forall k. k -> Type" - , ShouldHaveKindSignature (n "KindSignatureDocs") "TImplicit" "type TImplicit :: forall k. k -> Type" - , ShouldHaveKindSignature (n "KindSignatureDocs") "NImplicit" "newtype NImplicit :: forall k. k -> Type" - , ShouldHaveKindSignature (n "KindSignatureDocs") "CImplicit" "class CImplicit :: forall k1. (k1 -> Type) -> k1 -> Constraint" + , ShouldHaveKindSignature (n "KindSignatureDocs") "DImplicit" "data DImplicit :: forall (k :: Type). k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "TImplicit" "type TImplicit :: forall (k :: Type). k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "NImplicit" "newtype NImplicit :: forall (k :: Type). k -> Type" + , ShouldHaveKindSignature (n "KindSignatureDocs") "CImplicit" "class CImplicit :: forall (k1 :: Type). (k1 -> Type) -> k1 -> Constraint" -- expected docs , ShouldMergeDocComments (n "KindSignatureDocs") "DKindAndType" $ Just "dkatk\n\ndkatt\n" From d04c9048de93dde47983271037372fce4bdff6e2 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Sun, 20 Jun 2021 07:01:10 -0700 Subject: [PATCH 32/33] Revert kind signature insertion code and tests --- src/Language/PureScript/Docs/Convert.hs | 37 ++-------------------- tests/TestDocs.hs | 11 ------- tests/purs/docs/src/KindSignatureDocs.purs | 15 --------- 3 files changed, 3 insertions(+), 60 deletions(-) diff --git a/src/Language/PureScript/Docs/Convert.hs b/src/Language/PureScript/Docs/Convert.hs index 05a4b333bc..9dd57ce6b8 100644 --- a/src/Language/PureScript/Docs/Convert.hs +++ b/src/Language/PureScript/Docs/Convert.hs @@ -39,18 +39,15 @@ convertModule :: P.Module -> m Module convertModule externs env checkEnv = - fmap (insertValueTypesAndInferredKinds checkEnv . convertSingleModule) . partiallyDesugar externs env + fmap (insertValueTypes checkEnv . convertSingleModule) . partiallyDesugar externs env -- | -- Updates all the types of the ValueDeclarations inside the module based on -- their types inside the given Environment. -- --- Also inserts inferred kind signatures into the corresponding declarations --- if no kind signatures were declared explicitly. --- -insertValueTypesAndInferredKinds :: +insertValueTypes :: P.Environment -> Module -> Module -insertValueTypesAndInferredKinds env m = +insertValueTypes env m = m { modDeclarations = map go (modDeclarations m) } where -- insert value types @@ -60,20 +57,6 @@ insertValueTypesAndInferredKinds env m = ty = lookupName ident in d { declInfo = ValueDeclaration (ty $> ()) } - - -- insert inferred kinds - go d@Declaration{..} | isNothing declKind = case declInfo of - DataDeclaration dataDeclType _ -> do - d { declKind = mkInferredKindInfo declTitle $ toKindSignatureFor dataDeclType } - - TypeSynonymDeclaration _ _ -> - d { declKind = mkInferredKindInfo declTitle P.TypeSynonymSig } - - TypeClassDeclaration _ _ _ -> - d { declKind = mkInferredKindInfo declTitle P.ClassSig } - - _ -> d - go other = other @@ -88,20 +71,6 @@ insertValueTypesAndInferredKinds env m = Nothing -> err ("name not found: " ++ show key) - toKindSignatureFor :: P.DataDeclType -> P.KindSignatureFor - toKindSignatureFor = \case - P.Data -> P.DataSig - P.Newtype -> P.NewtypeSig - - mkInferredKindInfo :: Text -> P.KindSignatureFor -> Maybe KindInfo - mkInferredKindInfo name keyword = - let key = P.Qualified (Just (modName m)) (P.ProperName name) - in case Map.lookup key (P.types env) of - Just (inferredKind, _) -> - Just $ KindInfo { kiKeyword = keyword, kiKind = () <$ inferredKind } - Nothing -> - err ("type not found: " ++ show key) - err msg = P.internalError ("Docs.Convert.insertValueTypes: " ++ msg) diff --git a/tests/TestDocs.hs b/tests/TestDocs.hs index df3bd3b32a..102d70cd9b 100644 --- a/tests/TestDocs.hs +++ b/tests/TestDocs.hs @@ -740,12 +740,6 @@ testCases = , ShouldHaveKindSignature (n "KindSignatureDocs") "NTypeOnly" "newtype NTypeOnly :: forall k. k -> Type" , ShouldHaveKindSignature (n "KindSignatureDocs") "CTypeOnly" "class CTypeOnly :: forall k. (k -> Type) -> k -> Constraint" - -- Declarations with no explicit kind signatures should stlil have them implicitly. - , ShouldHaveKindSignature (n "KindSignatureDocs") "DImplicit" "data DImplicit :: forall (k :: Type). k -> Type" - , ShouldHaveKindSignature (n "KindSignatureDocs") "TImplicit" "type TImplicit :: forall (k :: Type). k -> Type" - , ShouldHaveKindSignature (n "KindSignatureDocs") "NImplicit" "newtype NImplicit :: forall (k :: Type). k -> Type" - , ShouldHaveKindSignature (n "KindSignatureDocs") "CImplicit" "class CImplicit :: forall (k1 :: Type). (k1 -> Type) -> k1 -> Constraint" - -- expected docs , ShouldMergeDocComments (n "KindSignatureDocs") "DKindAndType" $ Just "dkatk\n\ndkatt\n" , ShouldMergeDocComments (n "KindSignatureDocs") "TKindAndType" $ Just "tkatk\n\ntkatt\n" @@ -761,11 +755,6 @@ testCases = , ShouldMergeDocComments (n "KindSignatureDocs") "TTypeOnly" $ Just "ttot\n" , ShouldMergeDocComments (n "KindSignatureDocs") "NTypeOnly" $ Just "ntot\n" , ShouldMergeDocComments (n "KindSignatureDocs") "CTypeOnly" $ Just "ctot\n" - - , ShouldMergeDocComments (n "KindSignatureDocs") "DImplicit" $ Just "dit\n" - , ShouldMergeDocComments (n "KindSignatureDocs") "TImplicit" $ Just "tit\n" - , ShouldMergeDocComments (n "KindSignatureDocs") "NImplicit" $ Just "nit\n" - , ShouldMergeDocComments (n "KindSignatureDocs") "CImplicit" $ Just "cit\n" ] ) ] diff --git a/tests/purs/docs/src/KindSignatureDocs.purs b/tests/purs/docs/src/KindSignatureDocs.purs index 37dcd44531..d7e693e47a 100644 --- a/tests/purs/docs/src/KindSignatureDocs.purs +++ b/tests/purs/docs/src/KindSignatureDocs.purs @@ -58,18 +58,3 @@ class CTypeOnly :: forall k. (k -> Type) -> k -> Constraint -- | ctot class CTypeOnly a k where fooTypeOnly :: a k -> String - ----------- - --- | dit -data DImplicit a = DImplicit - --- | tit -type TImplicit a = Int - --- | nit -newtype NImplicit a = NImplicit Int - --- | cit -class CImplicit a k where - fooImplicit :: a k -> String From 1fb079b12976f6dbf5169ada99c9f93302880ba1 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Mon, 21 Jun 2021 18:40:43 -0700 Subject: [PATCH 33/33] Provide more description for changelog entry --- CHANGELOG.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7da785168e..0285f81d39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,30 @@ New features: * Display kind signatures and their comments in documentation (#4100 by JordanMartinez) + Previously, data/newtype/type/class declarations that have explicit kind + signatures would not display those kind signatures in their documentation. + For example, the two below types... + + ```purescript + data PolyProxy :: forall k. k -> Type + data PolyProxy a = PolyProxy + + data TypeProxy :: Type -> Type + data TypeProxy a = TypeProxy + ``` + + ... would only show the following information in their docs. One cannot + be distinguished from another due to the missing kind signatures: + + ``` + data PolyProxy a = PolyProxy + + data TypeProxy a = TypeProxy + ``` + + Now, these types' kind signatures are displayed above their declarations + in their docs, similar to what one would see in the source code. + Bugfixes: * Ensure unnamed instances appear in documentation (#4109 by @JordanMartinez)