API.dcl 11.8 KB
Newer Older
1
definition module Cloogle.API
2

Camil Staps's avatar
Camil Staps committed
3 4 5 6 7
/**
 * The API for Cloogle, a Clean search engine.
 * https://cloogle.org
 */

Camil Staps's avatar
Camil Staps committed
8
from StdOverloaded import class zero, class fromString, class toString,
Camil Staps's avatar
Camil Staps committed
9
	class fromInt, class toInt, class <, class ==
10

11
from Data.Error import :: MaybeError, :: MaybeErrorString
12
from Data.GenEq import generic gEq
13
from Data.Maybe import :: Maybe
14
from Text.GenJSON import generic JSONEncode, generic JSONDecode, :: JSONNode
15

Camil Staps's avatar
Camil Staps committed
16
/**
Camil Staps's avatar
Camil Staps committed
17
 * A Cloogle request.
Camil Staps's avatar
Camil Staps committed
18
 */
19 20 21
:: Request =
	{ unify            :: Maybe String   //* Functions that unify with this type
	, name             :: Maybe String   //* Entries that match this name
22 23 24
	, exactName        :: Maybe String   //* Exactly this name
	, className        :: Maybe String   //* Exactly this name, and a class
	, typeName         :: Maybe String   //* Exactly this name, and a type
25
	, using            :: Maybe [String] //* Return everything that uses all of these exact names (types or classes)
26 27 28 29 30 31 32
	, modules          :: Maybe [String] //* Modules to search in
	, libraries        :: Maybe [String] //* Libraries to search in
	, include_builtins :: Maybe Bool     //* Whether language builtins should be included
	, include_core     :: Maybe Bool     //* Whether library core modules should be included
	, include_apps     :: Maybe Bool     //* Whether app modules should be included
	, page             :: Maybe Int      //* Pagination of the results
	}
33

Camil Staps's avatar
Camil Staps committed
34
/**
Camil Staps's avatar
Camil Staps committed
35
 * A Cloogle response.
Camil Staps's avatar
Camil Staps committed
36
 */
37
:: Response =
Camil Staps's avatar
Camil Staps committed
38
	{ return         :: Int       //* A return code (use {{`fromInt`}} of {{`CloogleError`}})
39 40 41 42 43 44
	, data           :: [Result]  //* The actual results
	, msg            :: String    //* A human-readable message describing the return code
	, more_available :: Maybe Int //* How many more results are available in next pages
	, suggestions    :: Maybe [(Request, Int)]
	                              //* Suggestions for related requests and how many results they have
	}
45

Camil Staps's avatar
Camil Staps committed
46
/**
Camil Staps's avatar
Camil Staps committed
47
 * A single Cloogle result.
Camil Staps's avatar
Camil Staps committed
48
 */
49
:: Result
Camil Staps's avatar
Camil Staps committed
50
	= FunctionResult FunctionResult //* A normal function, macro, generic, class member, constructor or record field
Camil Staps's avatar
Camil Staps committed
51 52 53
	| TypeResult TypeResult         //* A type definition
	| ClassResult ClassResult       //* A class definition
	| ModuleResult ModuleResult     //* A module
54
	| SyntaxResult SyntaxResult     //* A Clean language syntax element
Camil Staps's avatar
Camil Staps committed
55
	| ABCInstructionResult ABCInstructionResult //* An ABC machine instruction
56
	| ProblemResult ProblemResult   //* A common problem (see https://gitlab.science.ru.nl/cloogle/common-problems)
Camil Staps's avatar
Camil Staps committed
57 58

/**
Camil Staps's avatar
Camil Staps committed
59
 * Basic data that is included in any Cloogle result.
Camil Staps's avatar
Camil Staps committed
60
 */
61 62 63 64 65 66
:: BasicResult =
	{ library       :: String       //* The library the entry was found in
	, filename      :: String       //* The basename of the definition module
	, modul         :: String       //* The full (hierarchical) module name
	, dcl_line      :: Maybe Int    //* The line in the definition module of this entry
	, icl_line      :: Maybe Int    //* The line in the implementation module of this entry
67
	, name          :: String       //* The name of the entry
68
	, distance      :: Maybe Real   //* A distancy measure, lower is more relevant
69 70
	, builtin       :: Maybe Bool   //* Whether this is a builtin function
	, documentation :: Maybe String //* The CleanDoc description for this result
71 72 73 74
	, langrep_documentation :: Maybe [CleanLangReportLocation] //* Documentation in the Clean language report
	}

