mmbuilder: detect type of some attributes
authorAlexis Laferrière <alexis.laf@xymus.net>
Tue, 6 Mar 2012 03:11:24 +0000 (22:11 -0500)
committerAlexis Laferrière <alexis.laf@xymus.net>
Thu, 12 Apr 2012 19:38:17 +0000 (15:38 -0400)
Allows to automaticaly determine the static type of some attributes assigned
where introduced. Works for literal Int, Char, Bool and String, as well as
"new" and boolean expressions.

Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

src/syntax/mmbuilder.nit
tests/sav/test_attr_easy.sav [new file with mode: 0644]
tests/test_attr_easy.nit [new file with mode: 0644]

index 765c26b..636ef1f 100644 (file)
@@ -1090,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
@@ -1108,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)
@@ -1118,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
 
@@ -1420,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
diff --git a/tests/sav/test_attr_easy.sav b/tests/sav/test_attr_easy.sav
new file mode 100644 (file)
index 0000000..e6da479
--- /dev/null
@@ -0,0 +1,4 @@
+true false 12345 1.234500 asdf true
+an instance of B
+true true true true
+true true true true
diff --git a/tests/test_attr_easy.nit b/tests/test_attr_easy.nit
new file mode 100644 (file)
index 0000000..dfcbb6b
--- /dev/null
@@ -0,0 +1,24 @@
+
+class B
+       redef fun to_s do return "an instance of B"
+end
+
+class A
+       var a = true
+       var b = false
+       var c = 12345
+       var d = 1.2345
+       var e = "asdf"
+       var f = new B
+       var g = new HashMap[Int,B]
+
+       var h = true or false
+
+       redef fun to_s do return "{a} {b} {c} {d} {e} {h}\n" +
+               "{f}\n" + 
+               "{a isa Bool} {b isa Bool} {c isa Int} {d isa Float}\n" +
+               "{e isa String} {f isa B} {not f isa A} {g isa HashMap[Int,B]}"
+end
+
+var a = new A
+print a