forked from purescript/purescript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTypes.hs
More file actions
321 lines (271 loc) · 9.98 KB
/
Types.hs
File metadata and controls
321 lines (271 loc) · 9.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
-----------------------------------------------------------------------------
--
-- Module : Language.PureScript.Ide.Types
-- Description : Type definitions for psc-ide
-- Copyright : Christoph Hegemann 2016
-- License : MIT (http://opensource.org/licenses/MIT)
--
-- Maintainer : Christoph Hegemann <christoph.hegemann1337@gmail.com>
-- Stability : experimental
--
-- |
-- Type definitions for psc-ide
-----------------------------------------------------------------------------
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE TemplateHaskell #-}
module Language.PureScript.Ide.Types where
import Protolude
import Control.Concurrent.STM
import Control.Lens.TH
import Data.Aeson
import qualified Data.Map.Lazy as M
import qualified Language.PureScript as P
import qualified Language.PureScript.Errors.JSON as P
type ModuleIdent = Text
type ModuleMap a = Map P.ModuleName a
data IdeDeclaration
= IdeDeclValue IdeValue
| IdeDeclType IdeType
| IdeDeclTypeSynonym IdeTypeSynonym
| IdeDeclDataConstructor IdeDataConstructor
| IdeDeclTypeClass IdeTypeClass
| IdeDeclValueOperator IdeValueOperator
| IdeDeclTypeOperator IdeTypeOperator
| IdeDeclKind (P.ProperName 'P.KindName)
deriving (Show, Eq, Ord)
data IdeValue = IdeValue
{ _ideValueIdent :: P.Ident
, _ideValueType :: P.Type
} deriving (Show, Eq, Ord)
data IdeType = IdeType
{ _ideTypeName :: P.ProperName 'P.TypeName
, _ideTypeKind :: P.Kind
} deriving (Show, Eq, Ord)
data IdeTypeSynonym = IdeTypeSynonym
{ _ideSynonymName :: P.ProperName 'P.TypeName
, _ideSynonymType :: P.Type
} deriving (Show, Eq, Ord)
data IdeDataConstructor = IdeDataConstructor
{ _ideDtorName :: P.ProperName 'P.ConstructorName
, _ideDtorTypeName :: P.ProperName 'P.TypeName
, _ideDtorType :: P.Type
} deriving (Show, Eq, Ord)
data IdeTypeClass = IdeTypeClass
{ _ideTCName :: P.ProperName 'P.ClassName
, _ideTCInstances :: [IdeInstance]
} deriving (Show, Eq, Ord)
data IdeInstance = IdeInstance
{ _ideInstanceModule :: P.ModuleName
, _ideInstanceName :: P.Ident
, _ideInstanceTypes :: [P.Type]
, _ideInstanceConstraints :: Maybe [P.Constraint]
} deriving (Show, Eq, Ord)
data IdeValueOperator = IdeValueOperator
{ _ideValueOpName :: P.OpName 'P.ValueOpName
, _ideValueOpAlias :: P.Qualified (Either P.Ident (P.ProperName 'P.ConstructorName))
, _ideValueOpPrecedence :: P.Precedence
, _ideValueOpAssociativity :: P.Associativity
, _ideValueOpType :: Maybe P.Type
} deriving (Show, Eq, Ord)
data IdeTypeOperator = IdeTypeOperator
{ _ideTypeOpName :: P.OpName 'P.TypeOpName
, _ideTypeOpAlias :: P.Qualified (P.ProperName 'P.TypeName)
, _ideTypeOpPrecedence :: P.Precedence
, _ideTypeOpAssociativity :: P.Associativity
, _ideTypeOpKind :: Maybe P.Kind
} deriving (Show, Eq, Ord)
makePrisms ''IdeDeclaration
makeLenses ''IdeValue
makeLenses ''IdeType
makeLenses ''IdeTypeSynonym
makeLenses ''IdeDataConstructor
makeLenses ''IdeTypeClass
makeLenses ''IdeInstance
makeLenses ''IdeValueOperator
makeLenses ''IdeTypeOperator
data IdeDeclarationAnn = IdeDeclarationAnn
{ _idaAnnotation :: Annotation
, _idaDeclaration :: IdeDeclaration
} deriving (Show, Eq, Ord)
data Annotation
= Annotation
{ annLocation :: Maybe P.SourceSpan
, annExportedFrom :: Maybe P.ModuleName
, annTypeAnnotation :: Maybe P.Type
} deriving (Show, Eq, Ord)
makeLenses ''IdeDeclarationAnn
emptyAnn :: Annotation
emptyAnn = Annotation Nothing Nothing Nothing
type DefinitionSites a = Map IdeDeclNamespace a
type TypeAnnotations = Map P.Ident P.Type
newtype AstData a = AstData (ModuleMap (DefinitionSites a, TypeAnnotations))
-- ^ SourceSpans for the definition sites of Values and Types aswell as type
-- annotations found in a module
deriving (Show, Eq, Ord, Functor, Foldable)
data IdeLogLevel = LogDebug | LogPerf | LogAll | LogDefault | LogNone
deriving (Show, Eq)
data Configuration =
Configuration
{ confOutputPath :: FilePath
, confLogLevel :: IdeLogLevel
, confGlobs :: [FilePath]
}
data IdeEnvironment =
IdeEnvironment
{ ideStateVar :: TVar IdeState
, ideConfiguration :: Configuration
}
type Ide m = (MonadIO m, MonadReader IdeEnvironment m)
data IdeState = IdeState
{ ideStage1 :: Stage1
, ideStage2 :: Stage2
, ideStage3 :: Stage3
} deriving (Show)
emptyIdeState :: IdeState
emptyIdeState = IdeState emptyStage1 emptyStage2 emptyStage3
emptyStage1 :: Stage1
emptyStage1 = Stage1 M.empty M.empty
emptyStage2 :: Stage2
emptyStage2 = Stage2 (AstData M.empty)
emptyStage3 :: Stage3
emptyStage3 = Stage3 M.empty Nothing
data Stage1 = Stage1
{ s1Externs :: ModuleMap P.ExternsFile
, s1Modules :: ModuleMap (P.Module, FilePath)
} deriving (Show)
data Stage2 = Stage2
{ s2AstData :: AstData P.SourceSpan
} deriving (Show, Eq)
data Stage3 = Stage3
{ s3Declarations :: ModuleMap [IdeDeclarationAnn]
, s3CachedRebuild :: Maybe (P.ModuleName, P.ExternsFile)
} deriving (Show)
newtype Match a = Match (P.ModuleName, a)
deriving (Show, Eq, Functor)
-- | A completion as it gets sent to the editors
data Completion = Completion
{ complModule :: Text
, complIdentifier :: Text
, complType :: Text
, complExpandedType :: Text
, complLocation :: Maybe P.SourceSpan
, complDocumentation :: Maybe Text
} deriving (Show, Eq)
instance ToJSON Completion where
toJSON (Completion {..}) =
object [ "module" .= complModule
, "identifier" .= complIdentifier
, "type" .= complType
, "expandedType" .= complExpandedType
, "definedAt" .= complLocation
, "documentation" .= complDocumentation
]
data ModuleImport =
ModuleImport
{ importModuleName :: ModuleIdent
, importType :: P.ImportDeclarationType
, importQualifier :: Maybe Text
} deriving(Show)
instance Eq ModuleImport where
mi1 == mi2 =
importModuleName mi1 == importModuleName mi2
&& importQualifier mi1 == importQualifier mi2
instance ToJSON ModuleImport where
toJSON (ModuleImport mn P.Implicit qualifier) =
object $ [ "module" .= mn
, "importType" .= ("implicit" :: Text)
] ++ map (\x -> "qualifier" .= x) (maybeToList qualifier)
toJSON (ModuleImport mn (P.Explicit refs) qualifier) =
object $ [ "module" .= mn
, "importType" .= ("explicit" :: Text)
, "identifiers" .= (identifierFromDeclarationRef <$> refs)
] ++ map (\x -> "qualifier" .= x) (maybeToList qualifier)
toJSON (ModuleImport mn (P.Hiding refs) qualifier) =
object $ [ "module" .= mn
, "importType" .= ("hiding" :: Text)
, "identifiers" .= (identifierFromDeclarationRef <$> refs)
] ++ map (\x -> "qualifier" .= x) (maybeToList qualifier)
identifierFromDeclarationRef :: P.DeclarationRef -> Text
identifierFromDeclarationRef (P.TypeRef name _) = P.runProperName name
identifierFromDeclarationRef (P.ValueRef ident) = P.runIdent ident
identifierFromDeclarationRef (P.TypeClassRef name) = P.runProperName name
identifierFromDeclarationRef (P.KindRef name) = P.runProperName name
identifierFromDeclarationRef (P.ValueOpRef op) = P.showOp op
identifierFromDeclarationRef (P.TypeOpRef op) = P.showOp op
identifierFromDeclarationRef _ = ""
data Success =
CompletionResult [Completion]
| TextResult Text
| MultilineTextResult [Text]
| PursuitResult [PursuitResponse]
| ImportList [ModuleImport]
| ModuleList [ModuleIdent]
| RebuildSuccess [P.JSONError]
deriving (Show, Eq)
encodeSuccess :: (ToJSON a) => a -> Value
encodeSuccess res =
object ["resultType" .= ("success" :: Text), "result" .= res]
instance ToJSON Success where
toJSON (CompletionResult cs) = encodeSuccess cs
toJSON (TextResult t) = encodeSuccess t
toJSON (MultilineTextResult ts) = encodeSuccess ts
toJSON (PursuitResult resp) = encodeSuccess resp
toJSON (ImportList decls) = encodeSuccess decls
toJSON (ModuleList modules) = encodeSuccess modules
toJSON (RebuildSuccess modules) = encodeSuccess modules
newtype PursuitQuery = PursuitQuery Text
deriving (Show, Eq)
data PursuitSearchType = Package | Identifier
deriving (Show, Eq)
instance FromJSON PursuitSearchType where
parseJSON (String t) = case t of
"package" -> pure Package
"completion" -> pure Identifier
_ -> mzero
parseJSON _ = mzero
instance FromJSON PursuitQuery where
parseJSON o = PursuitQuery <$> parseJSON o
data PursuitResponse =
-- | A Pursuit Response for a module. Consists of the modules name and the
-- package it belongs to
ModuleResponse ModuleIdent Text
-- | A Pursuit Response for a declaration. Consist of the declaration's
-- module, name, package, type summary text
| DeclarationResponse Text ModuleIdent Text (Maybe Text) Text
deriving (Show,Eq)
instance FromJSON PursuitResponse where
parseJSON (Object o) = do
package <- o .: "package"
info <- o .: "info"
(type' :: Text) <- info .: "type"
case type' of
"module" -> do
name <- info .: "module"
pure (ModuleResponse name package)
"declaration" -> do
moduleName <- info .: "module"
ident <- info .: "title"
(text :: Text) <- o .: "text"
typ <- info .:? "typeText"
pure (DeclarationResponse moduleName ident package typ text)
_ -> mzero
parseJSON _ = mzero
instance ToJSON PursuitResponse where
toJSON (ModuleResponse name package) =
object ["module" .= name, "package" .= package]
toJSON (DeclarationResponse module' ident package type' text) =
object
[ "module" .= module'
, "ident" .= ident
, "type" .= type'
, "package" .= package
, "text" .= text
]
data IdeDeclNamespace =
-- | An identifier in the value namespace
IdeNSValue Text
-- | An identifier in the type namespace
| IdeNSType Text
-- | An identifier in the kind namespace
| IdeNSKind Text
deriving (Show, Eq, Ord)