CloogleDB.dcl 10.2 KB
Newer Older
Camil Staps's avatar
Camil Staps committed
1 2
definition module CloogleDB

3
from StdOverloaded import class ==, class <, class zero
Camil Staps's avatar
Camil Staps committed
4 5
from StdClass import class Ord

Camil Staps's avatar
Camil Staps committed
6
from Data.GenEq import generic gEq
Camil Staps's avatar
Camil Staps committed
7 8
from Data.Map import :: Map
from Data.Maybe import :: Maybe
Camil Staps's avatar
Camil Staps committed
9
from System.FilePath import :: FilePath
10
from Text.GenJSON import generic JSONEncode, generic JSONDecode, :: JSONNode
Camil Staps's avatar
Camil Staps committed
11 12

from Type import :: Type, :: TypeVar, :: TVAssignment, :: TypeDef,
13
	:: TypeContext, :: TypeRestriction, :: Priority, class print(..)
Camil Staps's avatar
Camil Staps committed
14

Camil Staps's avatar
Camil Staps committed
15
from Cloogle import :: FunctionKind, :: SyntaxExample, :: CleanLangReportLocation
Camil Staps's avatar
Camil Staps committed
16

17
from Doc import :: FunctionDoc, :: TypeDoc, :: ClassDoc, :: ModuleDoc
18
from DB import :: DB, :: Entry, :: Index
19
from NGramIndex import :: NGramIndex
Camil Staps's avatar
Camil Staps committed
20
from TypeTree import :: TypeTree
Camil Staps's avatar
Camil Staps committed
21 22 23 24

/**
 * A storage for function types, class definitions, type definitions, etc.
 */
25
:: *CloogleDB =
26 27 28 29 30 31 32 33 34 35 36 37 38
	{ db            :: !*DB CloogleEntry AnnotationKey Int //* Core data
	, name_ngrams   :: !NGramIndex Index //* Name ngrams
	, name_map      :: !Map Name [Index] //* For exact name search
	, types         :: !TypeTree Index   //* Types, map to FunctionEntries
	, core          :: ![Index]          //* Entries in core modules
	, apps          :: ![Index]          //* Entries in app modules
	, builtins      :: ![Index]          //* Entries in Clean core
	, syntax        :: ![Index]          //* SyntaxEntries
	, library_map   :: !Map Name [Index] //* Entries by library name
	, module_map    :: !Map Name [Index] //* Entries by module name
	, derive_map    :: !Map Name [Index] //* DeriveEntries by generic name
	, instance_map  :: !Map Name [Index] //* InstanceEntries by class name
	, always_unique :: !Map Name ()     //* Types that are always unique, like World
39 40
	}

Camil Staps's avatar
Camil Staps committed
41 42 43
/**
 * Information about a {{`CloogleDB`}}. Can be retrieved with {{`dbStats`}}.
 */
Camil Staps's avatar
Camil Staps committed
44 45 46 47 48 49 50 51 52 53 54 55 56
:: CloogleDBStats =
	{ n_modules             :: Int
	, n_functions           :: Int
	, n_functions_with_type :: Int
	, n_unique_types        :: Int
	, type_tree_depth       :: Int
	, n_type_definitions    :: Int
	, n_classes             :: Int
	, n_instances           :: Int
	, n_derivations         :: Int
	, n_syntax_constructs   :: Int
	}

Camil Staps's avatar
Camil Staps committed
57 58 59
/**
 * Annotations to store during search.
 */
60
:: AnnotationKey
Camil Staps's avatar
Camil Staps committed
61 62
	= MatchingNGrams //* For name search, the number of matching ngrams
	| UnifierSize    //* For type search, the 'size' of the unifier
63
	| ExactResult    //* 1 if this was an exact match found with filterExactName
64 65 66 67

instance == AnnotationKey
instance < AnnotationKey

Camil Staps's avatar
Camil Staps committed
68 69 70
/**
 * Wrapper around different kinds of entries to store all in one database.
 */
