-- This file is part of SmartEiffel The GNU Eiffel Compiler. -- Copyright (C) 1994-2002 LORIA - INRIA - U.H.P. Nancy 1 - FRANCE -- Dominique COLNET and Suzanne COLLIN - SmartEiffel@loria.fr -- http://SmartEiffel.loria.fr -- SmartEiffel is free software; you can redistribute it and/or modify it -- under the terms of the GNU General Public License as published by the Free -- Software Foundation; either version 2, or (at your option) any later -- version. SmartEiffel is distributed in the hope that it will be useful,but -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- for more details. You should have received a copy of the GNU General -- Public License along with SmartEiffel; see the file COPYING. If not, -- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -- Boston, MA 02111-1307, USA. -- class ASSERTION_COLLECTOR -- -- Singleton object in charge of assertion lookup. -- This singleton is shared via the GLOBALS.`assertion_collector' once function. -- inherit GLOBALS creation make feature {NONE} processing_require: BOOLEAN -- When processing require collection only. header_comment: COMMENT make is do end feature {RUN_CLASS} invariant_start is -- Called to start the collection of a class invariant. do collector.clear header_comment := Void end invariant_end(ct: E_TYPE): CLASS_INVARIANT is -- Called to finish the collection of `ct' class invariant. require ct /= Void local r: ARRAY[ASSERTION] position: POSITION do r := runnable(collector,ct,Void,'_') if r /= Void then smart_eiffel.magic_count_increment position := ct.base_class.name.start_position !!Result.make_runnable(position,r,ct,Void) Result.set_header_comment(header_comment) end end feature {BASE_CLASS} invariant_add_last(ci: CLASS_INVARIANT) is require ci /= Void local hc2: COMMENT bc, bc2: BASE_CLASS do ci.add_into(collector) hc2 := ci.header_comment if header_comment = Void then header_comment := hc2 elseif hc2 = Void then else bc := header_comment.start_position.base_class bc2 := hc2.start_position.base_class if bc2 = bc or else bc2.is_subclass_of(bc) then header_comment := hc2 end end end require_start is -- Called to start the collection of require assertions. do collector.clear header_comment := Void processing_require := true end require_end(rf: RUN_FEATURE; ct: E_TYPE): RUN_REQUIRE is -- Called to finish the collection of `ct' require assertion. require ct = rf.current_type local i: INTEGER sp: POSITION bc: BASE_CLASS a: ASSERTION r, r2: ARRAY[ASSERTION] er: E_REQUIRE do processing_require := false r := runnable(collector,ct,rf,'R') if r /= Void then from !!r2.with_capacity(r.count,1) a := r.item(1) r2.add_last(a) sp := a.start_position bc := sp.base_class i := 2 until i > r.upper or else r.item(i).start_position.base_class /= bc loop r2.add_last(r.item(i)) i := i + 1 end !!er.make_runnable(sp,r2,ct,rf) !!Result.make(er) from until i > r.upper loop from !!r2.with_capacity(r.count,1) a := r.item(i) r2.add_last(a) sp := a.start_position bc := sp.base_class i := i + 1 until i > r.upper or else r.item(i).start_position.base_class /= bc loop r2.add_last(r.item(i)) i := i + 1 end !!er.make_runnable(sp,r2,ct,rf) Result.add(er) end end end ensure_start is -- Called to start the collection of ensure assertions. do collector.clear header_comment := Void end ensure_end(rf: RUN_FEATURE; ct: E_TYPE): E_ENSURE is -- Called to finish the collection of `ct' ensure assertion. require ct = rf.current_type local r: ARRAY[ASSERTION] position: POSITION do r := runnable(collector,ct,rf,'E') if r /= Void then position := ct.base_class.name.start_position !!Result.make_runnable(position,r,ct,rf) Result.set_header_comment(header_comment) end end assertion_add_last(f: E_FEATURE) is -- To add some require/ensure assertion. local r: E_REQUIRE e: E_ENSURE do if processing_require then r := f.require_assertion if r /= Void then if header_comment = Void then header_comment := r.header_comment end r.add_into(collector) end else e := f.ensure_assertion if e /= Void then if header_comment = Void then header_comment := e.header_comment end e.add_into(collector) end end end feature {ASSERTION_LIST} runnable(collected: ARRAY[ASSERTION] ct: E_TYPE for: RUN_FEATURE assertion_check_tag: CHARACTER): ARRAY[ASSERTION] is -- Produce a runnable `collected'. require collected.lower = 1 for /= Void implies ct = for.current_type local i: INTEGER a: ASSERTION do if not collected.is_empty then from Result := collected.twin i := Result.upper until i = 0 loop smart_eiffel.push(for) a := Result.item(i).to_runnable(ct,assertion_check_tag) if a = Void then error(Result.item(i).start_position,fz_bad_assertion) else Result.put(a,i) end smart_eiffel.pop i := i - 1 end end end feature {NONE} collector: ARRAY[ASSERTION] is once !!Result.make(1,12) end singleton_memory: ASSERTION_COLLECTOR is once Result := Current end invariant is_real_singleton: Current = singleton_memory end -- ASSERTION_COLLECTOR