logo

class

sys::Type

sys::Obj
  sys::Type
   1  //
   2  // Copyright (c) 2006, Brian Frank and Andy Frank
   3  // Licensed under the Academic Free License version 3.0
   4  //
   5  // History:
   6  //   4 Jan 06  Brian Frank  Creation
   7  //
   8  
   9  **
  10  ** Type defines the contract of an Obj by the slots its supports.
  11  ** Types model the inheritance relationships and provide a mapping
  12  ** for all the slots both inherited and declared.  You can create
  13  ** new types at runtime via the `Type.makeDynamic` constructor.
  14  **
  15  class Type
  16  {
  17  
  18  //////////////////////////////////////////////////////////////////////////
  19  // Management
  20  //////////////////////////////////////////////////////////////////////////
  21  
  22    **
  23    ** Find a Type by it's qualified name "pod::Type".  If the type
  24    ** doesn't exist and checked is false then return null, otherwise
  25    ** throw UnknownTypeErr.
  26    **
  27    static Type find(Str qname, Bool checked := true)
  28  
  29    **
  30    ** Find all the types annotated with the specified facet name/value
  31    ** pair.  The facet name must be declared as an indexed facet
  32    ** by an installed pod, otherwise Err is thrown.  Return an empty
  33    ** list of no matches found.
  34    **
  35    ** If 'facetVal' is a 'Type', then you may pass 'true' for 'options'
  36    ** to check 'facetVals' inheritance hierarchy.
  37    **
  38    ** See [Facet Indexing]`docLang::TypeDatabase#facetIndexing` for details.
  39    **
  40    static Type[] findByFacet(Str facetName, Obj facetVal, Obj options := null)
  41  
  42  //////////////////////////////////////////////////////////////////////////
  43  // Constructor
  44  //////////////////////////////////////////////////////////////////////////
  45  
  46    **
  47    ** Make a dynamic type which implements the specified list of existing
  48    ** types.  Only one 'class' type may be specified and it must be the
  49    ** first item in the list.  All other types must be mixins.  None of
  50    ** the 'supers' may be dynamic, abstract, final, or const.
  51    **
  52    ** Refer to [Dynamic Types]`docLang::DynamicTypes` for more details.
  53    **
  54    ** NOTE: creating dynamics using mixins is not supported yet.
  55    **
  56    new makeDynamic(Type[] supers, Str:Obj facets := null)
  57  
  58  //////////////////////////////////////////////////////////////////////////
  59  // Naming
  60  //////////////////////////////////////////////////////////////////////////
  61  
  62    **
  63    ** Parent pod which defines this type.  For parameterized types derived
  64    ** from List, Map, or Func, this method always returns the sys pod.
  65    ** Return null if dynamic type.
  66    **
  67    ** Examples:
  68    **   Str.type.pod         -> sys
  69    **   acme::Foo.type.pod   -> acme
  70    **   acme::Foo[].type.pod -> sys
  71    **
  72    Pod pod()
  73  
  74    **
  75    ** Simple name of the type such as "Str".  For parameterized types derived
  76    ** from List, Map, or Func, this method always returns "List", "Map",
  77    ** or "Func" respectively.  Return "dynamic" if dynamic type.
  78    **
  79    ** Examples:
  80    **   Str.type.name         -> "Str"
  81    **   acme::Foo.type.name   -> "Foo"
  82    **   acme::Foo[].type.name -> "List"
  83    **
  84    Str name()
  85  
  86    **
  87    ** Qualified name formatted as "pod::name".  For parameterized
  88    ** types derived from List, Map, or Func, this method always returns
  89    ** "sys::List", "sys::Map", or "sys::Func" respectively.  Return
  90    ** "dynamic" if dynamic type.
  91    **
  92    ** Examples:
  93    **   Str.type.qname         -> "sys::Str"
  94    **   acme::Foo.type.qname   -> "acme::Foo"
  95    **   acme::Foo[].type.qname -> "sys::List"
  96    **
  97    Str qname()
  98  
  99    **
 100    ** Return the formal signature of this type.  In the case of non-parameterized
 101    ** types the signature is the same as qname.  Return "dynamic" if dynamic type.
 102    ** For parameterized types derived from List, Map, or Func the signature uses
 103    ** the following special syntax:
 104    **   List -> V[]
 105    **   Map  -> [K:V]
 106    **   Func -> |A,B...->R|
 107    **
 108    ** Examples:
 109    **   Str.type.signature -> "sys::Str"
 110    **   Int[].type.signature -> "sys::Int[]"
 111    **   Int:Str.type.signature -> "[sys::Int:sys::Str]"
 112    **   Str:Buf[].type.signature -> [sys::Str:sys::Buf[]]
 113    **   |Float x->Bool|.type.signature -> "|sys::Float->sys::Bool|"
 114    **   |Float x, Int y|.type.signature -> |sys::Float,sys::Int->sys::Void|
 115    **
 116    Str signature()
 117  
 118  //////////////////////////////////////////////////////////////////////////
 119  // Inheritance
 120  //////////////////////////////////////////////////////////////////////////
 121  
 122    **
 123    ** The direct super class of this type (null for Obj).
 124    ** Return sys::Obj for all mixin types.
 125    **
 126    ** Examples:
 127    **   Obj.type.base -> null
 128    **   Int.type.base -> sys::Num
 129    **   OutStream.type.base -> sys::Obj
 130    **
 131    Type base()
 132  
 133    **
 134    ** Return the mixins directly implemented by this type.
 135    **
 136    ** Examples:
 137    **   Obj.type.mixins -> [,]
 138    **   Buf.type.mixins -> [sys::InStream, sys::OutStream]
 139    **   OutStream.type.mixins -> [,]
 140    **
 141    Type[] mixins()
 142  
 143    **
 144    ** Return a recursive flattened list of all the types this type
 145    ** inherits from.  The result list always includes this type itself.
 146    ** The result of this method represents the complete list of types
 147    ** implemented by this type - instances of this type are assignable
 148    ** to any type in this list.  All types (including mixins) will
 149    ** include sys::Obj in this list.
 150    **
 151    ** Examples:
 152    **   Obj.type.inheritance -> [sys::Obj]
 153    **   Int.type.inheritance -> [sys::Int, sys::Num, sys::Obj]
 154    **
 155    Type[] inheritance()
 156  
 157    **
 158    ** Does this type implement the specified type.  If true, then
 159    ** this type is assignable to the specified type (although the
 160    ** converse is not necessarily true).  This method provides the
 161    ** same semantics as the 'is' operator, but between two types
 162    ** rather than an instance and a type.  All types (including
 163    ** mixin types) fit 'sys::Obj'.
 164    **
 165    ** Example:
 166    **   Float.type.fits(Float.type) -> true
 167    **   Float.type.fits(Num.type)  -> true
 168    **   Float.type.fits(Obj.type)  -> true
 169    **   Float.type.fits(Str.type)  -> false
 170    **   Obj.type.fits(Float.type)  -> false
 171    **
 172    Bool fits(Type t)
 173  
 174  //////////////////////////////////////////////////////////////////////////
 175  // Generics
 176  //////////////////////////////////////////////////////////////////////////
 177  
 178    **
 179    ** A generic type contains slot signatures which may be parameterized - for
 180    ** example Map's key and value types are generic as K and V.  Fan supports
 181    ** three built-in generic types: List, Map, and Func.   A parameterized
 182    ** type such as Str[] is not a generic type (all of its generic parameters
 183    ** have been filled in).  User defined generic types are not supported in Fan.
 184    **
 185    ** Examples:
 186    **   Str.type.isGeneric   -> false
 187    **   List.type.isGeneric  -> true
 188    **   Str[].type.isGeneric -> false
 189    **
 190    Bool isGeneric()
 191  
 192    **
 193    ** If this is a parameterized type, then return the map of names to
 194    ** types.  If this is not a parameterized type return an empty map.
 195    **
 196    ** Examples:
 197    **   Str.type.params -> [:]
 198    **   Str[].type.params -> ["V":Str, "L":Str[]]
 199    **   Int:Slot.type.params -> ["K":Int, "V":Slot, "M":Int:Slot]
 200    **   |Int x, Float y->Bool|.type.params -> ["A":Int, "B":Float, "R":Bool]
 201    **
 202    Str:Type params()
 203  
 204    **
 205    ** If this is a generic type, then dynamically create a new parameterized
 206    ** type with the specified name to type map.  If this type is not generic
 207    ** then throw UnsupportedErr.  Throw ArgErr if params fails to specify
 208    ** the required parameters:
 209    **    List -> V required
 210    **    Map  -> K, V required
 211    **    Func -> R required, A-H optional
 212    **
 213    ** Examples:
 214    **   List.type.parameterize(["V":Bool.type]) -> Bool[]
 215    **   Map.type.parameterize(["K":Str.type, "V":Obj.type]) -> Str:Obj
 216    **
 217    Type parameterize(Str:Type params)
 218  
 219    **
 220    ** Convenience for List.type.parameterize(["V":this])
 221    **
 222    ** Examples:
 223    **   Int.type.toListOf -> Int[]
 224    **   Str[].type.toListOf -> Str[][]
 225    **
 226    Type toListOf()
 227  
 228  //////////////////////////////////////////////////////////////////////////
 229  // Flags
 230  //////////////////////////////////////////////////////////////////////////
 231  
 232    **
 233    ** Return if this is a dynamic type which was created at
 234    ** runtime via the `Type.makeDynamic` method.
 235    **
 236    Bool isDynamic()
 237  
 238    **
 239    ** Return if this Type is abstract and cannot be instantiated.  This
 240    ** method will always return true if the type is a mixin.
 241    **
 242    Bool isAbstract()
 243  
 244    **
 245    ** Return if this Type is a class (as opposed to enum or mixin)
 246    **
 247    Bool isClass()
 248  
 249    **
 250    ** Return if this is a const class which means instances of this
 251    ** class are immutable.
 252    **
 253    Bool isConst()
 254  
 255    **
 256    ** Return if this Type is an Enum type.
 257    **
 258    Bool isEnum()
 259  
 260    **
 261    ** Return if this Type is marked final which means it may not be subclassed.
 262    **
 263    Bool isFinal()
 264  
 265    **
 266    ** Return if this Type has internal protection scope.
 267    **
 268    Bool isInternal()
 269  
 270    **
 271    ** Return if this Type is a mixin type and cannot be instantiated.
 272    **
 273    Bool isMixin()
 274  
 275    **
 276    ** Return if this Type has public protection scope.
 277    **
 278    Bool isPublic()
 279  
 280    **
 281    ** Return if this Type was generated by the compiler.
 282    **
 283    Bool isSynthetic()
 284  
 285  //////////////////////////////////////////////////////////////////////////
 286  // Slots
 287  //////////////////////////////////////////////////////////////////////////
 288  
 289    **
 290    ** List of the all defined fields (including inherited fields).
 291    **
 292    Field[] fields()
 293  
 294    **
 295    ** List of the all defined methods (including inherited methods).
 296    **
 297    Method[] methods()
 298  
 299    **
 300    ** List of the all defined slots, both fields and methods (including
 301    ** inherited slots).
 302    **
 303    Slot[] slots()
 304  
 305    **
 306    ** Convenience for (Field)slot(name, checked)
 307    **
 308    Field field(Str name, Bool checked := true)
 309  
 310    **
 311    ** Convenience for (Method)slot(name, checked)
 312    **
 313    Method method(Str name, Bool checked := true)
 314  
 315    **
 316    ** Lookup a slot by name.  If the slot doesn't exist and checked
 317    ** is false then return null, otherwise throw UnknownSlotErr.
 318    **
 319    Slot slot(Str name, Bool checked := true)
 320  
 321    **
 322    ** Add a new slot to a dynamic type.  If not a dynamic
 323    ** type or a duplicate slot name exists, then throw Err.
 324    **
 325    ** Refer to [Dynamic Types]`docLang::DynamicTypes` for more details.
 326    **
 327    Void add(Slot slot)
 328  
 329    **
 330    ** Remove a slot from a dynamic type.  If not a dynamic
 331    ** type or the slot is inherited, then throw Err.
 332    **
 333    ** Refer to [Dynamic Types]`docLang::DynamicTypes` for more details.
 334    **
 335    Void remove(Slot slot)
 336  
 337    **
 338    ** Create a new instance of this Type using a public constructor
 339    ** called "make".  Throw Err if public constructor "make" is
 340    ** not available.
 341    **
 342    Obj make(Obj[] args := null)
 343  
 344  //////////////////////////////////////////////////////////////////////////
 345  // Facets
 346  //////////////////////////////////////////////////////////////////////////
 347  
 348    **
 349    ** Return all the facets defined for this slot or an empty map
 350    ** if no facets are defined.  If 'inherited' is true, then this method
 351    ** returns a map of all the facets of this type's `inheritance`.  If
 352    ** looking up a facet by name, then use the `facet` method which will
 353    ** provide better performance.  See the [Facets Doc]`docLang::Facets`
 354    ** for details.
 355    **
 356    Str:Obj facets(Bool inherited := false)
 357  
 358    **
 359    ** Get a facet by name, or return the 'def' is the facet is not defined.
 360    ** If 'inherited' is true, then this type's `inheritance` chain is
 361    ** searched.  See the [Facets Doc]`docLang::Facets` for details.
 362    **
 363    Obj facet(Str name, Obj def := null, Bool inherited := false)
 364  
 365  //////////////////////////////////////////////////////////////////////////
 366  // Documentation
 367  //////////////////////////////////////////////////////////////////////////
 368  
 369    **
 370    ** Return the raw fandoc for this type or null if not available.
 371    **
 372    Str doc()
 373  
 374  //////////////////////////////////////////////////////////////////////////
 375  // Conversion
 376  //////////////////////////////////////////////////////////////////////////
 377  
 378    **
 379    ** Always return signature().
 380    **
 381    override Str toStr()
 382  
 383  }