71 72 73 74 75 76 77 78 79 80 81
:: CloogleEntry
	= FunctionEntry FunctionEntry
	| TypeDefEntry  TypeDefEntry
	| ModuleEntry   ModuleEntry
	| ClassEntry    ClassEntry
	| InstanceEntry InstanceEntry
	| DeriveEntry   DeriveEntry
	| SyntaxEntry   SyntaxEntry

derive JSONEncode CloogleEntry
derive JSONDecode CloogleEntry
Camil Staps's avatar
Camil Staps committed
82 83 84 85 86

/**
 * A location in the Clean libraries
 */
:: Location
Camil Staps's avatar
Camil Staps committed
87
	= Location !Library !Module !FilePath !LineNr !LineNr !Name //* A normal location
88
	| Builtin !Name ![CleanLangReportLocation] //* A language builtin
89
	| NoLocation //* Only used internally
Camil Staps's avatar
Camil Staps committed
90

Camil Staps's avatar
Camil Staps committed
91 92 93 94 95 96
/**
 * Wrapper around {{`Location`}} for use in {{`CloogleDBFactory`}} to avoid
 * name clashes with {{`Module`}} in the compiler.
 */
location :: !Library !String !FilePath !LineNr !LineNr !Name -> Location

Camil Staps's avatar
Camil Staps committed
97 98 99 100
/**
 * Not-type information that is often associated with things that have a type
 */
:: FunctionEntry
101 102
	= { fe_loc            :: !Location       //* The location
	  , fe_kind           :: !FunctionKind   //* The type of entry
Camil Staps's avatar
Camil Staps committed
103 104 105 106 107
	  , fe_type           :: !Maybe Type     //* The type, Nothing for macros
	  , fe_priority       :: !Maybe Priority //* The infix priority
	  , fe_generic_vars   :: !Maybe [String] //* The names of the type variables of a generic function
	    // Using TypeVar causes import clashes in CloogleDBFactory
	  , fe_representation :: !Maybe String   //* A string representation of the entry
108
	  , fe_documentation  :: !Maybe FunctionDoc //* Documentation on this entry
109
	  , fe_class          :: !Maybe Index    //* The class, for class members
110
	  , fe_derivations    :: !Maybe [Index]  //* The DerivaionEntries
111
	  , fe_usages         :: ![Index]        //* FunctionEntries where the implementation uses this function
Camil Staps's avatar
Camil Staps committed
112 113 114 115 116 117
	  }

/**
 * A TypeDef with meta-data
 */
:: TypeDefEntry
118 119 120 121 122
	= { tde_loc         :: !Location      //* The location
	  , tde_typedef     :: !TypeDef       //* The TypeDef
	  , tde_doc         :: !Maybe TypeDoc //* Documentation on the TypeDef
	  , tde_instances   :: ![Index]       //* Instances of this type
	  , tde_derivations :: ![Index]       //* Derivations of this type
123
	  , tde_usages      :: ![Index]       //* FunctionEntries using the type
Camil Staps's avatar
Camil Staps committed
124 125 126 127 128 129
	  }

/**
 * Information about a Clean module
 */
:: ModuleEntry
130 131
	= { me_loc           :: !Location        //* The location
	  , me_is_core       :: !Bool            //* Whether this is a core module (e.g. the os* modules in ObjectIO and TCPIP)
132 133
	  , me_is_app        :: !Bool            //* Whether this module is not actually a library but an app
	  , me_documentation :: !Maybe ModuleDoc //* Documentation on this module
134
	  , me_usages        :: ![Index]         //* Modules importing this module
Camil Staps's avatar
Camil Staps committed
135 136 137 138 139 140
	  }

/**
 * Information about a Clean class
 */
