rename 'package' to 'module'
[nit.git] / src / syntax / mmbuilder.nit
index 8cab94c..2df1ad2 100644 (file)
 # Build MM entity from NIT AST and check conformance of these entities.
 # This module introduce specific MM class (MMSrcXXX) that specialize the abstract one from metamodel
 #
-package mmbuilder
+module 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,20 +679,31 @@ 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
+                       if glob.is_extern then
+                               glob.mmmodule.is_extern_hybrid = true
+                       end
 
                        for c in _local_class.cshe.direct_greaters do
                                var cg = c.global
@@ -905,7 +938,7 @@ redef class APropdef
        # The part of process_and_check when prop is a redefinition
        private fun do_and_check_redef(v: PropertyVerifierVisitor, prop: MMLocalProperty, has_redef: Bool, visibility_level: Int)
        do
-               var is_init = self isa AConcreteInitPropdef
+               var is_init = self isa AInitPropdef
                var glob = prop.global
 
                if not has_redef then
@@ -943,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
@@ -998,8 +1033,7 @@ redef class APropdef
                                # Systematic fallback for conformance check
                                v.error(self, "Redef error: Incompatible redefinition of {ip.local_class}::{ip} with {prop.local_class}::{prop}")
                        else if srt != null and isrt != null and srt != isrt and prop isa MMAttribute then
-                               # FIXME: To remove
-                               v.warning(self, "Redef warning: Expected {isrt}, as in {ip.local_class}::{ip}.")
+                               v.error(self, "Redef error: Expected {isrt}, as in {ip.local_class}::{ip}.")
                        end
                end
 
@@ -1055,11 +1089,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
@@ -1073,7 +1111,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)
@@ -1083,7 +1121,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
 
@@ -1107,7 +1145,7 @@ redef class AMethPropdef
                super
                var name: Symbol
                if n_methid == null then
-                       if self isa AConcreteInitPropdef then
+                       if self isa AInitPropdef then
                                name = once "init".to_symbol
                        else
                                name = once "main".to_symbol
@@ -1165,7 +1203,7 @@ redef class AMainMethPropdef
        end
 end
 
-redef class AExternMethPropdef
+redef class AExternPropdef
        redef fun accept_property_verifier(v)
        do
                super # Compute signature
@@ -1174,7 +1212,7 @@ redef class AExternMethPropdef
                        ename = n_extern.text
                        ename = ename.substring(1, ename.length-2)
                else
-                       ename = "{method.mmmodule.name}_{method.local_class.name}_{method.local_class.name}_{method.name}_{method.signature.arity}"
+                       ename = method.default_extern_name
                end
                method.extern_name = ename
        end
@@ -1353,7 +1391,7 @@ redef class AClosureDecl
                var clos = new MMClosure(name, sig, n_kwbreak != null, n_expr != null)
                for c in old_signature_builder.closure_decls do
                        if c.n_id.to_symbol == name then
-                               v.error(n_id, "A closure '!{name}' already defined at {c.n_id.location.relative_to(n_id.location)}.")
+                               v.error(n_id, "Error: A closure '!{name}' already defined at {c.n_id.location.relative_to(n_id.location)}.")
                                return
                        end
                end
@@ -1385,4 +1423,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