do
var cla = self.model.get_mclasses_by_name(name)
if cla == null then
- if name == "Bool" then
+ if name == "Bool" and self.model.get_mclasses_by_name("Object") != null then
+ # Bool is injected because it is needed by engine to code the result
+ # of the implicit casts.
var c = new MClass(self, name, null, enum_kind, public_visibility)
var cladef = new MClassDef(self, c.mclass_type, new Location(null, 0,0,0,0))
+ cladef.set_supertypes([object_type])
+ cladef.add_in_hierarchy
return c
end
print("Fatal Error: no primitive class {name}")
redef var name: String
# The canonical name of the class
+ #
+ # It is the name of the class prefixed by the full_name of the `intro_mmodule`
# Example: `"owner::module::MyClass"`
- fun full_name: String
- do
- return "{self.intro_mmodule.full_name}::{name}"
+ redef var full_name is lazy do
+ return "{self.intro_mmodule.namespace_for(visibility)}::{name}"
+ end
+
+ redef var c_name is lazy do
+ return "{intro_mmodule.c_namespace_for(visibility)}__{name.to_cmangle}"
end
# The number of generic formal parameters
# is empty if the class is not generic
var mparameters = new Array[MParameterType]
+ # Initialize `mparameters` from their names.
protected fun setup_parameter_names(parameter_names: nullable Array[String]) is
autoinit
do
# Actually the name of the `mclass`
redef fun name do return mclass.name
+ # The module and class name separated by a '#'.
+ #
+ # The short-name of the class is used for introduction.
+ # Example: "my_module#MyClass"
+ #
+ # The full-name of the class is used for refinement.
+ # Example: "my_module#intro_module::MyClass"
+ redef var full_name is lazy do
+ if is_intro then
+ # 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
+ # public gives 'q::n#p::A'
+ # private gives 'q::n#p::m::A'
+ return "{mmodule.full_name}#{mclass.full_name}"
+ else if mclass.visibility > private_visibility then
+ # public gives 'p::n#A'
+ return "{mmodule.full_name}#{mclass.name}"
+ else
+ # private gives 'p::n#::m::A' (redundant p is omitted)
+ return "{mmodule.full_name}#::{mclass.intro_mmodule.name}::{mclass.name}"
+ end
+ end
+
+ 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
+ return "{mmodule.c_name}___{mclass.name.to_cmangle}"
+ else
+ return "{mmodule.c_name}___{mclass.c_name}"
+ end
+ end
+
redef fun model do return mmodule.model
# All declared super-types
redef fun to_s do return mclass.to_s
+ redef fun full_name do return mclass.full_name
+
+ redef fun c_name do return mclass.c_name
+
redef fun need_anchor do return false
redef fun anchor_to(mmodule: MModule, anchor: MClassType): MClassType
self.to_s = "{mclass}[{arguments.join(", ")}]"
end
- # Recursively print the type of the arguments within brackets.
+ # 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
+ # 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]]"`
+ redef var full_name is lazy do
+ var args = new Array[String]
+ for t in arguments do
+ args.add t.full_name
+ end
+ return "{mclass.full_name}[{args.join(", ")}]}"
+ end
+
+ redef var c_name is lazy do
+ var res = mclass.c_name
+ # Note: because the arity is known, a prefix notation is enough
+ for t in arguments do
+ res += "__"
+ res += t.c_name
+ end
+ return res.to_s
+ end
+
redef var need_anchor: Bool is noinit
redef fun resolve_for(mtype, anchor, mmodule, cleanup_virtual)
end
redef fun to_s do return self.mproperty.to_s
+
+ redef fun full_name do return self.mproperty.full_name
+
+ redef fun c_name do return self.mproperty.c_name
end
# The type associated to a formal parameter generic type of a class
redef fun to_s do return name
+ redef var full_name is lazy do return "{mclass.full_name}::{name}"
+
+ redef var c_name is lazy do return mclass.c_name + "__" + "#{name}".to_cmangle
+
redef fun lookup_bound(mmodule: MModule, resolved_receiver: MType): MType
do
assert not resolved_receiver.need_anchor
redef var to_s: String is noinit
+ redef var full_name is lazy do return "nullable {mtype.full_name}"
+
+ redef var c_name is lazy do return "nullable__{mtype.c_name}"
+
redef fun need_anchor do return mtype.need_anchor
redef fun as_nullable do return self
redef fun as_notnullable do return mtype
super MType
redef var model: Model
redef fun to_s do return "null"
+ redef fun full_name do return "null"
+ redef fun c_name do return "null"
redef fun as_nullable do return self
redef fun need_anchor do return false
redef fun resolve_for(mtype, anchor, mmodule, cleanup_virtual) do return self
end
end
+ # Returns a new parameter with the `mtype` resolved.
+ # See `MType::resolve_for` for details.
fun resolve_for(mtype: MType, anchor: nullable MClassType, mmodule: MModule, cleanup_virtual: Bool): MParameter
do
if not self.mtype.need_anchor then return self
# The (short) name of the property
redef var name: String
- # The canonical name of the property
- # Example: "owner::my_module::MyClass::my_method"
- fun full_name: String
- do
- return "{self.intro_mclassdef.mmodule.full_name}::{self.intro_mclassdef.mclass.name}::{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"
+ redef var full_name is lazy do
+ return "{intro_mclassdef.mmodule.namespace_for(visibility)}::{intro_mclassdef.mclass.name}::{name}"
+ end
+
+ redef var c_name is lazy do
+ # FIXME use `namespace_for`
+ return "{intro_mclassdef.mmodule.c_name}__{intro_mclassdef.mclass.name.to_cmangle}__{name.to_cmangle}"
end
# The visibility of the property
# Actually the name of the `mproperty`
redef fun name do return mproperty.name
+ # The full-name of mpropdefs combine the information about the `classdef` and the `mproperty`.
+ #
+ # Therefore the combination of identifiers is awful,
+ # the worst case being
+ #
+ # * a property "p::m::A::x"
+ # * redefined in a refinement of a class "q::n::B"
+ # * in a module "r::o"
+ # * so "r::o#q::n::B#p::m::A::x"
+ #
+ # Fortunately, the full-name is simplified when entities are repeated.
+ # For the previous case, the simplest form is "p#A#x".
+ redef var full_name is lazy do
+ var res = new FlatBuffer
+
+ # The first part is the mclassdef. Worst case is "r::o#q::n::B"
+ res.append mclassdef.full_name
+
+ res.append "#"
+
+ if mclassdef.mclass == mproperty.intro_mclassdef.mclass then
+ # intro are unambiguous in a class
+ res.append name
+ else
+ # Just try to simplify each part
+ if mclassdef.mmodule.mproject != mproperty.intro_mclassdef.mmodule.mproject 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,
+ # does the module part ("::m") need to be displayed
+ if mclassdef.mmodule.namespace_for(mclassdef.mclass.visibility) != mproperty.intro_mclassdef.mmodule.mproject then
+ res.append "::"
+ res.append mproperty.intro_mclassdef.mmodule.name
+ res.append "::"
+ end
+ end
+ if mclassdef.mclass != mproperty.intro_mclassdef.mclass then
+ # precise "B" only if not the same class than "A"
+ res.append mproperty.intro_mclassdef.name
+ res.append "::"
+ end
+ # Always use the property name "x"
+ res.append mproperty.name
+ end
+ return res.to_s
+ end
+
+ redef var c_name is lazy do
+ var res = new FlatBuffer
+ res.append mclassdef.c_name
+ res.append "___"
+ if mclassdef.mclass == mproperty.intro_mclassdef.mclass then
+ res.append name.to_cmangle
+ else
+ if mclassdef.mmodule != mproperty.intro_mclassdef.mmodule then
+ res.append mproperty.intro_mclassdef.mmodule.c_name
+ res.append "__"
+ end
+ if mclassdef.mclass != mproperty.intro_mclassdef.mclass then
+ res.append mproperty.intro_mclassdef.name.to_cmangle
+ res.append "__"
+ end
+ res.append mproperty.name.to_cmangle
+ end
+ return res.to_s
+ end
+
redef fun model do return mclassdef.model
# Internal name combining the module, the class and the property