model: promote `c_name` from abstract-compiler to model
authorJean Privat <jean@pryen.org>
Tue, 16 Dec 2014 04:09:49 +0000 (23:09 -0500)
committerJean Privat <jean@pryen.org>
Wed, 17 Dec 2014 04:52:46 +0000 (23:52 -0500)
Signed-off-by: Jean Privat <jean@pryen.org>

src/compiler/abstract_compiler.nit
src/model/mmodule.nit
src/model/model.nit
src/model/model_base.nit

index ca3269e..6f9e166 100644 (file)
@@ -1692,21 +1692,9 @@ redef class MType
 
        # Short name of the `ctype` to use in unions
        fun ctypename: String do return "val"
-
-       # Return the name of the C structure associated to a Nit live type
-       fun c_name: String is abstract
-       protected var c_name_cache: nullable String is protected writable
 end
 
 redef class MClassType
-       redef fun c_name
-       do
-               var res = self.c_name_cache
-               if res != null then return res
-               res = "{mclass.intro_mmodule.c_name}__{mclass.name.to_cmangle}"
-               self.c_name_cache = res
-               return res
-       end
 
        redef fun ctype: String
        do
@@ -1757,90 +1745,8 @@ redef class MClassType
        end
 end
 
-redef class MGenericType
-       redef fun c_name
-       do
-               var res = self.c_name_cache
-               if res != null then return res
-               res = super
-               for t in self.arguments do
-                       res = res + t.c_name
-               end
-               self.c_name_cache = res
-               return res
-       end
-end
-
-redef class MParameterType
-       redef fun c_name
-       do
-               var res = self.c_name_cache
-               if res != null then return res
-               res = "{self.mclass.c_name}_FT{self.rank}"
-               self.c_name_cache = res
-               return res
-       end
-end
-
-redef class MVirtualType
-       redef fun c_name
-       do
-               var res = self.c_name_cache
-               if res != null then return res
-               res = "{self.mproperty.intro.mclassdef.mclass.c_name}_VT{self.mproperty.name}"
-               self.c_name_cache = res
-               return res
-       end
-end
-
-redef class MNullableType
-       redef fun c_name
-       do
-               var res = self.c_name_cache
-               if res != null then return res
-               res = "nullable_{self.mtype.c_name}"
-               self.c_name_cache = res
-               return res
-       end
-end
-
-redef class MClass
-       # Return the name of the C structure associated to a Nit class
-       fun c_name: String do
-               var res = self.c_name_cache
-               if res != null then return res
-               res = "{intro_mmodule.c_name}__{name.to_cmangle}"
-               self.c_name_cache = res
-               return res
-       end
-       private var c_name_cache: nullable String
-end
-
-redef class MProperty
-       fun c_name: String do
-               var res = self.c_name_cache
-               if res != null then return res
-               res = "{self.intro.c_name}"
-               self.c_name_cache = res
-               return res
-       end
-       private var c_name_cache: nullable String
-end
-
 redef class MPropDef
        type VISITOR: AbstractCompilerVisitor
-
-       private var c_name_cache: nullable String
-
-       # The mangled name associated to the property
-       fun c_name: String
-       do
-               var res = self.c_name_cache
-               if res != null then return res
-               res = "{self.mclassdef.mmodule.c_name}__{self.mclassdef.mclass.name.to_cmangle}__{self.mproperty.name.to_cmangle}"
-               self.c_name_cache = res
-               return res
-       end
 end
 
 redef class MMethodDef
@@ -3020,19 +2926,6 @@ redef class Array[E]
 end
 
 redef class MModule
-       # Return the name of the global C identifier associated to `self`.
-       # This name is used to prefix files and other C identifiers associated with `self`.
-       var c_name: String is lazy do
-               var g = mgroup
-               var res
-               if g != null and g.mproject.name != name then
-                       res = g.mproject.name.to_cmangle + "__" + name.to_cmangle
-               else
-                       res = name.to_cmangle
-               end
-               return res
-       end
-
        # All `MProperty` associated to all `MClassDef` of `mclass`
        fun properties(mclass: MClass): Set[MProperty] do
                if not self.properties_cache.has_key(mclass) then
