var cla = self.model.get_mclasses_by_name(name)
if cla == null then
if name == "Bool" then
- var c = new MClass(self, name, 0, enum_kind, public_visibility)
- var cladef = new MClassDef(self, c.mclass_type, new Location(null, 0,0,0,0), new Array[String])
+ 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))
return c
end
print("Fatal Error: no primitive class {name}")
# 0 if the class is not generic
var arity: Int
+ # Each generic formal parameters in order.
+ # is empty if the class is not generic
+ var mparameters = new Array[MParameterType]
+
# The kind of the class (interface, abstract class, etc.)
# In Nit, the kind of a class cannot evolve in refinements
var kind: MClassKind
# In Nit, the visibility of a class cannot evolve in refinements
var visibility: MVisibility
- init(intro_mmodule: MModule, name: String, arity: Int, kind: MClassKind, visibility: MVisibility)
+ init(intro_mmodule: MModule, name: String, parameter_names: nullable Array[String], kind: MClassKind, visibility: MVisibility)
do
self.intro_mmodule = intro_mmodule
self.name = name
- self.arity = arity
+ if parameter_names == null then
+ self.arity = 0
+ else
+ self.arity = parameter_names.length
+ end
self.kind = kind
self.visibility = visibility
intro_mmodule.intro_mclasses.add(self)
# Create the formal parameter types
if arity > 0 then
+ assert parameter_names != null
var mparametertypes = new Array[MParameterType]
for i in [0..arity[ do
- var mparametertype = new MParameterType(self, i)
+ var mparametertype = new MParameterType(self, i, parameter_names[i])
mparametertypes.add(mparametertype)
end
+ self.mparameters = mparametertypes
var mclass_type = new MGenericType(self, mparametertypes)
self.mclass_type = mclass_type
self.get_mtype_cache.add(mclass_type)
# ENSURE: `bound_mtype.mclass == self.mclass`
var bound_mtype: MClassType
- # Name of each formal generic parameter (in order of declaration)
- var parameter_names: Array[String]
-
# The origin of the definition
var location: Location
# Example: "mymodule#MyClass"
redef var to_s: String
- init(mmodule: MModule, bound_mtype: MClassType, location: Location, parameter_names: Array[String])
+ init(mmodule: MModule, bound_mtype: MClassType, location: Location)
do
- assert bound_mtype.mclass.arity == parameter_names.length
self.bound_mtype = bound_mtype
self.mmodule = mmodule
self.mclass = bound_mtype.mclass
self.location = location
mmodule.mclassdefs.add(self)
mclass.mclassdefs.add(self)
- self.parameter_names = parameter_names
self.to_s = "{mmodule}#{mclass}"
end
# FIXME: is `position` a better name?
var rank: Int
- # Internal name of the parameter type
- # Names of parameter types changes in each class definition
- # Therefore, this method return an internal name.
- # Example: return "G#1" for the second parameter of the class G
- # FIXME: add a way to get the real name in a classdef
- redef fun to_s do return "{mclass}#{rank}"
+ redef var name
+
+ redef fun to_s do return name
# Resolve the bound for a given resolved_receiver
# The result may be a other virtual type (or a parameter type)
return mtype.collect_mclassdefs(mmodule).has(mclass.intro)
end
- init(mclass: MClass, rank: Int)
+ init(mclass: MClass, rank: Int, name: String)
do
self.mclass = mclass
self.rank = rank
+ self.name = name
end
end
var nvisibility: nullable AVisibility
var mvisibility: nullable MVisibility
var arity = 0
+ var names = new Array[String]
if nclassdef isa AStdClassdef then
name = nclassdef.n_id.text
nkind = nclassdef.n_classkind
error(nvisibility, "Error: intrude is not a legal visibility for classes.")
return
end
+ # Collect formal parameter names
+ for i in [0..arity[ do
+ var nfd = nclassdef.n_formaldefs[i]
+ var ptname = nfd.n_id.text
+ if names.has(ptname) then
+ error(nfd, "Error: A formal parameter type `{ptname}' already exists")
+ return
+ end
+ for c in ptname.chars do if c >= 'a' and c<= 'z' then
+ warning(nfd, "formal-type-name", "Warning: lowercase in the formal parameter type {ptname}")
+ break
+ end
+ names.add(ptname)
+ end
+
else if nclassdef isa ATopClassdef then
name = "Object"
nkind = null
error(nclassdef, "Redef error: No imported class {name} to refine.")
return
end
- mclass = new MClass(mmodule, name, arity, mkind, mvisibility)
+ mclass = new MClass(mmodule, name, names, mkind, mvisibility)
#print "new class {mclass}"
else if nclassdef isa AStdClassdef and nmodule.mclass2nclassdef.has_key(mclass) then
error(nclassdef, "Error: A class {name} is already defined at line {nmodule.mclass2nclassdef[mclass].location.line_start}.")
return
end
- var names = new Array[String]
var bounds = new Array[MType]
if nclassdef isa AStdClassdef and mclass.arity > 0 then
- # Collect formal parameter names
+ # Revolve bound for formal parameters
for i in [0..mclass.arity[ do
- var nfd = nclassdef.n_formaldefs[i]
- var ptname = nfd.n_id.text
- if names.has(ptname) then
- error(nfd, "Error: A formal parameter type `{ptname}' already exists")
- return
- end
- for c in ptname.chars do if c >= 'a' and c<= 'z' then
- warning(nfd, "formal-type-name", "Warning: lowercase in the formal parameter type {ptname}")
- break
- end
- names.add(ptname)
- nfd.mtype = mclass.mclass_type.arguments[i].as(MParameterType)
- end
- # Revolve bound for formal parameter names
- for i in [0..mclass.arity[ do
var nfd = nclassdef.n_formaldefs[i]
+ var pname = mclass.mparameters[i].name
+ if nfd.n_id.text != pname then
+ error(nfd.n_id, "Error: Formal parameter type #{i} `{nfd.n_id.text}` must be named `{pname}' as in the original definition in module `{mclass.intro.mmodule}`.")
+ end
var nfdt = nfd.n_type
if nfdt != null then
var bound = resolve_mtype_unchecked(mmodule, null, nfdt, false)
if bound == null then return # Forward error
if bound.need_anchor then
# No F-bounds!
- error(nfd, "Error: Formal parameter type `{names[i]}' bounded with a formal parameter type")
+ error(nfd, "Error: Formal parameter type `{pname}' bounded with a formal parameter type")
else
bounds.add(bound)
nfd.bound = bound
end
var bound_mtype = mclass.get_mtype(bounds)
- var mclassdef = new MClassDef(mmodule, bound_mtype, nclassdef.location, names)
+ var mclassdef = new MClassDef(mmodule, bound_mtype, nclassdef.location)
nclassdef.mclassdef = mclassdef
self.mclassdef2nclassdef[mclassdef] = nclassdef