Merge remote branch 'alexis/wip'
[nit.git] / src / syntax / mmbuilder.nit
index c2c92b8..61b80a3 100644 (file)
 package mmbuilder
 
 import syntax_base
+private import primitive_info
+
+redef class ToolContext
+       redef fun handle_property_conflict(lc, impls)
+       do
+               var location: nullable Location = null
+               if lc isa MMSrcLocalClass then
+                       var node = lc.node
+                       if node != null then node.location
+               end
+               #if location == null then location = lc.mmmodule.location
+               var clas = new Array[MMLocalClass]
+               for i in impls do
+                       clas.add(i.local_class)
+               end
+               self.fatal_error(location, "Property inheritance conflict in class {lc} for `{impls.first.name}': conflicting properties are defined in {clas.join(", ")}")
+       end
+end
 
 # Class specialization hierarchy sorter
 private class CSHSorter
@@ -163,7 +181,7 @@ redef class MMSrcLocalClass
                        n = n.next_node
                end
 
-               for p in src_local_properties do
+               for p in src_local_properties.values do
                        p.accept_property_visitor(v)
                end
        end
@@ -197,7 +215,7 @@ redef class MMSrcLocalClass
 
                # Collect unassigned attributes
                var unassigned_attributes = new Array[MMSrcAttribute]
-               for a in src_local_properties do
+               for a in src_local_properties.values do
                        if a isa MMSrcAttribute then
                                var n = a.node
                                if n.n_expr == null then unassigned_attributes.add(a)
@@ -302,7 +320,11 @@ redef class MMImplicitInit
                for a in unassigned_attributes do
                        var sig = a.signature
                        if sig == null then return # Broken attribute definition
-                       params.add( new MMParam( sig.return_type.as(not null), once "recv".to_symbol))
+                       var name = a.name
+                       if name.to_s.first == '_' or name.to_s.first == '@' then
+                               name = a.to_s.substring_from(1).to_symbol
+                       end
+                       params.add(new MMParam(sig.return_type.as(not null), name))
                end
                signature = new MMSignature(params, null, local_class.get_type)
        end
@@ -522,7 +544,7 @@ redef class AClassdef
                var local_class: MMSrcLocalClass
                var mod = v.mmmodule
                var local_classes = mod.src_local_classes
-               if (local_classes.has_key(name)) then
+               if local_classes.has_key(name) then
                        local_class = local_classes[name]
                        _local_class = local_class
                        if self isa AStdClassdef then
@@ -657,17 +679,25 @@ redef class AStdClassdef
        do
                return n_formaldefs.length
        end
-       redef fun accept_class_verifier(v)
+       redef fun accept_class_specialization_builder(v)
        do
                super
-               var glob = _local_class.global
-               if glob.intro == _local_class then
-                       # Intro
-                       glob.visibility_level = visibility_level
+
+               var glob = local_class.global
+               if glob.intro == local_class then
                        glob.is_interface = n_classkind.is_interface
                        glob.is_abstract = n_classkind.is_abstract
                        glob.is_enum = n_classkind.is_enum
                        glob.is_extern = n_classkind.is_extern
+                       glob.visibility_level = visibility_level
+               end
+       end
+       redef fun accept_class_verifier(v)
+       do
+               super
+               var glob = _local_class.global
+               if glob.intro == _local_class then
+                       # Intro
                        if n_kwredef != null then
                                v.error(self, "Redef error: No class {name} is imported. Remove the redef keyword to define a new class.")
                        end
@@ -946,6 +976,8 @@ redef class APropdef
                                                t = v.type_array(t)
                                        end
                                        p.variable.stype = t
+
+                                       isig.params[p.position].name = p.variable.name
                                end
                                s = isig
                                prop.signature = s
@@ -1058,11 +1090,15 @@ redef class AAttrPropdef
        redef fun accept_property_verifier(v)
        do
                super
-               var t: MMType
+               var t: nullable MMType = null
                if n_type != null then
                        var t0 = n_type.get_stype(v)
                        if t0 != null then t = t0 else return
-               else
+               else if n_expr != null then
+                       t = n_expr.get_easy_stype(v)
+               end
+
+               if t == null then
                        v.error(self, "Not yet implemented: Attribute definition {prop.local_class}::{prop} requires an explicit type.")
                        return
                end