index 2fbb424..3e3c497 100644 (file)
@@ -104,6 +104,20 @@ class MModule
                end
        end
 
+       # Return the name of the global C identifier associated to `self`.
+       # This name is used to prefix files and other C identifiers associated with `self`.
+       redef var c_name: String is lazy do
+               var g = mgroup
+               var res
+               if g != null and g.mproject.name != name then
+                       res = g.mproject.name.to_cmangle + "__" + name.to_cmangle
+               else
+                       res = name.to_cmangle
+               end
+               return res
+       end
+
+
        # Create a new empty module and register it to a model
        init
        do
index 6309385..8eabb75 100644 (file)
@@ -363,6 +363,8 @@ class MClass
        # Example: `"owner::module::MyClass"`
        redef var full_name is lazy do return "{self.intro_mmodule.full_name}::{name}"
 
+       redef var c_name is lazy do return "{intro_mmodule.c_name}__{name.to_cmangle}"
+
        # The number of generic formal parameters
        # 0 if the class is not generic
        var arity: Int is noinit
@@ -542,6 +544,14 @@ class MClassDef
                end
        end
 
+       redef var c_name is lazy do
+               if is_intro then
+                       return mclass.c_name
+               else
+                       return "{mmodule.c_name}__{mclass.c_name.to_cmangle}"
+               end
+       end
+
        redef fun model do return mmodule.model
 
        # All declared super-types
@@ -1051,6 +1061,8 @@ class MClassType
 
        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
@@ -1173,6 +1185,16 @@ class MGenericType
                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)
@@ -1315,6 +1337,8 @@ class MVirtualType
        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
@@ -1361,6 +1385,8 @@ class MParameterType
 
        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
@@ -1482,6 +1508,8 @@ class MNullableType
 
        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
@@ -1535,6 +1563,7 @@ class MNullType
        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
@@ -1709,6 +1738,10 @@ abstract class MProperty
                return "{intro_mclassdef.mmodule.full_name}::{intro_mclassdef.mclass.name}::{name}"
        end
 
+       redef var c_name is lazy do
+               return "{intro_mclassdef.mmodule.c_name}__{intro_mclassdef.mclass.c_name}__{name.to_cmangle}"
+       end
+
        # The visibility of the property
        var visibility: MVisibility
 
@@ -2010,6 +2043,18 @@ abstract class MPropDef
                return res.to_s
        end
 
+       redef var c_name is lazy do
+               var res = new FlatBuffer
+               res.append mclassdef.c_name
+               res.append "__"
+               if is_intro then
+                       res.append name.to_cmangle
+               else
+                       res.append mproperty.c_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
index ba2d5e3..fd2e1d1 100644 (file)
@@ -47,6 +47,21 @@ abstract class MEntity
        # See the specific implementation in subclasses for details.
        fun full_name: String is abstract
 
+       # A fully-qualified C-like identifier of this model entity.
+       #
+       # The C-name is a name that respects the rule of identifiers in the C language:
+       # it is only made of alphanumeric characters and starts with a letter (or a underscore).
+       #
+       # The C-name can be seen as a mangled version of the `full_name`.
+       # Therefore, it is expected to be unique and unambiguous in lawful Nit models for the same kind of entity.
+       #
+       # The C-name is used by tools that need some identifiers in generated files to designate the
+       # entity.
+       #
+       # Is is not suitable to use it directly with the user (e.g. in message) and
+       # indirect use should be restricted (e.g. to name a web-page)
+       fun c_name: String is abstract
+
        # A Model Entity has a direct link to its model
        fun model: Model is abstract
 end