nullable: type, compile and test 'isset _attr'
authorJean Privat <jean@pryen.org>
Wed, 24 Jun 2009 18:44:24 +0000 (14:44 -0400)
committerJean Privat <jean@pryen.org>
Wed, 24 Jun 2009 20:29:37 +0000 (16:29 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

src/compiling/compiling_methods.nit
src/parser/parser_nodes.nit
src/syntax/typing.nit
tests/base_attr_isset.nit [new file with mode: 0644]
tests/sav/base_attr_isset.sav [new file with mode: 0644]
tests/sav/base_attr_isset_alt1.sav [new file with mode: 0644]
tests/sav/base_attr_isset_alt2.sav [new file with mode: 0644]

index 61f3267..3f79777 100644 (file)
@@ -455,6 +455,12 @@ end
 
 redef class MMAttribute
        # Compile a read acces on selffor a given reciever.
+       meth compile_isset(v: CompilerVisitor, n: PNode, recv: String): String
+       do
+               return "TAG_Bool({global.attr_access}({recv})!=NIT_NULL) /* isset {local_class}::{name}*/"
+       end
+
+       # Compile a read acces on selffor a given reciever.
        meth compile_read_access(v: CompilerVisitor, n: PNode, recv: String): String
        do
                var res = "{global.attr_access}({recv}) /*{local_class}::{name}*/"
@@ -1501,6 +1507,14 @@ redef class AAttrReassignExpr
        end
 end
 
+redef class AIssetAttrExpr
+       redef meth compile_expr(v)
+       do
+               var e = v.compile_expr(n_expr)
+               return prop.compile_isset(v, n_id, e)
+       end
+end
+
 redef class AAbsAbsSendExpr
        # Compile each argument and add them to the array
        meth compile_arguments_in(v: CompilerVisitor, cargs: Array[String])
index 9e94135..6e2f6ac 100644 (file)
@@ -893,10 +893,8 @@ special PExpr
     readable writable attr _n_kwnull: TKwnull = null
 end
 class AIssetAttrExpr
-special PExpr
+special AAttrFormExpr
     readable writable attr _n_kwisset: TKwisset = null
-    readable writable attr _n_expr: PExpr = null
-    readable writable attr _n_id: TAttrid = null
 end
 class APlusAssignOp
 special PAssignOp
index 3cc50b2..6717511 100644 (file)
@@ -1001,6 +1001,19 @@ redef class AAttrReassignExpr
        end
 end
 
+redef class AIssetAttrExpr
+       redef meth after_typing(v)
+       do
+               do_typing(v)
+               if prop == null then return
+               if attr_type.is_nullable then
+                       v.error(self, "Error: isset on a nullable attribute.")
+               end
+               _stype = v.type_bool
+               _is_typed = true
+       end
+end
+
 class AAbsAbsSendExpr
 special PExpr
        # The signature of the called property
diff --git a/tests/base_attr_isset.nit b/tests/base_attr_isset.nit
new file mode 100644 (file)
index 0000000..f4eee62
--- /dev/null
@@ -0,0 +1,99 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2004-2008 Jean Privat <jean@pryen.org>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import end
+
+interface Object
+end
+
+universal Int
+       meth output is intern
+       meth +(o: Int): Int is intern
+end
+
+universal Bool
+       meth output is intern
+end
+
+class Integer
+       readable writable attr _val: Int
+       init(val: Int) do _val = val
+       meth output do _val.output
+end
+
+class Foo
+       attr _a1: Integer
+       readable attr _a2: Integer
+       meth run
+       do
+               _a1.output
+               a2.output
+       end
+
+       meth show(i: Int)
+       do
+               i.output
+               (isset _a1).output
+               (isset _a2).output
+       end
+
+       init
+       do
+               show(1)
+               _a1 = new Integer(1)
+               show(2)
+               _a2 = new Integer(_a1.val + 1)
+               show(3)
+       end
+
+       init nop do end
+end
+
+class Bar
+special Foo
+       attr _a3: Integer#!alt1# #!alt2#
+       #alt1#attr _a3: Integer = new Integer(9000)
+       #alt2#attr _a3: nullable Integer
+       redef meth run
+       do
+               _a1.output
+               _a2.output
+               _a3.output
+       end
+
+       redef meth show(i)
+       do
+               super
+               (isset _a3).output
+       end
+
+       init
+       do
+               nop
+               show(4)
+               _a1 = new Integer(10)
+               show(5)
+               _a2 = new Integer(20)
+               show(6)
+               _a3 = new Integer(30)
+               show(7)
+       end
+end
+
+var f = new Foo
+var b = new Bar
+f.run
+b.run
diff --git a/tests/sav/base_attr_isset.sav b/tests/sav/base_attr_isset.sav
new file mode 100644 (file)
index 0000000..1613858
--- /dev/null
@@ -0,0 +1,30 @@
+1
+false
+false
+2
+true
+false
+3
+true
+true
+4
+false
+false
+false
+5
+true
+false
+false
+6
+true
+true
+false
+7
+true
+true
+true
+1
+2
+10
+20
+30
diff --git a/tests/sav/base_attr_isset_alt1.sav b/tests/sav/base_attr_isset_alt1.sav
new file mode 100644 (file)
index 0000000..25b9c0b
--- /dev/null
@@ -0,0 +1,30 @@
+1
+false
+false
+2
+true
+false
+3
+true
+true
+4
+false
+false
+true
+5
+true
+false
+true
+6
+true
+true
+true
+7
+true
+true
+true
+1
+2
+10
+20
+30
diff --git a/tests/sav/base_attr_isset_alt2.sav b/tests/sav/base_attr_isset_alt2.sav
new file mode 100644 (file)
index 0000000..a6a6749
--- /dev/null
@@ -0,0 +1 @@
+alt/base_attr_isset_alt2.nit:79,4--12: Error: isset on a nullable attribute.