end
end
-# An OrderedTree that can be easily refined for display purposes
+# An OrderedTree bound to MEntity.
+#
+# We introduce a new class so it can be easily refined by tools working
+# with a Model.
+class MEntityTree
+ super OrderedTree[MEntity]
+end
+
+# A MEntityTree borned to MConcern.
+#
+# TODO remove when nitdoc is fully merged with model_collect
class ConcernsTree
super OrderedTree[MConcern]
end
# 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
end
print("Fatal Error: no primitive class {name} in {self}")
exit(1)
+ abort
end
if cla.length != 1 then
var msg = "Fatal Error: more than one primitive class {name} in {self}:"
var props = self.model.get_mproperties_by_name(name)
if props == null then return null
var res: nullable MMethod = null
+ var recvtype = recv.intro.bound_mtype
for mprop in props do
assert mprop isa MMethod
- var intro = mprop.intro_mclassdef
- for mclassdef in recv.mclassdefs do
- if not self.in_importation.greaters.has(mclassdef.mmodule) then continue
- if not mclassdef.in_hierarchy.greaters.has(intro) then continue
- if res == null then
- res = mprop
- else if res != mprop then
- print("Fatal Error: ambigous property name '{name}'; conflict between {mprop.full_name} and {res.full_name}")
- abort
- end
+ if not recvtype.has_mproperty(self, mprop) then continue
+ if res == null then
+ res = mprop
+ else if res != mprop then
+ print("Fatal Error: ambigous property name '{name}'; conflict between {mprop.full_name} and {res.full_name}")
+ abort
end
end
return res
# The short name of the class
# In Nit, the name of a class cannot evolve in refinements
- redef var name: String
+ redef var name
# The canonical name of the class
#
# Internal name combining the module and the class
# Example: "mymodule#MyClass"
- redef var to_s: String is noinit
+ redef var to_s is noinit
init
do
# 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}"
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}"
end
#print "4.is {sub} a {sup}? <- no more resolution"
- assert sub isa MClassType else print "{sub} <? {sub}" # It is the only remaining type
-
- # A unfixed formal type can only accept itself
- if sup isa MFormalType then
- return false
+ if sub isa MBottomType then
+ return true
end
- if sup isa MNullType then
- # `sup` accepts only null
+ assert sub isa MClassType else print "{sub} <? {sub}" # It is the only remaining type
+
+ # Handle sup-type when the sub-type is class-based (other cases must have be identified before).
+ if sup isa MFormalType or sup isa MNullType or sup isa MBottomType then
+ # These types are not super-types of Class-based types.
return false
end
- assert sup isa MClassType # It is the only remaining type
+ assert sup isa MClassType else print "got {sup} {sub.inspect}" # It is the only remaining type
# Now both are MClassType, we need to dig
# The result is returned exactly as declared in the "type" property (verbatim).
# So it could be another formal type.
#
- # In case of conflict, the method aborts.
+ # In case of conflicts or inconsistencies in the model, the method returns a `MBottomType`.
fun lookup_bound(mmodule: MModule, resolved_receiver: MType): MType do return self
# Resolve the formal type to its simplest equivalent form.
#
# By default, return self.
# See the redefinitions for specific behavior in each kind of type.
+ #
+ # In case of conflicts or inconsistencies in the model, the method returns a `MBottomType`.
fun lookup_fixed(mmodule: MModule, resolved_receiver: MType): MType do return self
# Can the type be resolved?
# The short-name of the class, then the full-name of each type arguments within brackets.
# Example: `"Map[String, List[Int]]"`
- redef var to_s: String is noinit
+ redef var to_s 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
return res.to_s
end
- redef var need_anchor: Bool is noinit
+ redef var need_anchor is noinit
redef fun resolve_for(mtype, anchor, mmodule, cleanup_virtual)
do
redef fun lookup_bound(mmodule: MModule, resolved_receiver: MType): MType
do
- return lookup_single_definition(mmodule, resolved_receiver).bound.as(not null)
+ return lookup_single_definition(mmodule, resolved_receiver).bound or else new MBottomType(model)
end
private fun lookup_single_definition(mmodule: MModule, resolved_receiver: MType): MVirtualTypeDef
assert resolved_receiver isa MClassType # It is the only remaining type
var prop = lookup_single_definition(mmodule, resolved_receiver)
- var res = prop.bound.as(not null)
+ var res = prop.bound
+ if res == null then return new MBottomType(model)
# Recursively lookup the fixed result
res = res.lookup_fixed(mmodule, resolved_receiver)
end
if resolved_receiver isa MNullableType then resolved_receiver = resolved_receiver.mtype
if resolved_receiver isa MParameterType then
+ assert anchor != null
assert resolved_receiver.mclass == anchor.mclass
resolved_receiver = anchor.arguments[resolved_receiver.rank]
if resolved_receiver isa MNullableType then resolved_receiver = resolved_receiver.mtype
self.to_s = "nullable {mtype}"
end
- redef var to_s: String is noinit
+ redef var to_s is noinit
redef var full_name is lazy do return "nullable {mtype.full_name}"
# The is only one null type per model, see `MModel::null_type`.
class MNullType
super MType
- redef var model: Model
+ redef var model
redef fun to_s do return "null"
redef fun full_name do return "null"
redef fun c_name do return "null"
# Semantically it is the singleton `null.as_notnull`.
class MBottomType
super MType
- redef var model: Model
+ redef var model
redef fun to_s do return "bottom"
redef fun full_name do return "bottom"
redef fun c_name do return "bottom"
for i in [0..mparameters.length[ do
var parameter = mparameters[i]
if parameter.is_vararg then
- assert vararg_rank == -1
+ if vararg_rank >= 0 then
+ # If there is more than one vararg,
+ # consider that additional arguments cannot be mapped.
+ vararg_rank = -1
+ break
+ end
vararg_rank = i
end
end
self.vararg_rank = vararg_rank
end
- # The rank of the ellipsis (`...`) for vararg (starting from 0).
+ # The rank of the main ellipsis (`...`) for vararg (starting from 0).
# value is -1 if there is no vararg.
# Example: for "(a: Int, b: Bool..., c: Char)" #-> vararg_rank=1
+ #
+ # From a model POV, a signature can contain more than one vararg parameter,
+ # the `vararg_rank` just indicates the one that will receive the additional arguments.
+ # However, currently, if there is more that one vararg parameter, no one will be the main one,
+ # and additional arguments will be refused.
var vararg_rank: Int is noinit
# The number of parameters
super MEntity
# The name of the parameter
- redef var name: String
+ redef var name
# The static type of the parameter
var mtype: MType
var intro_mclassdef: MClassDef
# The (short) name of the property
- redef var name: String
+ redef var name
# 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
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 "::"
# Internal name combining the module, the class and the property
# Example: "mymodule#MyClass#mymethod"
- redef var to_s: String is noinit
+ redef var to_s is noinit
# Is self the definition that introduce the property?
- fun is_intro: Bool do return mproperty.intro == self
+ fun is_intro: Bool do return isset mproperty._intro and mproperty.intro == self
# Return the next definition in linearization of `mtype`.
#
# Note this class is basically an enum.
# FIXME: use a real enum once user-defined enums are available
class MClassKind
- redef var to_s: String
+ redef var to_s
# Is a constructor required?
var need_init: Bool