/**
Camil Staps's avatar
Camil Staps committed
75
 * A location in a Clean language report.
76 77 78 79 80 81
 */
:: CleanLangReportLocation =
	{ clr_version :: String //* The version of the report
	, clr_section :: String //* The section in the report
	, clr_file    :: String //* The HTML file that section belongs to
	, clr_heading :: String //* A heading in the HTML file
82
	}
83

Camil Staps's avatar
Camil Staps committed
84 85
/**
 * Cloogle result about a function, generic, class member, constructor or
Camil Staps's avatar
Camil Staps committed
86
 * record field.
Camil Staps's avatar
Camil Staps committed
87 88 89
 *
 * @representation A tuple of basic and function-specific data
 */
90
:: FunctionResult :== (BasicResult, FunctionResultExtras)
Camil Staps's avatar
Camil Staps committed
91

Camil Staps's avatar
Camil Staps committed
92
/**
Camil Staps's avatar
Camil Staps committed
93
 * Different kinds of Clean functions.
Camil Staps's avatar
Camil Staps committed
94 95 96 97 98 99
 */
:: FunctionKind
	= Function    //* A normal function or generic
	| Macro       //* A macro
	| Constructor //* An ADT constructor
	| RecordField //* A record field
100 101
	| ClassMember //* A class member
	| ClassMacro  //* A class macro
Camil Staps's avatar
Camil Staps committed
102

Camil Staps's avatar
Camil Staps committed
103
/**
Camil Staps's avatar
Camil Staps committed
104
 * Function-specific Cloogle result data.
Camil Staps's avatar
Camil Staps committed
105
 */
106 107 108 109 110 111 112 113 114 115 116 117
:: FunctionResultExtras =
	{ func                :: String         //* A string representation of the type
	, kind                :: FunctionKind   //* The kind of function
	, unifier             :: Maybe StrUnifier //* A unifier, if the request included a type
	, required_context    :: Maybe [(String, [LocationResult])] //* Instances or derivations that are needed (if the request included a type)
	, cls                 :: Maybe ShortClassResult //* The class, if this is a class member
	, constructor_of      :: Maybe String   //* The type that this is a constructor of
	, recordfield_of      :: Maybe String   //* The type that this is a record field of
	, generic_derivations :: Maybe [(String, [LocationResult])]
	    //* Derivations, if this is a generic function, and their locations
	, param_doc           :: Maybe [String] //* Documentation of the parameters
	, generic_var_doc     :: Maybe [String] //* Documentation of the generic type variables
118
	, result_doc          :: Maybe [String] //* Documentation of the result(s)
119
	, type_doc            :: Maybe String   //* Documentation of the type (for macros)
120
	, throws_doc          :: Maybe [String] //* Documentation of the exceptions
121
	}
122

Camil Staps's avatar
Camil Staps committed
123
/**
Camil Staps's avatar
Camil Staps committed
124
 * Cloogle result about a type definition.
Camil Staps's avatar
Camil Staps committed
125 126 127
 *
 * @representation A tuple of basic and type-specific data
 */
128
:: TypeResult :== (BasicResult, TypeResultExtras)
Camil Staps's avatar
Camil Staps committed
129 130

/**
Camil Staps's avatar
Camil Staps committed
131
 * Type-specific Cloogle result data.
Camil Staps's avatar
Camil Staps committed
132
 */
133 134 135 136 137 138 139 140 141 142 143 144 145 146
:: TypeResultExtras =
	{ type                    :: String
	  //* A string representation of the definition
	, type_instances          :: [(String, [String], [LocationResult])]
	  //* Instances of the type: the class, the class parameters and the locations of the instance
	, type_derivations        :: [(String, [LocationResult])]
	  //* Generic derivations of the type: the generic and the locations of the derivation
	, type_field_doc          :: Maybe [Maybe String]
	  //* Documentation of the record fields
	, type_constructor_doc    :: Maybe [Maybe String]
	  //* Documentation of the constructors
	, type_representation_doc :: Maybe String
	  //* Documentation of the synonym type representation
	}
147

Camil Staps's avatar
Camil Staps committed
148 149 150 151 152
/**
 * Cloogle result about a class definition
 *
 * @representation A tuple of basic and class-specific data
 */
153
:: ClassResult :== (BasicResult, ClassResultExtras)
Camil Staps's avatar
Camil Staps committed
154 155

