X-Git-Url: http://nitlanguage.org diff --git a/src/model/model.nit b/src/model/model.nit index cd1e570..8d6bf7a 100644 --- a/src/model/model.nit +++ b/src/model/model.nit @@ -206,6 +206,24 @@ redef class MModule # The primitive type `Int` var int_type: MClassType = self.get_primitive_class("Int").mclass_type is lazy + # The primitive type `Byte` + var byte_type: MClassType = self.get_primitive_class("Byte").mclass_type is lazy + + # The primitive type `Int8` + var int8_type: MClassType = self.get_primitive_class("Int8").mclass_type is lazy + + # The primitive type `Int16` + var int16_type: MClassType = self.get_primitive_class("Int16").mclass_type is lazy + + # The primitive type `UInt16` + var uint16_type: MClassType = self.get_primitive_class("UInt16").mclass_type is lazy + + # The primitive type `Int32` + var int32_type: MClassType = self.get_primitive_class("Int32").mclass_type is lazy + + # The primitive type `UInt32` + var uint32_type: MClassType = self.get_primitive_class("UInt32").mclass_type is lazy + # The primitive type `Char` var char_type: MClassType = self.get_primitive_class("Char").mclass_type is lazy @@ -514,6 +532,18 @@ class MClass # Is there a `new` factory to allow the pseudo instantiation? var has_new_factory = false is writable + + # Is `self` a standard or abstract class kind? + var is_class: Bool is lazy do return kind == concrete_kind or kind == abstract_kind + + # Is `self` an interface kind? + var is_interface: Bool is lazy do return kind == interface_kind + + # Is `self` an enum kind? + var is_enum: Bool is lazy do return kind == enum_kind + + # Is `self` and abstract class? + var is_abstract: Bool is lazy do return kind == abstract_kind end @@ -584,7 +614,7 @@ class MClassDef # public gives 'p#A' # private gives 'p::m#A' return "{mmodule.namespace_for(mclass.visibility)}#{mclass.name}" - else if mclass.intro_mmodule.mproject != mmodule.mproject then + else if mclass.intro_mmodule.mpackage != mmodule.mpackage then # public gives 'q::n#p::A' # private gives 'q::n#p::m::A' return "{mmodule.full_name}#{mclass.full_name}" @@ -600,7 +630,7 @@ class MClassDef redef var c_name is lazy do if is_intro then return "{mmodule.c_namespace_for(mclass.visibility)}___{mclass.c_name}" - else if mclass.intro_mmodule.mproject == mmodule.mproject and mclass.visibility > private_visibility then + else if mclass.intro_mmodule.mpackage == mmodule.mpackage and mclass.visibility > private_visibility then return "{mmodule.c_name}___{mclass.name.to_cmangle}" else return "{mmodule.c_name}___{mclass.c_name}" @@ -1250,7 +1280,7 @@ class MGenericType redef var to_s: String is noinit # The full-name of the class, then the full-name of each type arguments within brackets. - # Example: `"standard::Map[standard::String, standard::List[standard::Int]]"` + # Example: `"core::Map[core::String, core::List[core::Int]]"` redef var full_name is lazy do var args = new Array[String] for t in arguments do @@ -1697,8 +1727,32 @@ class MNullType redef fun c_name do return "null" redef fun as_nullable do return self - # Aborts on `null` - redef fun as_notnull do abort # sorry... + redef var as_notnull = new MBottomType(model) is lazy + redef fun need_anchor do return false + redef fun resolve_for(mtype, anchor, mmodule, cleanup_virtual) do return self + redef fun can_resolve_for(mtype, anchor, mmodule) do return true + + redef fun collect_mclassdefs(mmodule) do return new HashSet[MClassDef] + + redef fun collect_mclasses(mmodule) do return new HashSet[MClass] + + redef fun collect_mtypes(mmodule) do return new HashSet[MClassType] +end + +# The special universal most specific type. +# +# This type is intended to be only used internally for type computation or analysis and should not be exposed to the user. +# The bottom type can de used to denote things that are absurd, dead, or the absence of knowledge. +# +# Semantically it is the singleton `null.as_notnull`. +class MBottomType + super MType + redef var model: Model + redef fun to_s do return "bottom" + redef fun full_name do return "bottom" + redef fun c_name do return "bottom" + redef fun as_nullable do return model.null_type + redef fun as_notnull do return self redef fun need_anchor do return false redef fun resolve_for(mtype, anchor, mmodule, cleanup_virtual) do return self redef fun can_resolve_for(mtype, anchor, mmodule) do return true @@ -1717,6 +1771,15 @@ class MSignature # The each parameter (in order) var mparameters: Array[MParameter] + # Returns a parameter named `name`, if any. + fun mparameter_by_name(name: String): nullable MParameter + do + for p in mparameters do + if p.name == name then return p + end + return null + end + # The return type (null for a procedure) var return_mtype: nullable MType @@ -1762,7 +1825,7 @@ class MSignature # Example: for "(a: Int, b: Bool..., c: Char)" #-> vararg_rank=1 var vararg_rank: Int is noinit - # The number or parameters + # The number of parameters fun arity: Int do return mparameters.length redef fun to_s @@ -1869,7 +1932,7 @@ abstract class MProperty # The canonical name of the property. # # It is the short-`name` prefixed by the short-name of the class and the full-name of the module. - # Example: "my_project::my_module::MyClass::my_method" + # Example: "my_package::my_module::MyClass::my_method" redef var full_name is lazy do return "{intro_mclassdef.mmodule.namespace_for(visibility)}::{intro_mclassdef.mclass.name}::{name}" end @@ -2101,6 +2164,10 @@ class MMethod do return self.is_init end + + # A specific method that is safe to call on null. + # Currently, only `==`, `!=` and `is_same_instance` are safe + fun is_null_safe: Bool do return name == "==" or name == "!=" or name == "is_same_instance" end # A global attribute @@ -2183,14 +2250,14 @@ abstract class MPropDef res.append name else # Just try to simplify each part - if mclassdef.mmodule.mproject != mproperty.intro_mclassdef.mmodule.mproject then + if mclassdef.mmodule.mpackage != mproperty.intro_mclassdef.mmodule.mpackage then # precise "p::m" only if "p" != "r" res.append mproperty.intro_mclassdef.mmodule.full_name res.append "::" else if mproperty.visibility <= private_visibility then - # Same project ("p"=="q"), but private visibility, + # Same package ("p"=="q"), but private visibility, # does the module part ("::m") need to be displayed - if mclassdef.mmodule.namespace_for(mclassdef.mclass.visibility) != mproperty.intro_mclassdef.mmodule.mproject then + if mclassdef.mmodule.namespace_for(mclassdef.mclass.visibility) != mproperty.intro_mclassdef.mmodule.mpackage then res.append "::" res.append mproperty.intro_mclassdef.mmodule.name res.append "::"