:: ClassEntry
141 142
	= { ce_loc           :: !Location       //* The location
	  , ce_vars          :: ![String]       //* The type variables of the class
Camil Staps's avatar
Camil Staps committed
143
	    // Using TypeVar causes import clashes in CloogleDBFactory
144
	  , ce_is_meta       :: !Bool           //* Whether this is a meta class (no non-macro members and not TC)
145 146
	  , ce_context       :: !TypeContext    //* A class context
	  , ce_documentation :: !Maybe ClassDoc //* Documentation on this class
Camil Staps's avatar
Camil Staps committed
147
	  , ce_members       :: [Index]         //* Class members (FunctionEntries; must be lazy for CloogleDBFactory to work)
148 149
	  , ce_instances     :: ![Index]        //* All instances of the class
	  , ce_derivations   :: ![Index]        //* Derivations of generic meta-classes like iTask
Camil Staps's avatar
Camil Staps committed
150
	  , ce_usages        :: ![Index]        //* FunctionEntries, TypeDefEntries and ClassEntries using this class
Camil Staps's avatar
Camil Staps committed
151 152 153 154 155 156
	  }

/**
 * Information about a class instance
 */
:: InstanceEntry
157 158 159
	= { ie_class     :: Name             //* The class
	  , ie_types     :: [(Type, String)] //* The instantiated type and a string representation for each class variable
	  , ie_locations :: [Location]       //* The places where this instance is found
Camil Staps's avatar
Camil Staps committed
160 161 162 163 164 165
	  }

/**
 * Information about a generic derivation
 */
:: DeriveEntry
166 167
	= { de_generic             :: !Name       //* The generic
	  , de_type                :: !Type       //* The type to derive an instance for
168 169
	  , de_type_representation :: !String     //* A string representation of the type
	  , de_locations           :: ![Location] //* The locations in which the derivation occurs
Camil Staps's avatar
Camil Staps committed
170 171
	  }

172 173
/**
 * Information about a syntax construct
174 175
 * This is very similar to {{`SyntaxResultExtras`}}, but also includes a
 * description string.
176
 */
177
:: SyntaxEntry =
Camil Staps's avatar
Camil Staps committed
178
	{ syntax_title         :: String //* The name of the construct
Camil Staps's avatar
Camil Staps committed
179
	, syntax_patterns      :: [String] //* Patterns to search for the construct
Camil Staps's avatar
Camil Staps committed
180 181 182 183
	, syntax_code          :: [String] //* Strings describing the construct, as short as possible
	, syntax_description   :: String //* A description for documentation
	, syntax_doc_locations :: [CleanLangReportLocation] //* Where to find documentation on the construct
	, syntax_examples      :: [SyntaxExample] //* Some code examples (should include comments)
184
	}
185

186 187 188 189 190
/**
 * A search pattern for syntax constructs
 */
:: SyntaxPattern :== String

Camil Staps's avatar
Camil Staps committed
191
patternMatches :: !SyntaxPattern !String -> Bool
192

Camil Staps's avatar
Camil Staps committed
193 194 195 196 197
:: Name    :== String
:: Library :== String
:: Module  :== String
:: LineNr  :== Maybe Int

198
instance zero Location
199
instance == Location
Camil Staps's avatar
Camil Staps committed
200 201 202
instance zero FunctionEntry
instance zero ModuleEntry

Camil Staps's avatar
Camil Staps committed
203
instance print (!Name, !FunctionEntry)
Camil Staps's avatar
Camil Staps committed
204

Camil Staps's avatar
Camil Staps committed
205
class getLocation a :: !a -> Maybe Location
206 207 208 209 210 211
instance getLocation FunctionEntry
instance getLocation TypeDefEntry
instance getLocation ModuleEntry
instance getLocation ClassEntry
instance getLocation CloogleEntry

Camil Staps's avatar
Camil Staps committed
212 213
getLibrary :: !Location -> Maybe Name
getModule :: !Location -> Maybe Name
214
setModule :: !Name !Location -> Location
Camil Staps's avatar
Camil Staps committed
215 216 217 218 219 220
getFilename :: !Location -> Maybe String
getDclLine :: !Location -> Maybe Int
getIclLine :: !Location -> Maybe Int
getName :: !Location -> Name
setName :: !Name !Location -> Location
isBuiltin :: !Location -> Bool
Camil Staps's avatar
Camil Staps committed
221