/**
Camil Staps's avatar
Camil Staps committed
156
 * Class-specific Cloogle result data.
Camil Staps's avatar
Camil Staps committed
157
 */
158 159 160 161
:: ClassResultExtras =
	{ class_name        :: String   //* The name of the class
	, class_heading     :: String   //* The class name and variables
	, class_funs        :: [String] //* The class members (may contain newlines if there are macros)
162
	, class_fun_doc     :: Maybe [Maybe String] //* Documentation of the members
163 164 165
	, class_instances   :: [([String], [LocationResult])]
	  //* Instances of the class: the types and the locations of the instances
	}
166

Camil Staps's avatar
Camil Staps committed
167
/**
Camil Staps's avatar
Camil Staps committed
168
 * Cloogle result about a module.
Camil Staps's avatar
Camil Staps committed
169
 *
170
 * @representation A tuple of basic and module-specific data
Camil Staps's avatar
Camil Staps committed
171
 */
172
:: ModuleResult :== (BasicResult, ModuleResultExtras)
Camil Staps's avatar
Camil Staps committed
173 174

/**
Camil Staps's avatar
Camil Staps committed
175
 * Module-specific Cloogle result data.
Camil Staps's avatar
Camil Staps committed
176
 */
177 178 179
:: ModuleResultExtras =
	{ module_is_core :: Bool //* Whether this module is part of a library core
	}
180

Camil Staps's avatar
Camil Staps committed
181
/**
Camil Staps's avatar
Camil Staps committed
182
 * Cloogle result about a Clean language construct.
Camil Staps's avatar
Camil Staps committed
183
 *
184
 * @representation A tuple of basic and construct-specific data
Camil Staps's avatar
Camil Staps committed
185
 */
186
:: SyntaxResult :== (BasicResult, SyntaxResultExtras)
Camil Staps's avatar
Camil Staps committed
187 188

/**
Camil Staps's avatar
Camil Staps committed
189
 * Syntax contruct-specific Cloogle result data.
190 191 192 193 194 195 196 197
 */
:: SyntaxResultExtras =
	{ syntax_title        :: String //* The name of the construct
	, syntax_code         :: [String] //* Strings describing the construct, as short as possible
	, syntax_examples     :: [SyntaxExample] //* Some code examples (should include comments)
	}

/**
Camil Staps's avatar
Camil Staps committed
198
 * An example of Clean syntax.
199 200 201 202
 */
:: SyntaxExample =
	{ example       :: String       //* The actual code
	, cleanjs_start :: Maybe String //* The state in which clean.js should start highlighting
203 204
	, bootstrap     :: [String]     //* Imports and other bootstrapping code required for this example
	, requires_itask_compiler :: Bool //* Whether this example requires the iTask compiler
205 206
	}

Camil Staps's avatar
Camil Staps committed
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
/**
 * Cloogle result about an ABC instruction.
 *
 * @representation A tuple of basic and instruction-specific data.
 */
:: ABCInstructionResult :== (BasicResult, ABCInstructionResultExtras)

/**
 * Information about an ABC instruction.
 */
:: ABCInstructionResultExtras =
	{ abc_instruction :: String        //* The name of the instruction
	, abc_arguments   :: [ABCArgument] //* The arguments
	}

/**
 * An argument for an ABC instruction.
 */
:: ABCArgument = ABCArgument ABCArgumentType Bool //* The type and whether it is optional or not.

:: ABCArgumentType
	= ABCTypeLabel
229 230
	| ABCTypeAStackOffset
	| ABCTypeBStackOffset
231 232
	| ABCTypeAStackSize
	| ABCTypeBStackSize
Camil Staps's avatar
Camil Staps committed
233 234 235 236 237 238
	| ABCTypeBool
	| ABCTypeChar
	| ABCTypeInt
	| ABCTypeReal
	| ABCTypeString

239 240 241
instance toString ABCArgument, ABCArgumentType
instance fromString ABCArgument, ABCArgumentType

242
/**
243
 * Cloogle result about a common problem (see https://gitlab.science.ru.nl/cloogle/common-problems).
244 245 246 247 248 249 250 251 252
 */
:: ProblemResult =
	{ problem_key         :: String   //* The key (filename in the common-problems repo without extension)
	, problem_title       :: String   //* The problem title
	, problem_description :: String   //* A concise description
	, problem_solutions   :: [String] //* Possible solutions
	, problem_examples    :: [String] //* A number of examples
	}