@@ -1076,7 +1112,7 @@ redef class AAttrPropdef
                        var m = _readmethod.as(not null)
                        m.signature = signature
                        process_and_check(v, m, (n_readable != null and n_readable.n_kwredef != null) or (n_id == null and n_kwredef != null), visibility_level)
-                       n_type.check_visibility(v, m)
+                       if n_type != null then n_type.check_visibility(v, m)
                end
                if n_writable != null or n_id == null then
                        var m = _writemethod.as(not null)
@@ -1086,7 +1122,7 @@ redef class AAttrPropdef
                                if n_writable == null then vl = 3 else vl = n_writable.n_visibility.level # write accessor has a specific visibility
                        end
                        process_and_check(v, m, n_writable != null and n_writable.n_kwredef != null, vl)
-                       n_type.check_visibility(v, m)
+                       if n_type != null then n_type.check_visibility(v, m)
                end
        end
 
@@ -1183,68 +1219,6 @@ redef class AExternPropdef
        end
 end
 
-redef class MMMethod
-       fun default_extern_name : String
-       do
-               return "{friendly_extern_name(local_class)}___impl"
-       end
-
-       # Friendly name for this method. Is mainly the class name followed by the
-       # function name. It is prefixed with "new" for a constructor.
-       fun friendly_extern_name( local_class : MMLocalClass ) : String
-       do
-               if not is_init then
-                       var native_fun_name : String
-                       var method_name = name.to_s
-                       if method_name == "+" then
-                               native_fun_name = "_plus" # add
-                       else if method_name == "-" then
-                               native_fun_name = "_minus" # sub
-                       else if method_name == "*" then
-                               native_fun_name = "_star" # multi
-                       else if method_name == "/" then
-                               native_fun_name = "_slash" # div
-                       else if method_name == "%" then
-                               native_fun_name = "_percent" # mod
-                       else if method_name == "[]" then
-                               native_fun_name = "_index" # brackets
-                       else if method_name == "[]=" then
-                               native_fun_name = "_index_assign" # brackets
-                       else if method_name == "==" then
-                               native_fun_name = "_equal" # eq
-                       else if method_name == "<" then
-                               native_fun_name = "_less" # lt
-                       else if method_name == ">" then
-                               native_fun_name = "_greater" # gt
-                       else if method_name == "<=" then
-                               native_fun_name = "_less_or_equal" # greater_or_equal
-                       else if method_name == ">=" then
-                               native_fun_name = "_ge" # smaller_or_equal
-                       else if method_name == "!=" then
-                               native_fun_name = "_not_equal" # bang
-                       else if method_name == ">>" then
-                               native_fun_name = "_right"
-                       else if method_name == "<<" then
-                               native_fun_name = "_left"
-                       else if method_name == "<=>" then
-                               native_fun_name = "_starship"
-                       else if method_name[ method_name.length-1 ] == '=' then
-                               native_fun_name = "{method_name.substring(0,method_name.length-1)}__assign"
-                       else
-                               native_fun_name = method_name
-                       end
-
-                       return "{local_class.name}_{native_fun_name}"
-               else
-                       if name == once "init".to_symbol then
-                               return "new_{local_class.name}"
-                       else
-                               return "new_{local_class.name}_{name}"
-                       end
-               end
-       end
-end
-
 redef class ATypePropdef
        redef fun prop do return _prop.as(not null)
        var _prop: nullable MMSrcTypeProperty
@@ -1450,4 +1424,30 @@ redef class AExpr
        redef fun accept_class_builder(v) do end
        redef fun accept_property_builder(v) do end
        redef fun accept_property_verifier(v) do end
+
+       private fun get_easy_stype(v:PropertyVerifierVisitor) : nullable MMType do return null
+end
+
+redef class ABoolExpr
+       redef fun get_easy_stype(v) do return v.type_bool
+end
+
+redef class AStringExpr
+       redef fun get_easy_stype(v) do return v.type_string
+end
+
+redef class ACharExpr
+       redef fun get_easy_stype(v) do return v.type_char
+end
+
+redef class AIntExpr
+       redef fun get_easy_stype(v) do return v.type_int
+end
+
+redef class AFloatExpr
+       redef fun get_easy_stype(v) do return v.type_float
+end
+
+redef class ANewExpr
+       redef fun get_easy_stype(v) do return n_type.get_stype(v)
 end