Camil Staps's avatar
Camil Staps committed
222 223 224 225
toTypeDefEntry :: !Location !TypeDef !(Maybe TypeDoc) -> TypeDefEntry
getTypeDef :: !TypeDefEntry -> TypeDef
getTypeDefDoc :: !TypeDefEntry -> Maybe TypeDoc
mergeTypeDefEntries :: !TypeDefEntry !TypeDefEntry -> TypeDefEntry
Camil Staps's avatar
Camil Staps committed
226 227 228 229

/**
 * Wrapper around the Class record field to work around name clashes
 *
230
 * @param The location of the class
Camil Staps's avatar
Camil Staps committed
231
 * @param The type variables of the class
232
 * @param Whether this is a meta class
Camil Staps's avatar
Camil Staps committed
233
 * @param The class context
234
 * @param The documentation
Camil Staps's avatar
Camil Staps committed
235 236
 * @result A Class record with those data
 */
Camil Staps's avatar
Camil Staps committed
237 238
toClass :: !Location ![String] !Bool !TypeContext !(Maybe ClassDoc) -> ClassEntry
classContext :: !ClassEntry -> [TypeRestriction]
Camil Staps's avatar
Camil Staps committed
239

Camil Staps's avatar
Camil Staps committed
240
saveDB :: !*CloogleDB !*File -> *(!*CloogleDB, !*File)
241
openDB :: !*File -> *(!Maybe *CloogleDB, !*File)
Camil Staps's avatar
Camil Staps committed
242

Camil Staps's avatar
Camil Staps committed
243 244 245
/**
 * Reset the database (count everything as included again).
 */
Camil Staps's avatar
Camil Staps committed
246 247
resetDB :: !*CloogleDB -> *CloogleDB

Camil Staps's avatar
Camil Staps committed
248
dbStats :: !*CloogleDB -> *(CloogleDBStats, *CloogleDB)
Camil Staps's avatar
Camil Staps committed
249 250 251 252

/**
 * Write the type tree as dot graph to a file.
 */
Camil Staps's avatar
Camil Staps committed
253
writeTypeTree :: !*CloogleDB !*File -> *(*CloogleDB, *File)
Camil Staps's avatar
Camil Staps committed
254

255 256
getIndex :: !Index !*CloogleDB -> *(Entry CloogleEntry AnnotationKey Int, *CloogleDB)
getIndices :: ![Index] !*CloogleDB -> *([Entry CloogleEntry AnnotationKey Int], *CloogleDB)
257 258

filterDB :: (CloogleEntry -> Bool) !*CloogleDB -> *CloogleDB
Camil Staps's avatar
Camil Staps committed
259 260
excludeCore :: !*CloogleDB -> *CloogleDB
excludeApps :: !*CloogleDB -> *CloogleDB
Camil Staps's avatar
Camil Staps committed
261 262
excludeBuiltins :: !*CloogleDB -> *CloogleDB
includeBuiltins :: !*CloogleDB -> *CloogleDB
263 264
filterLibraries :: ![Name] !*CloogleDB -> *CloogleDB
filterModules :: ![Name] !*CloogleDB -> *CloogleDB
265
filterName :: !String !*CloogleDB -> *CloogleDB
266
filterExactName :: !String !*CloogleDB -> *CloogleDB
Camil Staps's avatar
Camil Staps committed
267
filterUnifying :: !Type !*CloogleDB -> *CloogleDB
268

Camil Staps's avatar
Camil Staps committed
269
filterUsages :: ![String] !*CloogleDB -> *CloogleDB
270

271
allTypeSynonyms :: !*CloogleDB -> *(Map Name [TypeDef], *CloogleDB)
272
alwaysUniquePredicate :: !*CloogleDB -> *(String -> Bool, *CloogleDB)
Camil Staps's avatar
Camil Staps committed
273 274
getInstances :: !Name !*CloogleDB -> *([InstanceEntry], *CloogleDB)
getDerivations :: !Name !*CloogleDB -> *([DeriveEntry], *CloogleDB)
275

276
getEntries :: !*CloogleDB -> *([(CloogleEntry, Map AnnotationKey Int)], *CloogleDB)