Camil Staps's avatar
Camil Staps committed
253
/**
Camil Staps's avatar
Camil Staps committed
254
 * A location in a Clean library.
Camil Staps's avatar
Camil Staps committed
255
 *
256 257
 * @representation The library, the module, the filename, the line in the
 *   definition module and the line in the implementation module
Camil Staps's avatar
Camil Staps committed
258
 */
259
:: LocationResult :== (String, String, String, Maybe Int, Maybe Int)
260

Camil Staps's avatar
Camil Staps committed
261
/**
Camil Staps's avatar
Camil Staps committed
262
 * A type unifier, represented with strings.
Camil Staps's avatar
Camil Staps committed
263
 */
264 265 266 267 268
:: StrUnifier =
	{ left_to_right :: [(String,String)] //* Transformations from request to response
	, right_to_left :: [(String,String)] //* Transformations from response to request
	, used_synonyms :: [(String,String)] //* Synonyms that were used during unification
	}
269

Camil Staps's avatar
Camil Staps committed
270
/**
Camil Staps's avatar
Camil Staps committed
271
 * Basic data about a class definition.
Camil Staps's avatar
Camil Staps committed
272
 */
273 274 275 276
:: ShortClassResult =
	{ cls_name :: String   //* The name
	, cls_vars :: [String] //* The type variables
	}
277

Camil Staps's avatar
Camil Staps committed
278
/**
Camil Staps's avatar
Camil Staps committed
279
 * A Cloogle Error.
Camil Staps's avatar
Camil Staps committed
280
 */
Camil Staps's avatar
Camil Staps committed
281 282
:: CloogleError
	/* Cloogle system errors */
Camil Staps's avatar
Camil Staps committed
283 284 285 286
	= NoResults      //* No matching entries were found
	| InvalidInput   //* The input is invalid (e.g., combining typeName and className)
	| InvalidName    //* The name is invalid (e.g., contains spaces)
	| InvalidType    //* A type could not be parsed (e.g., in unify)
Camil Staps's avatar
Camil Staps committed
287
	/* Cloogle.org errors */
Camil Staps's avatar
Camil Staps committed
288 289 290 291 292
	| ServerDown     //* The Cloogle backend could not be reached
	| IllegalMethod  //* Incorrect HTTP method to the API
	| IllegalRequest //* Incorrect parameters to the API
	| ServerTimeout  //* Connection to the Cloogle backend timed out
	| DosProtection  //* Too many requests from this client, try again later
293
	| QueryTooLong   //* The query was too long
Camil Staps's avatar
Camil Staps committed
294
	/* Wildcard to make fromInt total */
Camil Staps's avatar
Camil Staps committed
295
	| OtherCloogleError String //* Another Cloogle error
Camil Staps's avatar
Camil Staps committed
296 297 298 299

instance toInt CloogleError
instance fromInt CloogleError

300
derive JSONEncode Request, Response, Result, ShortClassResult, BasicResult,
Camil Staps's avatar
Camil Staps committed
301
	FunctionResultExtras, TypeResultExtras, ClassResultExtras, FunctionKind,
302
	ModuleResultExtras, SyntaxResultExtras, SyntaxExample,
Camil Staps's avatar
Camil Staps committed
303 304
	ABCInstructionResultExtras, ABCArgument, CleanLangReportLocation,
	StrUnifier
305
derive JSONDecode Request, Response, Result, ShortClassResult, BasicResult,
Camil Staps's avatar
Camil Staps committed
306
	FunctionResultExtras, TypeResultExtras, ClassResultExtras, FunctionKind,
307
	ModuleResultExtras, SyntaxResultExtras, SyntaxExample,
Camil Staps's avatar
Camil Staps committed
308 309
	ABCInstructionResultExtras, ABCArgument, CleanLangReportLocation,
	StrUnifier
Camil Staps's avatar
Camil Staps committed
310
derive gEq FunctionKind
311 312

instance zero Request
Camil Staps's avatar
Camil Staps committed
313
instance zero Response
314 315

instance toString Request
Camil Staps's avatar
Camil Staps committed
316
instance toString Response
317 318 319 320 321

instance fromString (Maybe Request)

instance < BasicResult
instance < Result
Camil Staps's avatar
Camil Staps committed
322 323

instance == FunctionKind
324

Camil Staps's avatar
Camil Staps committed
325
getBasicResult :: !Result -> Maybe BasicResult
Camil Staps's avatar
Camil Staps committed
326

327 328
toSingleLine :: !Request -> Maybe String
parseSingleLineRequest :: !String -> MaybeErrorString Request