diff --git a/CHANGELOG.md b/CHANGELOG.md index 86cda9f..fce3a30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Changes: - Package structure change: `dist/purescript-docs-search.cjs` has been moved to `dist/purescript-docs-search.cjs` due to NodeJS restrictions for `type: module` packages. +- Improve output for data and newtype constuctors ([#58](https://github.com/purescript/purescript-docs-search/pull/58)) New features: - Docs for each CLI option diff --git a/src/Docs/Search/Declarations.purs b/src/Docs/Search/Declarations.purs index c7272a9..8082031 100644 --- a/src/Docs/Search/Declarations.purs +++ b/src/Docs/Search/Declarations.purs @@ -11,7 +11,7 @@ import Prim hiding (Type) import Control.Alt ((<|>)) import Data.Array ((!!)) import Data.Array as Array -import Data.Foldable (foldr) +import Data.Foldable (foldl, foldr) import Data.List (List, (:)) import Data.List as List import Data.Maybe (Maybe(..), fromMaybe) @@ -244,8 +244,33 @@ mkChildInfo (SearchResult { info: parentInfo, moduleName, name: resultName }) (ChildDeclaration { info } ) - | ChildDeclDataConstructor <- info.declType = - info.arguments <#> \arguments -> DataConstructorResult { arguments } + | ChildDeclDataConstructor <- info.declType + , DataResult { dataDeclType, typeArguments } <- parentInfo = + let + parentTypeCtor :: Type + parentTypeCtor = TypeConstructor + $ QualifiedName { moduleNameParts: + String.split (wrap ".") (unwrap moduleName) + , name: resultName } + + parentTypeArgs :: Array Type + parentTypeArgs = typeArguments <#> unwrap >>> \{ name } -> TypeVar name + + parentType :: Type + parentType = foldl TypeApp parentTypeCtor parentTypeArgs + + typeArrow :: Type -> Type + typeArrow = + TypeApp (TypeConstructor (QualifiedName { moduleNameParts: [ "Prim" ] + , name: Identifier "Function" })) + + makeType :: Array Type -> Type + makeType = foldr (\a b -> TypeApp (typeArrow a) b) parentType + in + info.arguments <#> \arguments -> + DataConstructorResult { dataDeclType + , "type": makeType arguments + } | ChildDeclTypeClassMember <- info.declType , TypeClassResult { arguments } <- parentInfo = diff --git a/src/Docs/Search/Interactive.purs b/src/Docs/Search/Interactive.purs index 892ca0d..7c38c5b 100644 --- a/src/Docs/Search/Interactive.purs +++ b/src/Docs/Search/Interactive.purs @@ -194,6 +194,9 @@ showSignature result@{ name, info } = ValueAliasResult -> yellow ("(" <> unwrap name <> ")") + DataConstructorResult info' -> + showDataConstructorSignature info' result + _ -> yellow $ unwrap name @@ -294,11 +297,33 @@ showExternDataSignature { kind } { name } = keyword "foreign data" <> space <> yellow (unwrap name) <> - space <> syntax " :: " <> showType kind +showDataConstructorSignature + :: forall rest + . { dataDeclType :: DataDeclType + , "type" :: Type + } + -> { name :: Identifier + | rest + } + -> String +showDataConstructorSignature { dataDeclType, type: ctorType } { name } = + ( keyword + case dataDeclType of + NewtypeDataDecl -> "newtype constructor" + DataDataDecl -> "data constructor" + ) <> + space <> + yellow (unwrap name) <> + space <> + syntax "::" <> + space <> + showType ctorType + + leftShift :: Int -> String -> String leftShift shift str = Array.intercalate "\n" $ diff --git a/src/Docs/Search/SearchResult.purs b/src/Docs/Search/SearchResult.purs index 62d8757..821903c 100644 --- a/src/Docs/Search/SearchResult.purs +++ b/src/Docs/Search/SearchResult.purs @@ -22,7 +22,8 @@ data ResultInfo | ExternDataResult { kind :: Type } | TypeSynonymResult { arguments :: Array TypeArgument , type :: Type } - | DataConstructorResult { arguments :: Array Type } + | DataConstructorResult { dataDeclType :: DataDeclType + , type :: Type } | TypeClassMemberResult { type :: Type , typeClass :: QualifiedName , typeClassArguments :: Array TypeArgument }