metamodel: promote _filename to MMModule
[nit.git] / src / syntax / syntax_base.nit
index 3da7ef7..096e9b3 100644 (file)
@@ -29,9 +29,9 @@ special MMModule
        # Concrete NIT source local classs by name
        readable attr _src_local_classes: Map[Symbol, MMSrcLocalClass]
 
-       init(c: MMContext, source: AModule, dir: MMDirectory, name: Symbol)
+       init(c: MMContext, source: AModule, dir: MMDirectory, name: Symbol, filename: String)
        do
-               super(name, dir, c)
+               super(name, dir, c, filename)
                _node = source
                _src_local_classes = new HashMap[Symbol, MMSrcLocalClass]
        end
@@ -68,9 +68,9 @@ special MMConcreteClass
        # Concrete NIT source properties by name
        readable attr _src_local_properties: Map[Symbol, MMLocalProperty] 
 
-       init(n: Symbol, cla: PClassdef, a: Int)
+       init(mod: MMSrcModule, n: Symbol, cla: PClassdef, a: Int)
        do
-               super(n, a)
+               super(mod, n, a)
                _nodes = [cla]
                _src_local_properties = new HashMap[Symbol, MMLocalProperty]
        end
@@ -242,12 +242,12 @@ special Variable
        redef meth kind do return once "closure"
 
        # The signature of the closure
-       readable attr _signature: MMSignature
+       readable attr _closure: MMClosure
 
-       init(n: Symbol, d: PNode, s: MMSignature)
+       init(n: Symbol, d: PNode, c: MMClosure)
        do
                super(n, d)
-               _signature = s
+               _closure = c
        end
 end
 
@@ -256,6 +256,12 @@ end
 # Visitor used during the syntax analysis
 class AbsSyntaxVisitor
 special Visitor
+       # The root type Object
+       meth type_object: MMType
+       do
+               return _module.class_by_name(once ("Object".to_symbol)).get_type
+       end
+
        # The primitive type Bool
        meth type_bool: MMType
        do
@@ -367,9 +373,15 @@ special Visitor
        # Require that the static type of n is known
        meth check_expr(n: PExpr): Bool
        do
-               # FIXME: The tc.error_count is a workaround since currently there is no way
-               # to distingate statements from buggy expressions: both have a null stype
-               if tc.error_count == 0 and n.stype == null then
+               if not n.is_typed then
+                       if tc.error_count == 0 then
+                               print("{n.locate} not typed but not error")
+                               abort
+                       end
+                       # An error occured in a sub node,
+                       # sillently cascade fail
+                       return false
+               else if n.is_statement then
                        error(n, "Type error: expected expression.")
                        return false
                end
@@ -382,6 +394,37 @@ special Visitor
                if check_expr(n) then return check_conform(n, n.stype, stype) else return false
        end
 
+       # Check conformance between multiple expressions and a static type
+       # Conformance is granted if among them there is a most general type
+       # Return the most general type if a conformance is found
+       # Display an error and return null if no conformance is found
+       # @param stype is a possible additional type (without node)
+       # Examples:
+       #   Int, Int, Object => return Object
+       #   Int, Float => display error, return null
+       meth check_conform_multiexpr(stype: MMType, nodes: Collection[PExpr]): MMType
+       do
+               var node: PExpr = null # candidate node
+               for n in nodes do
+                       if not check_expr(n) then return null
+                       var ntype = n.stype
+                       if stype == null or (ntype != null and stype < ntype) then
+                               stype = ntype
+                               node = n
+                       end
+               end
+               for n in nodes do
+                       if not n.stype < stype then
+                               if node == null then
+                                       error(n, "Type error: no most general type. Got {n.stype} and {stype}.")
+                               else
+                                       error(n, "Type error: no most general type. Got {n.stype} and {stype} at {node.locate}.")
+                               end
+                               return null
+                       end
+               end
+               return stype
+       end
 
        protected init(tc: ToolContext, module: MMSrcModule)
        do
@@ -450,10 +493,7 @@ redef class PParam
 end
 
 redef class PClosureDecl
-       # The signature of the declared closure
-       meth signature: MMSignature is abstract
-
-       # Associated bloc variable
+       # Associated closure variable
        meth variable: ClosureVariable is abstract
 end
 
@@ -566,7 +606,9 @@ redef class AType
        redef meth get_stype(v)
        do
                var t = get_unchecked_stype(v)
-               if t != null then check_conform(v)
+               if t == null then return null
+               if not t.is_valid then return null
+               check_conform(v)
                return t
        end
 
@@ -580,8 +622,9 @@ redef class AType
                        for i in [0..arity[ do
                                var p = n_types[i]
                                var pt = p.get_stype(v)
-                               var bt = local_class.get_formal(i).bound
-                               if bt == null then return
+                               var b = local_class.get_formal(i)
+                               if not b.is_valid then return
+                               var bt = b.bound
                                bt = bt.adapt_to(st) # We need to abapt because of F-genericity
                                v.check_conform(p, pt, bt)
                        end
@@ -590,8 +633,17 @@ redef class AType
 end
 
 redef class PExpr
-       # Static type
-       # Is null for statement and for erronus expression
+       # Is the expression node correcly typed
+       # Return false if typed was not yet computed or
+       # if an error occured during the typing computation
+       meth is_typed: Bool is abstract
+
+       # Is the expression node a statement? (ie has no return value)
+       # require: is_typed
+       meth is_statement: Bool is abstract
+
+       # The static type of the expression
+       # require: is_typed and not is_statement
        meth stype: MMType is abstract
 end
 
@@ -600,7 +652,7 @@ redef class AVardeclExpr
        readable writable attr _variable: VarVariable
 end
 
-redef class AForVardeclExpr
+redef class AForExpr
        # Associated automatic local variable
        readable writable attr _variable: AutoVariable
 end
@@ -621,8 +673,8 @@ redef class AClosureCallExpr
 end
 
 redef class PClosureDef
-       # Associated signature
-       readable writable attr _signature: MMSignature
+       # Associated closure
+       readable writable attr _closure: MMClosure
 
        # Automatic variables
        readable writable attr _variables: Array[AutoVariable]