Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing up #1040 #1065

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7ba553f
fix: Avoid long IDs for nodes in type of primitive def
georgefst Apr 17, 2023
ba08a34
refactor: Move selection types to `App.Base`
georgefst Apr 17, 2023
0ac9c71
refactor: Parameterise selection types
georgefst Apr 17, 2023
355463c
refactor!: Rename selection fields
georgefst Apr 17, 2023
580a738
refactor!: Don't use API-specific selection types
georgefst May 16, 2023
7ef54d2
refactor: Make further use of new deriving helper
georgefst Apr 20, 2023
0a67975
refactor: Applying actions takes selection
georgefst Apr 20, 2023
6b9606d
feat: Add canonical names to prim type def parameters
georgefst Apr 23, 2023
dd4c4a5
feat!: Output typedefs in API modules
georgefst Apr 23, 2023
b1c2250
feat: Expose available actions for typedefs
georgefst Apr 26, 2023
b13def1
fix: Always omit nothing fields in JSON output
georgefst Apr 27, 2023
2ccdce0
feat: Set better selections after performing typedef actions
georgefst Apr 27, 2023
17dbeb3
feat: Add actions for modifying constructor field types
georgefst May 24, 2023
04c3f83
refactor: Abstract over labelling in available actions property test
georgefst May 15, 2023
8ba3519
refactor: Match actual function names in hedgehog output
georgefst May 15, 2023
d50be49
test: Extend available actions property test to cover typedefs
georgefst May 16, 2023
d082c9e
`AddConField` - update TC
georgefst May 16, 2023
e0c0b5d
allow "renaming" a type to its old name
georgefst May 17, 2023
40b11e3
make `AddInput` work in con fields
georgefst May 17, 2023
0852e55
less strict duplicate name checking
georgefst May 23, 2023
b7915ed
refactor - updateType'
georgefst May 23, 2023
03c7185
update names in metadata when renaming type
georgefst May 23, 2023
b75d98a
detect capture when renaming type param
georgefst May 23, 2023
760d5db
WIP - more fixes needed (see TODOs, then re-run test to check for more)
georgefst May 24, 2023
0f44557
fix: better metadata on rhs of new branch when addcon; that action no…
brprice May 30, 2023
1d20ba7
fix: use cached type of scrut in transformCaseBranches...
brprice Jun 2, 2023
8d96663
chore: clarify variable naming in checkEverything
brprice Jun 2, 2023
1631114
fix: checkEverything does smartholes inside typedefs
brprice Jun 2, 2023
c2b3cae
fix: stable kind cache when AddConField
brprice Jun 2, 2023
131d9e9
chore: formatting pass
dhess Jun 9, 2023
145520d
chore: clean up warnings
dhess Jun 9, 2023
0400348
fix: work around broken test
dhess Jun 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions primer-service/exe-server/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,9 @@ instance ConvertLogMessage SomeException LogMsg where
instance ConvertLogMessage PrimerErr LogMsg where
convert (DatabaseErr e) = LogMsg e
convert (UnknownDef e) = LogMsg $ show e
convert (UnknownTypeDef e) = LogMsg $ show e
convert (UnexpectedPrimDef e) = LogMsg $ show e
convert (UnexpectedPrimTypeDef e) = LogMsg $ show e
convert (AddDefError m n e) = LogMsg $ show (m, n, e)
convert (AddTypeDefError tc vcs e) = LogMsg $ show (tc, vcs, e)
convert (ActionOptionsNoID e) = LogMsg $ show e
Expand Down
44 changes: 35 additions & 9 deletions primer-service/src/Primer/OpenAPI.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ module Primer.OpenAPI (
import Foreword

import Data.Aeson (
FromJSON,
GFromJSON,
GToEncoding,
GToJSON,
ToJSON,
Zero,
toJSON,
)
import Data.OpenApi (
Expand All @@ -27,6 +33,7 @@ import Data.OpenApi.Internal.Schema (
rename,
timeSchema,
)
import Data.Text qualified as T
import Data.Time (
UTCTime (..),
fromGregorian,
Expand All @@ -42,10 +49,11 @@ import Primer.API (
Module,
NewSessionReq,
NodeBody,
NodeSelection (..),
Prog,
Selection (..),
Selection,
Tree,
TypeDef,
ValCon,
)
import Primer.API qualified as API
import Primer.API.NodeFlavor (
Expand All @@ -56,25 +64,30 @@ import Primer.API.NodeFlavor (
)
import Primer.API.RecordPair (RecordPair)
import Primer.Action.Available qualified as Available
import Primer.App (NodeType)
import Primer.App.Base (Level)
import Primer.App (DefSelection, NodeSelection, NodeType, TypeDefSelection)
import Primer.App.Base (Level, TypeDefConsFieldSelection (..), TypeDefConsSelection (..), TypeDefNodeSelection)
import Primer.Core (
GlobalName,
GlobalNameKind (ADefName, ATyCon, AValCon),
ID (..),
LVarName,
ModuleName,
PrimCon,
TyVarName,
)
import Primer.Database (
LastModified,
Session,
SessionName,
)
import Primer.JSON (CustomJSON, PrimerJSON)
import Primer.JSON (CustomJSON (CustomJSON), PrimerJSON)
import Primer.Name (Name)
import Servant.API (FromHttpApiData (parseQueryParam), ToHttpApiData (toQueryParam))

newtype PrimerJSONNamed (s :: Symbol) a = PrimerJSONNamed a
deriving via PrimerJSON a instance (Generic a, GFromJSON Zero (Rep a)) => FromJSON (PrimerJSONNamed s a)
deriving via PrimerJSON a instance (Generic a, GToJSON Zero (Rep a), GToEncoding Zero (Rep a)) => ToJSON (PrimerJSONNamed s a)

-- $orphanInstances
--
-- We define some OpenApi orphan instances in primer-service, to avoid
Expand All @@ -89,6 +102,12 @@ instance
where
declareNamedSchema _ = genericDeclareNamedSchema (fromAesonOptions (aesonOptions @os)) (Proxy @a)

instance
(Typeable a, Generic a, GToSchema (Rep a), KnownSymbol s) =>
ToSchema (PrimerJSONNamed s a)
where
declareNamedSchema _ = rename (Just $ T.pack $ symbolVal $ Proxy @s) <$> declareNamedSchema (Proxy @(PrimerJSON a))

instance ToSchema SessionName
deriving via PrimerJSON Session instance ToSchema Session

Expand Down Expand Up @@ -120,12 +139,12 @@ deriving via Text instance (ToSchema Name)
-- at the openapi level, so api consumers do not have to deal with
-- three identical types. Note that our openapi interface is a
-- simplified view, so this collapse is in the correct spirit.
instance ToSchema (GlobalName 'ADefName) where
declareNamedSchema _ = rename (Just "GlobalName") <$> declareNamedSchema (Proxy @(PrimerJSON (GlobalName 'ADefName)))
deriving via PrimerJSONNamed "GlobalName" (GlobalName 'ADefName) instance ToSchema (GlobalName 'ADefName)
deriving via GlobalName 'ADefName instance ToSchema (GlobalName 'ATyCon)
deriving via GlobalName 'ADefName instance ToSchema (GlobalName 'AValCon)

deriving via Name instance (ToSchema LVarName)
deriving via Name instance (ToSchema TyVarName)
deriving via PrimerJSON (RecordPair a b) instance (ToSchema a, ToSchema b) => ToSchema (RecordPair a b)
deriving via PrimerJSON Tree instance ToSchema Tree
deriving via PrimerJSON API.Name instance ToSchema API.Name
Expand All @@ -135,6 +154,8 @@ deriving via PrimerJSON NodeFlavorTextBody instance ToSchema NodeFlavorTextBody
deriving via PrimerJSON NodeFlavorPrimBody instance ToSchema NodeFlavorPrimBody
deriving via PrimerJSON NodeFlavorBoxBody instance ToSchema NodeFlavorBoxBody
deriving via PrimerJSON NodeFlavorNoBody instance ToSchema NodeFlavorNoBody
deriving via PrimerJSON TypeDef instance ToSchema TypeDef
deriving via PrimerJSON ValCon instance ToSchema ValCon
deriving via PrimerJSON Def instance ToSchema Def
deriving via NonEmpty Name instance ToSchema ModuleName
deriving via PrimerJSON Module instance ToSchema Module
Expand All @@ -146,8 +167,13 @@ deriving via PrimerJSON Available.FreeInput instance ToSchema Available.FreeInpu
deriving via PrimerJSON Available.Options instance ToSchema Available.Options
deriving via PrimerJSON Available.Action instance ToSchema Available.Action
deriving via PrimerJSON ApplyActionBody instance ToSchema ApplyActionBody
deriving via PrimerJSON Selection instance ToSchema Selection
deriving via PrimerJSON NodeSelection instance ToSchema NodeSelection
deriving via PrimerJSONNamed "Selection" Selection instance ToSchema Selection
deriving via PrimerJSONNamed "TypeDefSelection" (TypeDefSelection ID) instance ToSchema (TypeDefSelection ID)
deriving via PrimerJSONNamed "TypeDefNodeSelection" (TypeDefNodeSelection ID) instance ToSchema (TypeDefNodeSelection ID)
deriving via PrimerJSONNamed "TypeDefConsSelection" (TypeDefConsSelection ID) instance ToSchema (TypeDefConsSelection ID)
deriving via PrimerJSONNamed "TypeDefConsFieldSelection" (TypeDefConsFieldSelection ID) instance ToSchema (TypeDefConsFieldSelection ID)
deriving via PrimerJSONNamed "DefSelection" (DefSelection ID) instance ToSchema (DefSelection ID)
deriving via PrimerJSONNamed "NodeSelection" (NodeSelection ID) instance ToSchema (NodeSelection ID)
deriving via PrimerJSON NodeType instance ToSchema NodeType
deriving via PrimerJSON Level instance ToSchema Level
deriving via PrimerJSON NewSessionReq instance ToSchema NewSessionReq
Expand Down
2 changes: 2 additions & 0 deletions primer-service/src/Primer/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,8 @@ serve ss q v port logger = do
DatabaseErr msg -> err500{errBody = encode msg}
UnknownDef d -> err404{errBody = "Unknown definition: " <> encode (globalNamePretty d)}
UnexpectedPrimDef d -> err400{errBody = "Unexpected primitive definition: " <> encode (globalNamePretty d)}
UnknownTypeDef d -> err404{errBody = "Unknown type definition: " <> encode (globalNamePretty d)}
UnexpectedPrimTypeDef d -> err400{errBody = "Unexpected primitive type definition: " <> encode (globalNamePretty d)}
AddDefError m md pe -> err400{errBody = "Error while adding definition (" <> s <> "): " <> show pe}
where
s = encode $ case md of
Expand Down
60 changes: 53 additions & 7 deletions primer-service/test/Tests/OpenAPI.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ import Primer.API (
Module (Module),
NewSessionReq (..),
NodeBody (BoxBody, NoBody, PrimBody, TextBody),
NodeSelection (..),
Prog (Prog),
Selection (..),
Selection,
Tree,
TypeDef (..),
ValCon (..),
viewTreeExpr,
viewTreeType,
)
Expand All @@ -45,7 +46,17 @@ import Primer.API.NodeFlavor (
)
import Primer.API.RecordPair (RecordPair (RecordPair))
import Primer.Action.Available qualified as Available
import Primer.App (Level, NodeType)
import Primer.App (
DefSelection (..),
Level,
NodeSelection (..),
NodeType,
Selection' (..),
TypeDefConsFieldSelection (TypeDefConsFieldSelection),
TypeDefConsSelection (..),
TypeDefSelection (..),
)
import Primer.App.Base (TypeDefNodeSelection (..))
import Primer.Core (GVarName, ID (ID), ModuleName, PrimCon (PrimChar, PrimInt))
import Primer.Database (
LastModified (..),
Expand All @@ -64,6 +75,7 @@ import Primer.Gen.Core.Raw (
genModuleName,
genName,
genTyConName,
genTyVarName,
genType,
genValConName,
)
Expand Down Expand Up @@ -207,6 +219,18 @@ tasty_NodeFlavorNoBody = testToJSON $ G.enumBounded @_ @NodeFlavorNoBody
genDef :: ExprGen Def
genDef = Def <$> genGVarName <*> genExprTree <*> G.maybe genTypeTree

genTypeDef :: ExprGen TypeDef
genTypeDef =
TypeDef
<$> genTyConName
<*> G.list (R.linear 0 3) genTyVarName
<*> G.list (R.linear 0 3) genName
<*> G.maybe
( G.list
(R.linear 0 3)
(ValCon <$> genValConName <*> G.list (R.linear 0 3) genTypeTree)
)

tasty_Def :: Property
tasty_Def = testToJSON $ evalExprGen 0 genDef

Expand All @@ -215,7 +239,7 @@ genModule =
Module
<$> genModuleName
<*> G.bool
<*> G.list (R.linear 0 3) genTyConName
<*> G.list (R.linear 0 3) genTypeDef
<*> G.list (R.linear 0 3) genDef

tasty_Module :: Property
Expand All @@ -224,11 +248,33 @@ tasty_Module = testToJSON $ evalExprGen 0 genModule
genNodeType :: ExprGen NodeType
genNodeType = G.enumBounded

genNodeSelection :: ExprGen NodeSelection
genNodeSelection :: ExprGen (NodeSelection ID)
genNodeSelection = NodeSelection <$> genNodeType <*> genID

genDefSelection :: ExprGen (DefSelection ID)
genDefSelection = DefSelection <$> genGVarName <*> G.maybe genNodeSelection

genTypeDefSelection :: ExprGen (TypeDefSelection ID)
genTypeDefSelection =
TypeDefSelection
<$> genTyConName
<*> G.maybe
( G.choice
[ TypeDefParamNodeSelection <$> genTyVarName
, TypeDefConsNodeSelection
<$> ( TypeDefConsSelection
<$> genValConName
<*> G.maybe (TypeDefConsFieldSelection <$> G.integral (R.linear 0 3) <*> genID)
)
]
)

genSelection :: ExprGen Selection
genSelection = Selection <$> genGVarName <*> G.maybe genNodeSelection
genSelection =
G.choice
[ SelectionDef <$> genDefSelection
, SelectionTypeDef <$> genTypeDefSelection
]

genProg :: Gen Prog
genProg = evalExprGen 0 $ Prog <$> G.list (R.linear 0 3) genModule <*> G.maybe genSelection <*> G.bool <*> G.bool
Expand Down Expand Up @@ -307,7 +353,7 @@ instance Arbitrary ApplyActionBody where
arbitrary = ApplyActionBody <$> arbitrary <*> arbitrary
instance Arbitrary Selection where
arbitrary = hedgehog $ evalExprGen 0 genSelection
instance Arbitrary NodeSelection where
instance Arbitrary (NodeSelection ID) where
arbitrary = hedgehog $ evalExprGen 0 genNodeSelection
instance Arbitrary a => Arbitrary (NonEmpty a) where
arbitrary = (:|) <$> arbitrary <*> arbitrary
Expand Down
Loading