var g = local_class.global
v.add_instr("if (({recv}!=NIT_NULL) && !VAL_ISA({recv}, {g.color_id}, {g.id_id})) \{ fprintf(stderr, \"Cast failled\"); {v.printf_locate_error(n)} nit_exit(1); } /*cast {self}*/;")
end
+
+ # Compile a notnull cast assertion
+ meth compile_notnull_check(v: CompilerVisitor, recv: String, n: PNode)
+ do
+ if is_nullable then
+ v.add_instr("if (({recv}==NIT_NULL)) \{ fprintf(stderr, \"Cast failled\"); {v.printf_locate_error(n)} nit_exit(1); } /*cast {self}*/;")
+ end
+ end
end
###############################################################################
end
end
+redef class AAsNotnullExpr
+ redef meth compile_expr(v)
+ do
+ var e = v.compile_expr(n_expr)
+ n_expr.stype.compile_notnull_check(v, e, self)
+ return e
+ end
+end
+
redef class ATrueExpr
redef meth compile_expr(v)
do
end
end
+redef class AAsNotnullExpr
+ redef meth after_typing(v)
+ do
+ if not v.check_expr(n_expr) then return
+ var t = n_expr.stype
+ if t isa MMTypeNone then
+ v.error(n_expr, "Type error: 'as(not null)' on 'null' value.")
+ return
+ else if not t.is_nullable then
+ v.warning(n_expr, "Warning: 'as(not null)' on non nullable type.")
+ end
+ _stype = n_expr.stype.as_notnull
+ _is_typed = true
+ end
+end
+
redef class AProxyExpr
redef meth after_typing(v)
do
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2005-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 kernel
+
+class A
+ attr _i: Int
+ redef meth output do _i.output
+ init(i: Int) do _i = i
+end
+
+class B
+special A
+end
+
+meth outa(a: A) do a.output
+meth outb(b: B) do b.output
+
+var a: A = new A(1)
+var ab: A = new B(2)
+var b: B = new B(3)
+var na: nullable A = new A(4)
+var nab: nullable A = new B(5)
+var nb: nullable B = new B(6)
+var nan: nullable A = null
+var nbn: nullable B = null
+
+outa(a.as(not null))
+outa(ab.as(not null))
+outa(b.as(not null))
+outa(na.as(not null))
+outa(nab.as(not null))
+outa(nb.as(not null))
+
+'\n'.output
+
+#alt1#outb(a.as(not null))
+#alt2#outb(ab.as(not null))
+outb(b.as(not null))
+#alt3#outb(na.as(not null))
+#alt4#outb(nab.as(not null))
+outb(nb.as(not null))
+
+'\n'.output
+
+#alt5#nan.as(not null).output
+#alt6#nbn.as(not null).output
+#alt7#null.as(not null).output
--- /dev/null
+1
+2
+3
+4
+5
+6
+
+3
+6
+
--- /dev/null
+alt/base_as_notnull_alt1.nit:50,6--18: Type error: expected B, got A
--- /dev/null
+alt/base_as_notnull_alt2.nit:51,6--19: Type error: expected B, got A
--- /dev/null
+alt/base_as_notnull_alt3.nit:53,6--19: Type error: expected B, got A
--- /dev/null
+alt/base_as_notnull_alt4.nit:54,6--20: Type error: expected B, got A
--- /dev/null
+1
+2
+3
+4
+5
+6
+
+3
+6
+
+Cast failled in base_as_notnull_alt5::Sys::(kernel::Sys::main) (alt/base_as_notnull_alt5.nit:59)
+,---- Stack trace -- - - -
+| base_as_notnull_alt5::Sys::(kernel::Sys::main) (alt/base_as_notnull_alt5.nit:32)
+`------------------- - - -
--- /dev/null
+1
+2
+3
+4
+5
+6
+
+3
+6
+
+Cast failled in base_as_notnull_alt6::Sys::(kernel::Sys::main) (alt/base_as_notnull_alt6.nit:60)
+,---- Stack trace -- - - -
+| base_as_notnull_alt6::Sys::(kernel::Sys::main) (alt/base_as_notnull_alt6.nit:32)
+`------------------- - - -
--- /dev/null
+alt/base_as_notnull_alt7.nit:61,1--4: Type error: 'as(not null)' on 'null' value.