Merge: No old style accessors
[nit.git] / src / model / model.nit
index dbbec6d..7481338 100644 (file)
@@ -33,6 +33,7 @@ import poset
 import location
 import mmodule
 import mdoc
+import ordered_tree
 private import more_collections
 
 redef class Model
@@ -106,6 +107,35 @@ redef class Model
 
        # The only null type
        var null_type: MNullType = new MNullType(self)
+
+       # Build an ordered tree with from `concerns`
+       fun concerns_tree(mconcerns: Collection[MConcern]): ConcernsTree do
+               var seen = new HashSet[MConcern]
+               var res = new ConcernsTree
+
+               var todo = new Array[MConcern]
+               todo.add_all mconcerns
+
+               while not todo.is_empty do
+                       var c = todo.pop
+                       if seen.has(c) then continue
+                       var pc = c.parent_concern
+                       if pc == null then
+                               res.add(null, c)
+                       else
+                               res.add(pc, c)
+                               todo.add(pc)
+                       end
+                       seen.add(c)
+               end
+
+               return res
+       end
+end
+
+# An OrderedTree that can be easily refined for display purposes
+class ConcernsTree
+       super OrderedTree[MConcern]
 end
 
 redef class MModule
@@ -302,7 +332,7 @@ class MClass
 
        # The short name of the class
        # In Nit, the name of a class cannot evolve in refinements
-       var name: String
+       redef var name: String
 
        # The canonical name of the class
        # Example: `"owner::module::MyClass"`
@@ -463,6 +493,9 @@ class MClassDef
                self.to_s = "{mmodule}#{mclass}"
        end
 
+       # Actually the name of the `mclass`
+       redef fun name do return mclass.name
+
        # All declared super-types
        # FIXME: quite ugly but not better idea yet
        var supertypes: Array[MClassType] = new Array[MClassType]
@@ -1514,7 +1547,7 @@ abstract class MProperty
        var intro_mclassdef: MClassDef
 
        # The (short) name of the property
-       var name: String
+       redef var name: String
 
        # The canonical name of the property
        # Example: "owner::my_module::MyClass::my_method"
@@ -1718,6 +1751,10 @@ class MMethod
                super
        end
 
+       # Is the property defined at the top_level of the module?
+       # Currently such a property are stored in `Object`
+       var is_toplevel: Bool writable = false
+
        # Is the property a constructor?
        # Warning, this property can be inherited by subclasses with or without being a constructor
        # therefore, you should use `is_init_for` the verify if the property is a legal constructor for a given class
@@ -1795,6 +1832,9 @@ abstract class MPropDef
                self.to_s = "{mclassdef}#{mproperty}"
        end
 
+       # Actually the name of the `mproperty`
+       redef fun name do return mproperty.name
+
        # Internal name combining the module, the class and the property
        # Example: "mymodule#MyClass#mymethod"
        redef var to_s: String
@@ -1898,10 +1938,28 @@ class MClassKind
                self.to_s = s
                self.need_init = need_init
        end
+
+       # Can a class of kind `self` specializes a class of kine `other`?
+       fun can_specialize(other: MClassKind): Bool
+       do
+               if other == interface_kind then return true # everybody can specialize interfaces
+               if self == interface_kind or self == enum_kind then
+                       # no other case for interfaces
+                       return false
+               else if self == extern_kind then
+                       # only compatible with themselve
+                       return self == other
+               else if other == enum_kind or other == extern_kind then
+                       # abstract_kind and concrete_kind are incompatible
+                       return false
+               end
+               # remain only abstract_kind and concrete_kind
+               return true
+       end
 end
 
 fun abstract_kind: MClassKind do return once new MClassKind("abstract class", true)
 fun concrete_kind: MClassKind do return once new MClassKind("class", true)
 fun interface_kind: MClassKind do return once new MClassKind("interface", false)
 fun enum_kind: MClassKind do return once new MClassKind("enum", false)
-fun extern_kind: MClassKind do return once new MClassKind("extern", false)
+fun extern_kind: MClassKind do return once new MClassKind("extern class", false)