-- 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. -- deferred class CALL_PROC_CALL -- -- Common root for CALL and PROC_CALL. -- inherit GLOBALS feature {CALL_PROC_CALL} current_type: E_TYPE -- Non Void when runnable and checked in `ct' context. debug_info: STRING -- For debug only. debug_info_update is local i: INTEGER; e: EXPRESSION; t: E_TYPE; sp: POSITION do check debug_info = Void end create debug_info.make(32) sp := start_position if not sp.is_unknown then sp.line.append_in(debug_info) debug_info.extend('/') sp.column.append_in(debug_info) debug_info.extend('/') debug_info.append(sp.path) end debug_info.append(" ct:") current_type.debug_info_in(debug_info) debug_info.extend(' ') debug_info.extend('{') target.result_type.debug_info_in(debug_info) debug_info.extend('}') debug_info.extend('.') debug_info.append(feature_name.to_string) if arguments /= Void then debug_info.extend('(') from i := 1 until i > arguments.count loop e := arguments.expression(i) t := e.result_type t.debug_info_in(debug_info) i := i + 1 if i <= arguments.count then debug_info.extend(',') end end debug_info.extend(')') end if run_feature /= Void then debug_info.append(" rf: ") run_feature.debug_info_in(debug_info) end end feature target: EXPRESSION -- Target of the call. feature_name: FEATURE_NAME -- Written selector name of the call. run_feature: RUN_FEATURE -- Non void when runnable and if any `run_feature' exists. arguments: EFFECTIVE_ARG_LIST is -- Arguments of the call if any. deferred ensure Result = Void or else Result.count > 0 end arg_count: INTEGER is -- The `arguments' count or 0. deferred ensure Result >= 0 end feature -- Common frozen: frozen collect_c_tmp is do if run_feature /= Void then run_feature.collect_c_tmp end target.collect_c_tmp if arguments /= Void then arguments.collect_c_tmp end end frozen start_position: POSITION is do Result := feature_name.start_position end use_current, frozen standard_use_current: BOOLEAN is do if arg_count > 0 then Result := arguments.use_current end if Result then elseif target.is_current then if smart_eiffel.top_rf /= run_feature then Result := run_feature.use_current end else Result := target.use_current end end feature frozen afd_check is local trt: E_TYPE; rc: RUN_CLASS; run_time_set: RUN_TIME_SET do if run_feature /= Void then trt := target.result_type rc := trt.run_class run_time_set := rc.run_time_set if run_time_set.count > 1 then switch_collection.update(target,run_feature) end end target.afd_check if arg_count > 0 then arguments.afd_check end afd_check_hook end frozen safety_check is local run_time_set: RUN_TIME_SET do if run_feature /= Void then if arguments /= Void then run_time_set := run_feature.run_class.run_time_set if run_time_set.count >= 1 then smart_eiffel.covariance_check(start_position, run_feature, run_time_set) end end end target.safety_check if arguments /= Void then arguments.safety_check end end feature {RUN_FEATURE_3,RUN_FEATURE_4} finalize is -- For inlining of direct calls on an attribute. require ace.boost smart_eiffel.is_ready run_feature.run_class.run_time_set.count = 1 deferred ensure run_feature.run_class.at_run_time end feature {NONE} afd_check_hook is deferred end frozen call_proc_call_c2c is do cpp.put_cpc(Current) end frozen call_proc_call_c2jvm is do jvm.call_proc_call_mapping(Current) end frozen runnable_target(ct: E_TYPE) is require ct.run_type = ct local t: like target do t := target.to_runnable(ct) if t = Void then error_handler.add_position(target.start_position) error_handler.append("Bad target.") error_handler.add_context_info(ct) error_handler.print_as_fatal_error end target := t end frozen runnable_arguments(ct: E_TYPE): like arguments is require ct.run_type = ct do Result := arguments.to_runnable(ct) if Result = Void then error_handler.add_position(arguments.start_position) error_handler.append(fz_bad_argument) error_handler.add_context_info(ct) error_handler.print_as_fatal_error end end frozen run_feature_for(ct: E_TYPE) is require ct.run_type = ct local rf: RUN_FEATURE; rc: RUN_CLASS; rt: E_TYPE; bc: BASE_CLASS do rt := target.result_type if rt /= Void then rc := rt.run_class if rc /= Void then bc := rc.base_class rf := bc.run_feature_for(rc,target,feature_name,ct) end end if rf = Void then error_handler.add_position(feature_name.start_position) error_handler.append("Bad target for this call.") error_handler.add_context_info(ct) error_handler.print_as_fatal_error end run_feature := rf end frozen call_proc_call_stupid_switch(run_time_set: RUN_TIME_SET): BOOLEAN is local tr: RUN_TIME_SET do if arguments = Void then Result := true else Result := arguments.stupid_switch(run_time_set) end if Result then if target.is_current then if smart_eiffel.same_base_feature(run_feature,run_time_set) then Result := run_feature.stupid_switch(run_time_set) /= Void else Result := false end else Result := target.stupid_switch(run_time_set) if Result then if run_feature /= Void then tr := run_feature.current_type.run_class.run_time_set if tr.count > 1 then Result := smart_eiffel.same_base_feature(run_feature, tr) end end end end end end invariant target /= Void feature_name /= Void end -- CALL_PROC_CALL