module model::class_compound
import graph
+import member
+import type_entity
# A class.
class ClassCompound
init do
super
- class_type = new ClassType(graph, self)
+ class_type = new ClassType(graph)
+ class_type.class_compound = self
class_def = new ClassDef(graph, self)
self.labels.add("MClass")
- self["arity"] = 0 # TODO
kind = "class"
visibility = "public"
end
- redef fun name=(name: String) do
+ # Return the number of type parameters.
+ fun arity: Int do return class_type.arity
+
+ redef fun name=(name) do
super
class_type.name = name
class_def.name = name
end
- redef fun location=(location: nullable Location) do
+ redef fun location=(location) do
super
class_def.location = location
end
class_def["mdoc"] = doc
end
- redef fun declare_super(id: String, name: String, prot: String, virt: String) do
- class_def.declare_super(id, name, prot, virt)
+ redef fun declare_super(id, full_name, prot, virt) do
+ class_def.declare_super(id, full_name, prot, virt)
+ end
+
+ redef fun declare_member(member) do
+ class_def.declare_member(member)
+ end
+
+ # Append the specified type parameter.
+ fun add_type_parameter(parameter: TypeParameter) do
+ class_type.arguments.add(parameter)
end
redef fun put_in_graph do
redef fun put_edges do
super
graph.add_edge(self, "CLASSTYPE", class_type)
+ if arity > 0 then
+ var names = new JsonArray
+
+ for p in class_type.arguments do
+ names.add(p.name)
+ end
+ self["parameter_names"] = names
+ end
end
end
class ClassDef
super CodeBlock
+ # The defined class.
var class_compound: ClassCompound
+
+ # The `model_id` of the base classes.
var supers: SimpleCollection[String] = new Array[String]
+ # The set of the introduced/redefined members.
+ #
+ # Includes inner classes.
+ #
+ # Filled by `declare_member` and `declare_class`.
+ #
+ # Note: `declare_class` is defined by the `inner_class` module.
+ #
+ # SEE: `declare_member`
+ # SEE: `declare_class`
+ var members: SimpleCollection[MemberOrInner] = new Array[MemberOrInner]
+
init do
super
self.labels.add("MClassDef")
+ self["is_intro"] = true
end
- fun declare_super(id: String, name: String, prot: String, virt: String) do
- # TODO prot, virt, name
+ # Declare a base compound (usually, a base class).
+ #
+ # Parameters:
+ #
+ # * `id`: `model_id` of the base compound. May be empty.
+ # * `full_name`: qualified name of the base compound. May be empty.
+ # * `prot`: visibility (proctection) of the relationship.
+ # * `virt`: level of virtuality of the relationship.
+ fun declare_super(id: String, full_name: String, prot: String,
+ virt: String) do
+ # TODO prot, virt, full_name
if "" != id then
supers.add(id)
end
end
+ # Append the specified member.
+ fun declare_member(member: Member) do
+ members.add(member)
+ end
+
redef fun put_edges do
super
graph.add_edge(self, "BOUNDTYPE", class_compound.class_type)
for s in supers do
graph.add_edge(self, "INHERITS", graph.by_id[s].as(ClassCompound).class_type)
end
+ for m in members do
+ if m.is_intro then
+ var intro = m.introducer.as(not null)
+ graph.add_edge(self, "INTRODUCES", intro)
+ graph.add_edge(intro, "INTRO_CLASSDEF", self)
+ end
+ graph.add_edge(self, "DECLARES", m)
+ end
end
end
# A type defined by a class.
class ClassType
- super Entity
+ super TypeEntity
- var class_compound: ClassCompound
+ # The associated class.
+ #
+ # You may use this attribute or `class_compound_id` to specify the class.
+ var class_compound: nullable ClassCompound = null is writable
+
+ # The `model_id` of the associated class.
+ #
+ # You may use this attribute or `class_compound` to specify the class.
+ var class_compound_id: String = "" is writable
+
+ # The type arguments or the type parameters.
+ var arguments = new Array[TypeEntity]
init do
super
- self.labels.add("MType")
self.labels.add("MClassType")
end
+ # Return the number of arguments.
+ fun arity: Int do return arguments.length
+
+ # Is the class generic?
+ fun is_generic: Bool do return arity > 0
+
+ redef fun put_in_graph do
+ super
+ if is_generic then
+ self.labels.add("MGenericType")
+ else
+ var i = self.labels.index_of("MGenericType")
+ if i >= 0 then self.labels.remove_at(i)
+ end
+ end
+
redef fun put_edges do
- graph.add_edge(self, "CLASS", class_compound)
+ var cls = class_compound
+
+ if cls == null and class_compound_id != "" then
+ cls = graph.by_id[class_compound_id].as(ClassCompound)
+ end
+ assert cls != null
+
+ super
+ graph.add_edge(self, "CLASS", cls)
+ assert cls.arity == self.arity
+ for i in [0..arguments.length[ do
+ var a = arguments[i]
+ if cls.class_type != self then
+ a.name = cls.class_type.arguments[i].name
+ end
+ if a isa TypeParameter then
+ a.rank = i
+ graph.add_edge(a, "CLASS", cls)
+ end
+ graph.add_edge(self, "ARGUMENT", a)
+ end
end
end