From: Jean Privat Date: Wed, 24 Jun 2009 08:57:45 +0000 (-0400) Subject: compile: implicit isset for attribute read access X-Git-Tag: v0.3~216 X-Git-Url: http://nitlanguage.org compile: implicit isset for attribute read access Activated only if the program was compiled using -W and only display a warning at run-time. Therefore the new test base_attr_nullable.nit makes more sense with -W. Signed-off-by: Jean Privat --- diff --git a/src/compiling/compiling_methods.nit b/src/compiling/compiling_methods.nit index 1c6cee0..61f3267 100644 --- a/src/compiling/compiling_methods.nit +++ b/src/compiling/compiling_methods.nit @@ -455,13 +455,18 @@ end redef class MMAttribute # Compile a read acces on selffor a given reciever. - meth compile_read_access(v: CompilerVisitor, recv: String): String + meth compile_read_access(v: CompilerVisitor, n: PNode, recv: String): String do - return "{global.attr_access}({recv}) /*{local_class}::{name}*/" + var res = "{global.attr_access}({recv}) /*{local_class}::{name}*/" + if not signature.return_type.is_nullable and v.tc.opt_warn.value > 0 then + res = v.ensure_var(res, "{local_class}::{name}") + v.add_instr("if ({res} == NIT_NULL) \{ fprintf(stderr, \"Uninitialized attribute %s\", \"{name}\"); {v.printf_locate_error(n)} } /* implicit isset */;") + end + return res end # Compile a write acces on selffor a given reciever. - meth compile_write_access(v: CompilerVisitor, recv: String, value: String) + meth compile_write_access(v: CompilerVisitor, n: PNode, recv: String, value: String) do v.add_instr("{global.attr_access}({recv}) /*{local_class}::{name}*/ = {value};") end @@ -571,14 +576,14 @@ end redef class MMReadImplementationMethod redef meth do_compile_inside(v, params) do - return node.prop.compile_read_access(v, params[0]) + return node.prop.compile_read_access(v, node, params[0]) end end redef class MMWriteImplementationMethod redef meth do_compile_inside(v, params) do - node.prop.compile_write_access(v, params[0], params[1]) + node.prop.compile_write_access(v, node, params[0], params[1]) return null end end @@ -611,7 +616,7 @@ redef class MMImplicitInit end for i in [f..params.length[ do var attribute = unassigned_attributes[i-f] - attribute.compile_write_access(v, recv, params[i]) + attribute.compile_write_access(v, null, recv, params[i]) end return null end @@ -1473,7 +1478,7 @@ redef class AAttrExpr redef meth compile_expr(v) do var e = v.compile_expr(n_expr) - return prop.compile_read_access(v, e) + return prop.compile_read_access(v, n_id, e) end end @@ -1482,17 +1487,17 @@ redef class AAttrAssignExpr do var e = v.compile_expr(n_expr) var e2 = v.compile_expr(n_value) - prop.compile_write_access(v, e, e2) + prop.compile_write_access(v, n_id, e, e2) end end redef class AAttrReassignExpr redef meth compile_stmt(v) do var e1 = v.compile_expr(n_expr) - var e2 = prop.compile_read_access(v, e1) + var e2 = prop.compile_read_access(v, n_id, e1) var e3 = v.compile_expr(n_value) var e4 = assign_method.compile_expr_call(v, [e2, e3]) - prop.compile_write_access(v, e1, e4) + prop.compile_write_access(v, n_id, e1, e4) end end diff --git a/tests/base_attr_nullable.nit b/tests/base_attr_nullable.nit new file mode 100644 index 0000000..c8ea25c --- /dev/null +++ b/tests/base_attr_nullable.nit @@ -0,0 +1,84 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2004-2008 Jean Privat +# +# 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 + +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 run_other(o: Foo) + do + o._a1.output + o._a2.output + end + + init + do + #alt1#run + _a1 = new Integer(1) + #alt2#run + _a2 = new Integer(_a1.val + 1) + end + + init nop do end +end + +class Bar +special Foo + attr _a3: Integer + redef meth run + do + _a1.output + _a2.output + _a3.output + end + + init + do + nop + #alt3#run + _a1 = new Integer(10) + #alt4#run_other(self) + _a2 = new Integer(20) + #alt5#run + _a3 = new Integer(30) + end +end + +var f = new Foo +var b = new Bar +f.run +b.run diff --git a/tests/sav/base_attr_nullable.sav b/tests/sav/base_attr_nullable.sav new file mode 100644 index 0000000..66b1ef1 --- /dev/null +++ b/tests/sav/base_attr_nullable.sav @@ -0,0 +1,5 @@ +1 +2 +10 +20 +30 diff --git a/tests/sav/base_attr_nullable_alt1.sav b/tests/sav/base_attr_nullable_alt1.sav new file mode 100644 index 0000000..7f93cf3 --- /dev/null +++ b/tests/sav/base_attr_nullable_alt1.sav @@ -0,0 +1,6 @@ +Recieved signal 11 +,---- Stack trace -- - - - +| base_attr_nullable_alt1::Foo::run (alt/base_attr_nullable_alt1.nit:36) +| base_attr_nullable_alt1::Foo::init (alt/base_attr_nullable_alt1.nit:48) +| base_attr_nullable_alt1::Sys::main (alt/base_attr_nullable_alt1.nit:81) +`------------------- - - - diff --git a/tests/sav/base_attr_nullable_alt2.sav b/tests/sav/base_attr_nullable_alt2.sav new file mode 100644 index 0000000..450ae77 --- /dev/null +++ b/tests/sav/base_attr_nullable_alt2.sav @@ -0,0 +1,7 @@ +1 +Recieved signal 11 +,---- Stack trace -- - - - +| base_attr_nullable_alt2::Foo::run (alt/base_attr_nullable_alt2.nit:36) +| base_attr_nullable_alt2::Foo::init (alt/base_attr_nullable_alt2.nit:48) +| base_attr_nullable_alt2::Sys::main (alt/base_attr_nullable_alt2.nit:81) +`------------------- - - - diff --git a/tests/sav/base_attr_nullable_alt3.sav b/tests/sav/base_attr_nullable_alt3.sav new file mode 100644 index 0000000..4face12 --- /dev/null +++ b/tests/sav/base_attr_nullable_alt3.sav @@ -0,0 +1,6 @@ +Recieved signal 11 +,---- Stack trace -- - - - +| base_attr_nullable_alt3::Bar::(base_attr_nullable_alt3::Foo::run) (alt/base_attr_nullable_alt3.nit:62) +| base_attr_nullable_alt3::Bar::init (alt/base_attr_nullable_alt3.nit:69) +| base_attr_nullable_alt3::Sys::main (alt/base_attr_nullable_alt3.nit:81) +`------------------- - - - diff --git a/tests/sav/base_attr_nullable_alt4.sav b/tests/sav/base_attr_nullable_alt4.sav new file mode 100644 index 0000000..2c29f07 --- /dev/null +++ b/tests/sav/base_attr_nullable_alt4.sav @@ -0,0 +1,7 @@ +10 +Recieved signal 11 +,---- Stack trace -- - - - +| base_attr_nullable_alt4::Foo::run_other (alt/base_attr_nullable_alt4.nit:42) +| base_attr_nullable_alt4::Bar::init (alt/base_attr_nullable_alt4.nit:69) +| base_attr_nullable_alt4::Sys::main (alt/base_attr_nullable_alt4.nit:81) +`------------------- - - - diff --git a/tests/sav/base_attr_nullable_alt5.sav b/tests/sav/base_attr_nullable_alt5.sav new file mode 100644 index 0000000..961ad0d --- /dev/null +++ b/tests/sav/base_attr_nullable_alt5.sav @@ -0,0 +1,8 @@ +10 +20 +Recieved signal 11 +,---- Stack trace -- - - - +| base_attr_nullable_alt5::Bar::(base_attr_nullable_alt5::Foo::run) (alt/base_attr_nullable_alt5.nit:62) +| base_attr_nullable_alt5::Bar::init (alt/base_attr_nullable_alt5.nit:69) +| base_attr_nullable_alt5::Sys::main (alt/base_attr_nullable_alt5.nit:81) +`------------------- - - -