note description: "Instance of an Eiffel feature: for every inherited feature there is%N% %an instance of FEATURE_I with its final name, the class name where it%N% %is written, the body id of its content and the routine table ids to%N% %which the feature is attached.%N% %Attribute `type' is the real type of the feature in the class where it%N% %is inherited (or written), that means there is no more anchored type." legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" version: "$Revision$" deferred class FEATURE_I inherit IDABLE SHARED_WORKBENCH SHARED_SERVER export {ANY} all end SHARED_INSTANTIATOR SHARED_ERROR_HANDLER SHARED_TYPES SHARED_EVALUATOR SHARED_TABLE SHARED_AST_CONTEXT SHARED_BYTE_CONTEXT rename context as byte_context end SHARED_PATTERN_TABLE SHARED_INST_CONTEXT SHARED_ID_TABLES export {ANY} Body_index_table, Original_body_index_table end SHARED_ARRAY_BYTE SHARED_EXEC_TABLE HASHABLE rename hash_code as feature_name_id end COMPILER_EXPORTER SHARED_NAMES_HEAP DEBUG_OUTPUT COMPARABLE undefine is_equal end SHARED_STATELESS_VISITOR export {NONE} all end REFACTORING_HELPER export {NONE} all end SHARED_IL_CASING export {NONE} all end SHARED_INLINE_AGENT_LOOKUP feature -- Access feature_name: STRING -- Final name of feature. require feature_name_id_set: feature_name_id > 0 do Result := Names_heap.item (feature_name_id) ensure feature_name_not_void: Result /= Void feature_name_not_empty: not Result.is_empty end alias_name: STRING -- Alias name of feature (if any). do if alias_name_id > 0 then Result := Names_heap.item (alias_name_id) end end assigner_name: STRING -- Associated assigner name (if any). do if assigner_name_id /= 0 then Result := names_heap.item (assigner_name_id) end end feature_name_id: INTEGER -- Id of `feature_name' in `Names_heap' table. alias_name_id: INTEGER -- Id of `alias_name' in `Names_heap' table assigner_name_id: INTEGER -- Id of `assigner_name' in `Names_heap' table do -- 0 (no assigner) by default ensure valid_result: Result /= 0 implies names_heap.valid_index (Result) end feature_id: INTEGER -- Feature id: first key in feature call hash table -- of a class: two features of different names have two -- different feature ids. written_in: INTEGER -- Class id where feature is written body_index: INTEGER -- Index of body id pattern_id: INTEGER -- Id of feature pattern rout_id_set: ROUT_ID_SET -- Routine table to which feature belongs to. export_status: EXPORT_I -- Export status of feature do Result := internal_export_status if Result = Void then if (feature_flags & is_export_status_none_mask) = is_export_status_none_mask then Result := export_none_status else Result := export_all_status end end ensure export_status_not_void: export_status /= Void end origin_feature_id: INTEGER -- Feature ID of Current in associated CLASS_INTERFACE -- that defines it. -- Used for MSIL code generation only. origin_class_id: INTEGER -- Class ID of class defining Current in associated CLASS_INTERFACE -- that defines it. -- Used for MSIL code generation only. written_feature_id: INTEGER -- Feature ID of Current in associated CLASS_C of ID `access_in' -- that gives a body. -- Used for MSIL code generation only. frozen is_origin: BOOLEAN -- Is feature an origin? do Result := feature_flags & is_origin_mask = is_origin_mask end frozen has_replicated_ast: BOOLEAN -- Does feature have a replicated AST? do Result := feature_flags & has_replicated_ast_mask = has_replicated_ast_mask end frozen is_selected: BOOLEAN -- Is feature from a selected branch? do Result := feature_flags & is_selected_mask = is_selected_mask end frozen is_replicated_directly: BOOLEAN -- Is feature directly replicated in class it is created in? -- This flag is needed to distinguish between newly replicated features -- and inherited replicated features as currently the is no way of -- 'selecting' the feature_i object and keeping the 'access_in' value. do Result := feature_flags & is_replicated_directly_mask = is_replicated_directly_mask end frozen from_non_conforming_parent: BOOLEAN -- Is feature inherited from a non-conforming parent? do Result := feature_flags & from_non_conforming_parent_mask = from_non_conforming_parent_mask end frozen is_frozen: BOOLEAN -- Is feature frozen? do Result := feature_flags & is_frozen_mask = is_frozen_mask end frozen is_empty: BOOLEAN -- Is feature with an empty body? do Result := feature_flags & is_empty_mask = is_empty_mask end frozen is_infix: BOOLEAN -- Is feature an infixed one ? do Result := feature_flags & is_infix_mask = is_infix_mask end frozen is_prefix: BOOLEAN -- Is feature a prefixed one ? do Result := feature_flags & is_prefix_mask = is_prefix_mask end frozen is_bracket: BOOLEAN -- Is feature a bracket one ? do Result := feature_flags & is_bracket_mask = is_bracket_mask end frozen is_binary: BOOLEAN -- Is feature a binary one? do Result := feature_flags & is_binary_mask = is_binary_mask end frozen is_unary: BOOLEAN -- Is feature an unary one? do Result := feature_flags & is_unary_mask = is_unary_mask end frozen has_convert_mark: BOOLEAN -- Does binary feature have a convert mark? do Result := feature_flags & has_convert_mark_mask = has_convert_mark_mask end frozen covariantly_redefined_features (a_base_class: CLASS_C): HASH_TABLE [FEATURE_I, CLASS_C] -- Return all the covariantly redefined routines of Current require a_base_class_not_void: a_base_class /= Void conforming_class: a_base_class.conform_to (written_class) local l_descendants: ARRAYED_LIST [CLASS_C] l_feat: FEATURE_I l_covariant_features: like covariantly_redefined_features do if argument_count > 0 then -- If all arguments are expanded or if they are a frozen class -- then it cannot be covariantly redefined if not arguments.for_all (agent (v: TYPE_A): BOOLEAN do Result := v.is_expanded or (v.has_associated_class implies v.associated_class.is_frozen) end) then from l_descendants := a_base_class.direct_descendants create Result.make (l_descendants.count) l_descendants.start until l_descendants.after loop if l_descendants.item.conform_to (a_base_class) then l_feat := l_descendants.item.feature_of_rout_id (rout_id_set.first) -- It could be Void in case of a non-conforming descendants. if is_covariant_to (l_feat) then Result.put (l_feat, l_descendants.item) end l_covariant_features := l_feat.covariantly_redefined_features (l_descendants.item) if l_covariant_features /= Void and then not l_covariant_features.is_empty then Result.merge (l_covariant_features) end end l_descendants.forth end end end end frozen is_covariant_to (other: FEATURE_I): BOOLEAN -- Is `other' a covariant redefinition of Current? require other_not_void: other /= Void subset: other.rout_id_set.has (rout_id_set.first) do from arguments.start other.arguments.start until arguments.after or Result loop -- This is not the best way to check for covariance since `is_equivalent' will -- return False on thing that are not covariantly redefined. Result := not arguments.item.conformance_type.is_safe_equivalent (other.arguments.item.conformance_type) arguments.forth other.arguments.forth end end has_formal: BOOLEAN -- Is formal type present in the feature signature at the top level? -- (Formals used as parameters of generic class types do not count.) local a: like arguments i, l_count: INTEGER do -- It is pretty important that we use `actual_type.is_formal' and not -- just `is_formal' because otherwise if you have `like x' and `x: G' -- then we would fail to detect that. if type.actual_type.is_formal then Result := True else a := arguments if a /= Void then from i := 1 l_count := a.count until i > l_count loop if a [i].actual_type.is_formal then Result := True i := l_count end i := i + 1 end end end end generic_fingerprint: STRING -- Fingerprint of the feature signature that distinguishes -- between formal generic and non-formal-generic types. local digit: NATURAL_8 a: like arguments i: NATURAL_8 z: INTEGER do create Result.make_empty -- It is pretty important that we use `actual_type.is_formal' and not -- just `is_formal' because otherwise if you have `like x' and `x: G' -- then we would fail to detect that. if type.actual_type.is_formal then digit := 1 end a := arguments if a /= Void then from i := 2 a.start until a.after loop if a.item.actual_type.is_formal then digit := digit + i end i := i |<< 1 if i >= 16 then -- Add a digit to the result. Result.append_character (digit.to_hex_character) if digit = 0 then z := z + 1 else z := 0 end digit := 0 i := 1 end a.forth end end if digit /= 0 then Result.append_character (digit.to_hex_character) elseif z > 0 then -- Remove trailing zeroes. Result.remove_tail (z) end end extension: EXTERNAL_EXT_I -- Encapsulation of the external extension do end external_name: STRING -- External name require external_name_id_set: external_name_id > 0 do Result := Names_heap.item (external_name_id) ensure Result_not_void: Result /= Void Result_not_empty: not Result.is_empty end; external_name_id: INTEGER -- External name of feature if any generation. do Result := private_external_name_id if Result = 0 then Result := feature_name_id end end is_inline_agent: BOOLEAN -- is the feature an inline agent do Result := inline_agent_nr /= 0 end enclosing_body_id: INTEGER -- The body id of the enclosing feature of an inline agent enclosing_feature: FEATURE_I -- Gives the (real) feature in which this features is defined. -- If the feature has no enclosing feature, a reference to itself is returned. local l_written_class: CLASS_C do if is_inline_agent then l_written_class := written_class; Result := l_written_class.feature_of_body_index (enclosing_body_id) if Result = Void then Result := l_written_class.invariant_feature end else Result := Current end ensure Result /= Void and not Result.is_inline_agent end inline_agent_nr: INTEGER -- the number of this inline agent in the enclosing feature supports_step_in: BOOLEAN -- Is it possible to step into this feature or set breakpoints in it? do Result := not (enclosing_feature.is_invariant or else is_fake_inline_agent) end feature -- Comparison is_less alias "<" (other: FEATURE_I): BOOLEAN -- Comparison of FEATURE_I based on their name. local l_name, l_other_name: like feature_name do l_name := feature_name l_other_name := other.feature_name if l_name = Void then Result := l_other_name /= Void else Result := l_other_name /= Void and then l_name < l_other_name end end is_same_alias (other: FEATURE_I): BOOLEAN -- Does current have the same alias as `other'? require other_not_void: other /= Void do Result := alias_name_id = other.alias_name_id and then has_convert_mark = other.has_convert_mark end is_same_assigner (other: FEATURE_I; tbl: FEATURE_TABLE): BOOLEAN -- Does current have the same assigner command (if any) as `other'? require other_not_void: other /= Void tbl_not_void: tbl /= Void local assigner_command: FEATURE_I other_assigner_command: FEATURE_I do -- If either of the feature has no assigner command, we treat them as having -- the same assigner command if assigner_name_id = 0 or else other.assigner_name_id = 0 then Result := True else if written_in = system.current_class.class_id then assigner_command := tbl.item_id (assigner_name_id) else assigner_command := written_class.feature_named (assigner_name) end if assigner_command = Void then -- Assigner command is not found error_handler.insert_error (create {VFAC1}.make (system.current_class, Current)) else assigner_command := tbl.feature_of_rout_id (assigner_command.rout_id_set.first) if other.written_in = system.current_class.class_id then other_assigner_command := tbl.item_id (other.assigner_name_id) else other_assigner_command := other.written_class.feature_named (other.assigner_name) end check other_assigner_command_not_void: other_assigner_command /= Void end other_assigner_command := tbl.feature_of_rout_id (other_assigner_command.rout_id_set.first) Result := assigner_command = other_assigner_command end end end feature -- Debugger access number_of_breakpoint_slots: INTEGER -- Number of breakpoint slots in feature (:::) -- It includes pre/postcondition (inner & herited) -- and rescue clause. -- --|--------------------------------------------------------- --| Note from Arnaud PICHERY [ aranud@mail.dotcom.fr ] | --|--------------------------------------------------------- --| If the feature inherits from one routine that has no | --| precondition, the precondition for this routine will | --| always be true and thus will not be generated by the | --| compiler. So, we do not count the preconditions if one | --| of the inherited routines has an empty precondition | --| clause. | --|--------------------------------------------------------- local l_body: like real_body l_routine: ROUTINE_AS do l_body := real_body if l_body /= Void then l_routine ?= l_body.content Result := l_routine.number_of_breakpoint_slots end Result := Result.max (1) end first_breakpoint_slot_index: INTEGER -- Index of the first breakpoint-slot of the body -- Take into account inherited and inner assertions local l_body: like real_body l_routine: ROUTINE_AS l_internal: INTERNAL_AS do l_body := real_body if l_body /= Void then l_routine ?= l_body.content if l_routine /= Void then l_internal ?= l_routine.routine_body if l_internal /= Void then if l_internal.is_empty then --| in this case, the first bp of the body --| is the last breakable point Result := number_of_breakpoint_slots else Result := l_internal.first_breakpoint_slot_index end end end end Result := Result.max (1) end feature -- Status to_melt_in (a_class: CLASS_C): BOOLEAN -- Has current feature to be melted in class `a_class' ? require good_argument: a_class /= Void do Result := a_class.class_id = written_in or else is_replicated_directly end to_generate_in (a_class: CLASS_C): BOOLEAN -- Has current feature to be generated in class `a_class' ? require good_argument: a_class /= Void do Result := a_class.class_id = written_in or else is_replicated_directly end frozen to_implement_in (a_class: CLASS_C): BOOLEAN -- Does Current feature need to be exposed in interface -- used for IL generation? require a_class_not_void: a_class /= Void do Result := a_class.class_id = written_in or else is_replicated_directly end feature -- Setting set_feature_id (i: INTEGER) -- Assign `i' to `feature_id' do feature_id := i end set_body_index (i: INTEGER) -- Assign `i' to `body_index'. do body_index := i end set_pattern_id (i: INTEGER) -- Assign `i' to `pattern_id'. do pattern_id := i end set_feature_name (s: STRING) -- Assign `s' to `feature_name'. -- `set_renamed_name' is needed for C external -- routines that can't be renamed. require s_not_void: s /= Void s_not_empty: not s.is_empty local l_names_heap: like Names_heap do l_names_heap := Names_heap l_names_heap.put (s) feature_name_id := l_names_heap.found_item ensure feature_name_set: equal (feature_name, s) end set_feature_name_id (a_id: INTEGER; alias_id: INTEGER) -- Assign `a_id' to `feature_name_id'. require valid_id: Names_heap.valid_index (a_id) valid_alias_id: Names_heap.valid_index (alias_id) do feature_name_id := a_id alias_name_id := alias_id ensure feature_name_id_set: feature_name_id = a_id alias_name_id_set: alias_name_id = alias_id end set_renamed_name_id (a_id: INTEGER; alias_id: INTEGER) -- Assign `a_id' to `feature_name_id'. require valid_id: Names_heap.valid_index (a_id) valid_alias_id: Names_heap.valid_index (alias_id) do feature_name_id := a_id alias_name_id := alias_id ensure feature_name_id_set: feature_name_id = a_id alias_name_id_set: alias_name_id = alias_id end set_written_in (a_class_id: like written_in) -- Assign `a_class_id' to `access_in'. require a_class_id_not_void: a_class_id > 0 do written_in := a_class_id ensure written_in_set: written_in = a_class_id end set_written_feature_id (a_feature_id: like written_feature_id) -- Assign `a_feature_id' to `written_feature_id'. require valid_feature_id: a_feature_id >= 0 do written_feature_id := a_feature_id ensure written_feature_id_set: written_feature_id = a_feature_id end set_origin_feature_id (a_feature_id: like origin_feature_id) -- Assign `a_feature_id' to `origin_feature_id'. require valid_feature_id: a_feature_id >= 0 do origin_feature_id := a_feature_id ensure origin_feature_id_set: origin_feature_id = a_feature_id end set_origin_class_id (a_class_id: like origin_class_id) -- Assign `a_class_id' to `origin_class_id'. require valid_feature_id: a_class_id >= 0 do origin_class_id := a_class_id ensure origin_class_id_set: origin_class_id = a_class_id end set_export_status (e: EXPORT_I) -- Assign `e' to `export_status'. require e_not_void: e /= Void do if (written_in = system.any_id and then feature_name_id = {PREDEFINED_NAMES}.default_create_name_id) or (written_in = system.routine_class_id and then feature_name_id = {PREDEFINED_NAMES}.feature_id_name_id) or (written_in = system.routine_class_id and then feature_name_id = {PREDEFINED_NAMES}.class_id_name_id) then -- The code generated by the SCOOP degree requires the feature 'default_create' of class 'ANY' to be exported to the proxy class of 'ANY'. -- Other features: -- ROUTINE feature_id required by the SCOOP profiler -- ROUTINE class_id required by the SCOOP profiler -- After degree 4 all compiled features are stored on the disk and cashed in memory. To change the export status permanently we need to make sure our change gets written to the disk. We can achieve this by overwriting the export status upon creation of the compiled feature. internal_export_status := Void feature_flags := feature_flags.set_bit_with_mask (False, is_export_status_none_mask) else if e.is_all or e.is_none then internal_export_status := Void feature_flags := feature_flags.set_bit_with_mask (e.is_none, is_export_status_none_mask) else internal_export_status := e end end ensure normal_export_status_set: not ((written_in = system.any_id and then feature_name_id = {PREDEFINED_NAMES}.default_create_name_id) or (written_in = system.routine_class_id and then feature_name_id = {PREDEFINED_NAMES}.feature_id_name_id) or (written_in = system.routine_class_id and then feature_name_id = {PREDEFINED_NAMES}.class_id_name_id)) implies export_status.same_as (e) any_default_create_export_status_set: (written_in = system.any_id and then feature_name_id = {PREDEFINED_NAMES}.default_create_name_id) implies export_status.is_all end frozen set_is_origin (b: BOOLEAN) -- Assign `b' to `is_origin'. do feature_flags := feature_flags.set_bit_with_mask (b, is_origin_mask) ensure is_origin_set: is_origin = b end frozen set_is_selected (b: BOOLEAN) -- Assign `b' to `is_selected'. do feature_flags := feature_flags.set_bit_with_mask (b, is_selected_mask) ensure is_selected_set: is_selected = b end frozen set_has_replicated_ast (b: BOOLEAN) -- Assign `b' to `has_replicated_ast'. do feature_flags := feature_flags.set_bit_with_mask (b, has_replicated_ast_mask) ensure has_replicated_ast_set: has_replicated_ast = b end frozen set_is_replicated_directly (b: BOOLEAN) -- Assign `b' to `is_replicated_directly'. do feature_flags := feature_flags.set_bit_with_mask (b, is_replicated_directly_mask) ensure is_replicated_directly_set: is_replicated_directly = b end frozen set_from_non_conforming_parent (b: BOOLEAN) -- Assign `b' to `from_non_conforming_parent'. do feature_flags := feature_flags.set_bit_with_mask (b, from_non_conforming_parent_mask) ensure from_non_conforming_parent_set: from_non_conforming_parent = b end frozen set_is_empty (b : BOOLEAN) -- Set `is_empty' to `b' do feature_flags := feature_flags.set_bit_with_mask (b, is_empty_mask) ensure is_empty_set: is_empty = b end frozen set_is_frozen (b: BOOLEAN) -- Assign `b' to `is_frozen'. --|Note: nothing to do with melted/frozen features do feature_flags := feature_flags.set_bit_with_mask (b, is_frozen_mask) ensure is_frozen_set: is_frozen = b end frozen set_is_infix (b: BOOLEAN) -- Assign `b' to `is_infix'. do feature_flags := feature_flags.set_bit_with_mask (b, is_infix_mask) ensure is_infix_set: is_infix = b end frozen set_is_prefix (b: BOOLEAN) -- Assign `b' to `is_prefix'. do feature_flags := feature_flags.set_bit_with_mask (b, is_prefix_mask) ensure is_prefix_set: is_prefix = b end frozen set_is_bracket (b: BOOLEAN) -- Assign `b' to `is_bracket'. do feature_flags := feature_flags.set_bit_with_mask (b, is_bracket_mask) ensure is_bracket_set: is_bracket = b end frozen set_is_binary (b: BOOLEAN) -- Assign `b' to `is_binary'. do feature_flags := feature_flags.set_bit_with_mask (b, is_binary_mask) ensure is_binary_set: is_binary = b end frozen set_is_unary (b: BOOLEAN) -- Assign `b' to `is_unary'. do feature_flags := feature_flags.set_bit_with_mask (b, is_unary_mask) ensure is_unary_set: is_unary = b end frozen set_has_convert_mark (b: BOOLEAN) -- Assign `b' to `has_convert_mark'. do feature_flags := feature_flags.set_bit_with_mask (b, has_convert_mark_mask) ensure has_convert_mark_set: has_convert_mark = b end frozen set_is_require_else (b: BOOLEAN) -- Assign `b' to `is_require_else'. do feature_flags := feature_flags.set_bit_with_mask (b, is_require_else_mask) ensure is_require_else_set: is_require_else = b end frozen set_is_ensure_then (b: BOOLEAN) -- Assign `b' to `is_ensure_then'. do feature_flags := feature_flags.set_bit_with_mask (b, is_ensure_then_mask) ensure is_ensure_then_set: is_ensure_then = b end frozen set_has_precondition (b: BOOLEAN) -- Assign `b' to `has_precondition'. do feature_flags := feature_flags.set_bit_with_mask (b, has_precondition_mask) ensure has_precondition_set: has_precondition = b end frozen set_has_postcondition (b: BOOLEAN) -- Assign `b' to `has_postcondition'. do feature_flags := feature_flags.set_bit_with_mask (b, has_postcondition_mask) ensure has_postcondition_set: has_postcondition = b end frozen set_is_fake_inline_agent (b: BOOLEAN) -- Assign `b' to `is_fake_inline_agent'. do feature_flags := feature_flags.set_bit_with_mask (b, is_fake_inline_agent_mask) ensure is_fake_inline_agent_set: is_fake_inline_agent = b end frozen set_has_rescue_clause (b: BOOLEAN) -- Assign `b' to `has_rescue_clause'. do feature_flags := feature_flags.set_bit_with_mask (b, has_rescue_clause_mask) ensure has_rescue_clause_set: has_rescue_clause = b end set_has_property (v: BOOLEAN) -- Set `has_property' to `v'. do feature_flags := feature_flags.set_bit_with_mask (v, has_property_mask) ensure has_property_set: has_property = v end set_has_property_getter (v: BOOLEAN) -- Set `has_property_getter' to `v'. do feature_flags := feature_flags.set_bit_with_mask (v, has_property_getter_mask) ensure has_property_getter_set: has_property_getter = v end set_has_property_setter (v: BOOLEAN) -- Set `has_property_setter' to `v'. do feature_flags := feature_flags.set_bit_with_mask (v, has_property_setter_mask) ensure has_property_setter_set: has_property_setter = v end set_rout_id_set (an_id_set: like rout_id_set) -- Assign `an_id_set' to `rout_id_set'. require an_id_set_not_void: an_id_set /= Void do rout_id_set := an_id_set ensure rout_id_set: rout_id_set = an_id_set end set_private_external_name_id (n_id: like private_external_name_id) -- Assign `n_id' to `private_external_name_id'. require valid_n: n_id > 0 do private_external_name_id := n_id ensure private_external_name_set: private_external_name_id = n_id end generation_class_id: INTEGER -- Id of class where feature has to be generated in do Result := written_in end duplicate: like Current -- Clone do Result := twin end duplicate_arguments -- Do a clone of arguments (for replication) do -- Do nothing end set_inline_agent (a_enclosing_body_id, a_inline_agent_nr: INTEGER) -- Define this feature as an inline agent require enclosing_body_id_valid: a_enclosing_body_id > 0 inline_agent_nr_valid: (is_fake_inline_agent implies a_inline_agent_nr = -1) and not is_fake_inline_agent implies a_inline_agent_nr > 0 do inline_agent_nr := a_inline_agent_nr enclosing_body_id := a_enclosing_body_id end feature -- Incrementality equiv (other: FEATURE_I): BOOLEAN -- Incrementality test on instance of FEATURE_I during -- second pass. require good_argument: other /= Void do Result := written_in = other.written_in and then body_index = other.body_index and then rout_id_set.same_as (other.rout_id_set) and then is_origin = other.is_origin and then is_frozen = other.is_frozen and then is_deferred = other.is_deferred and then is_external = other.is_external and then export_status.same_as (other.export_status) and then same_signature (other) and then has_precondition = other.has_precondition and then has_postcondition = other.has_postcondition and then is_once = other.is_once and then is_process_relative = other.is_process_relative and then is_constant = other.is_constant and then is_stable = other.is_stable and then alias_name_id = other.alias_name_id and then has_convert_mark = other.has_convert_mark and then assigner_name_id = other.assigner_name_id and then has_property = other.has_property and then (has_property implies property_name.is_equal (other.property_name)) and then has_property_getter = other.has_property_getter and then has_property_setter = other.has_property_setter debug ("ACTIVITY") if not Result then io.error.put_boolean (written_in = other.written_in) io.error.put_new_line; io.error.put_boolean (rout_id_set.same_as (other.rout_id_set)) io.error.put_new_line; io.error.put_boolean (is_origin = other.is_origin) io.error.put_new_line; io.error.put_boolean (is_frozen = other.is_frozen) io.error.put_new_line; io.error.put_boolean (is_deferred = other.is_deferred) io.error.put_new_line; io.error.put_boolean (is_external = other.is_external) io.error.put_new_line; io.error.put_boolean (export_status.same_as (other.export_status)) io.error.put_new_line; io.error.put_boolean (same_signature (other)) io.error.put_new_line; io.error.put_boolean (has_precondition = other.has_precondition) io.error.put_new_line; io.error.put_boolean (has_postcondition = other.has_postcondition) io.error.put_new_line; io.error.put_boolean (is_once = other.is_once) io.error.put_new_line; end end if Result then if assert_id_set /= Void then Result := assert_id_set.same_as (other.assert_id_set) else Result := (other.assert_id_set = Void) end end if Result and then rout_id_set.first = System.default_rescue_rout_id then -- This is the default rescue feature. -- Test whether emptiness of body has changed. Result := (is_empty = other.is_empty) end if Result and then rout_id_set.first = System.default_create_rout_id then -- This is the default create feature. -- Test whether emptiness of body has changed. Result := (is_empty = other.is_empty) end debug ("ACTIVITY") if not Result then io.error.put_string ("%T%T") io.error.put_string (feature_name) io.error.put_string (" is not equiv%N") end end end select_table_equiv (other: FEATURE_I): BOOLEAN -- Incrementality of select table require good_argument: other /= Void do Result := written_in = other.written_in and then rout_id_set.same_as (other.rout_id_set) and then is_origin = other.is_origin and then body_index = other.body_index and then type.is_safe_equivalent (other.type) end is_valid: BOOLEAN -- Is feature still valid? -- Incrementality: The types of arguments and/or result -- are still defined in system do Result := type.is_valid if Result and then has_arguments then Result := arguments.is_valid end end same_class_type (other: FEATURE_I): BOOLEAN -- Has `other' same resulting type than Current ? require good_argument: other /= Void same_names: other.feature_name_id = feature_name_id do Result := type.same_as (other.type) end same_interface (other: FEATURE_I): BOOLEAN -- Has `other' same interface than Current ? -- [Semnatic for second pass is `old_feat.same_interface (new)'] require good_argument: other /= Void -- export_statuses_exist: not (export_status = Void -- or else other.export_status = Void) do -- Still an attribute Result := is_attribute = other.is_attribute -- Same alias if Result then Result := alias_name_id = other.alias_name_id if Result then Result := has_convert_mark = other.has_convert_mark end end -- Same assigner procedure if Result then Result := assigner_name_id = other.assigner_name_id end -- Same return type Result := Result and then type.same_as (other.type) -- and then export_status.equiv (other.export_status) -- Same arguments if any if Result then if argument_count = 0 then Result := other.argument_count = 0 else Result := argument_count = other.argument_count and then arguments.same_interface (other.arguments) end end -- Still a once Result := Result and then is_once = other.is_once -- Of the same stability Result := Result and then is_stable = other.is_stable end feature -- creation of default rescue clause create_default_rescue (def_resc_name_id: INTEGER) -- Create default_rescue clause if necessary require valid_feature_name_id : def_resc_name_id > 0 local my_body : like body do if not (is_attribute or is_constant or is_external or is_deferred) then my_body := body if (my_body /= Void) then my_body.create_default_rescue (def_resc_name_id) end end end feature -- Type id written_type (class_type: CLASS_TYPE): CLASS_TYPE -- Written type of feature in context of -- type `class_type'. require good_argument: class_type /= Void conformance: class_type.associated_class.conform_to (written_class) do Result := written_class.meta_type (class_type) end feature -- Conveniences assert_id_set: ASSERT_ID_SET -- Assertions to which procedure belongs to -- (To be redefined in PROCEDURE_I). do -- Do nothing end is_obsolete: BOOLEAN -- Is Current feature obsolete? do Result := obsolete_message /= Void end obsolete_message: STRING -- Obsolete message -- (Void if Current is not obsolete) do -- Do nothing end has_arguments: BOOLEAN -- Has current feature some formal arguments ? do Result := arguments /= Void end is_replicated: BOOLEAN -- Is Current feature conceptually replicated? do -- Do nothing end is_routine: BOOLEAN -- Is current feature a routine ? do -- Do nothing end is_function: BOOLEAN -- Is current feature a function ? do -- Do nothing end is_type_feature: BOOLEAN -- Is current an instance of TYPE_FEATURE_I? do -- Do nothing end is_attribute: BOOLEAN -- Is current feature an attribute ? do -- Do nothing end is_constant: BOOLEAN -- Is current feature a constant ? do -- Do nothing end is_once: BOOLEAN -- Is current feature a once one ? do -- Do nothing end is_do: BOOLEAN -- Is current feature a do one ? do -- Do nothing end is_deferred: BOOLEAN -- Is current feature a deferred one ? do -- Do nothing end is_unique: BOOLEAN -- Is current feature a unique constant ? do -- Do nothing end is_external: BOOLEAN -- Is current feature an external one ? do -- Do nothing end has_return_value: BOOLEAN -- Does current return a value? do Result := is_constant or is_attribute or is_function ensure validity: Result implies (is_constant or is_attribute or is_function) end frozen is_il_external: BOOLEAN -- Is current feature a C external one? local ext: IL_EXTENSION_I l_const: CONSTANT_I do ext ?= extension Result := ext /= Void if not Result then l_const ?= Current if l_const /= Void then Result := l_const.written_class.is_external end end ensure not_is_c_external: Result implies not is_c_external end frozen is_c_external: BOOLEAN -- Is current feature a C external one? local ext: EXTERNAL_EXT_I do ext := extension Result := ext /= Void and then not ext.is_il ensure not_is_il_external: Result implies not is_il_external end is_process_relative: BOOLEAN -- Is feature process-wide (rather than thread-local)? -- (Usually applies to once routines.) do -- False by default end is_stable: BOOLEAN -- Is feature stable, i.e. never gets Void after returning a non-void value? -- (Usually applies to attributes.) do -- False by default end has_static_access: BOOLEAN -- Can Current be access in a static manner? local l_ext: IL_EXTENSION_I do Result := is_constant if not Result then if System.il_generation then l_ext ?= extension -- Static access only if it is a C external (l_ext = Void) -- or if IL external does not need an object. Result := (l_ext = Void and (is_external and not has_assertion)) or (l_ext /= Void and then not l_ext.need_current (l_ext.type)) else Result := is_external and not has_assertion end end end frozen has_precondition: BOOLEAN -- Is feature declaring some preconditions ? do Result := feature_flags & has_precondition_mask = has_precondition_mask end frozen has_postcondition: BOOLEAN -- Is feature declaring some postconditions ? do Result := feature_flags & has_postcondition_mask = has_postcondition_mask end has_assertion: BOOLEAN -- Is feature declaring some pre or post conditions ? do Result := has_postcondition or else has_precondition end frozen is_require_else: BOOLEAN -- Is precondition block of feature a redefined one ? do Result := feature_flags & is_require_else_mask = is_require_else_mask end frozen is_ensure_then: BOOLEAN -- Is postcondition block of feature a redefined one ? do Result := feature_flags & is_ensure_then_mask = is_ensure_then_mask end frozen is_fake_inline_agent: BOOLEAN -- Is postcondition block of feature a redefined one ? do Result := feature_flags & is_fake_inline_agent_mask = is_fake_inline_agent_mask end frozen has_rescue_clause: BOOLEAN -- Has rescue clause ? do Result := feature_flags & has_rescue_clause_mask = has_rescue_clause_mask end is_invariant: BOOLEAN -- Is this feature the invariant feature of its eiffel class ? do Result := False end can_be_encapsulated: BOOLEAN -- Is current feature a feature that can be encapsulated? -- Eg: attribute or constant. do end redefinable: BOOLEAN -- Is feature redefinable ? do Result := not is_frozen end undefinable: BOOLEAN -- Is feature undefinable ? do Result := redefinable end has_property: BOOLEAN -- Does feature have an associated property? do Result := feature_flags & has_property_mask = has_property_mask end has_property_getter: BOOLEAN -- Does feature have an associated property getter? do Result := feature_flags & has_property_getter_mask = has_property_getter_mask end has_property_setter: BOOLEAN -- Does feature have an associated property setter? do Result := feature_flags & has_property_setter_mask = has_property_setter_mask end property_name: STRING -- IL property name. do if byte_server.has (body_index) then Result := byte_server.item (body_index).property_name end if Result = Void or else Result.is_empty then -- Explicit property name is not specified Result := il_casing.pascal_casing (system.dotnet_naming_convention, feature_name, {IL_CASING_CONVERSION}.lower_case) end ensure result_attached: Result /= Void end type: TYPE_A -- Result type of feature do Result := void_type ensure type_not_void: Result /= Void end set_type (t: like type; a: like assigner_name_id) -- Assign `t' to `type' and `a' to `assigner_name_id'. require t_not_void: t /= Void valid_a: a /= 0 implies names_heap.valid_index (a) do -- Do nothing ensure type_set: type ~ t end arguments: FEAT_ARG -- Argument types do -- No arguments end set_arguments (args: like arguments) -- Assign `args' to arguments. do end set_assert_id_set (set: like assert_id_set) -- Assign `set' to assert_id_set. do -- Do nothing end argument_count: INTEGER -- Number of arguments of feature do if arguments /= Void then Result := arguments.count end end written_class: CLASS_C -- Class where feature is written in require good_written_in: written_in /= 0 do Result := System.class_of_id (written_in) ensure written_class_not_void: Result /= Void end access_class: CLASS_C -- Class where current feature can be accessed -- through its routine id. -- Useful for replication require access_in_positive: access_in > 0 do Result := System.class_of_id (access_in) ensure written_class_not_void: Result /= Void end feature -- Export checking -- has_special_export: BOOLEAN is -- -- The export status is special, i.e. feature -- -- is not exported to all other classes. -- -- A call to this feature must be recorded specially -- -- in dependances for incrementality purpose: -- -- If hierarchy changes, call may be invalid. -- require -- has_export_status: export_status /= Void -- do -- Result := not export_status.is_all -- end is_exported_for (client: CLASS_C): BOOLEAN -- Is current feature exported to class `client' ? require good_argument: client /= Void has_export_status: export_status /= Void local l_ncp_classes: FIXED_LIST [CLASS_C] do Result := export_status.valid_for (client) if not Result then -- We need to check that `Current' is non-conformally inherited by `client'. l_ncp_classes := client.non_conforming_parents_classes if l_ncp_classes /= Void then from l_ncp_classes.start until Result or else l_ncp_classes.after loop Result := export_status.valid_for (l_ncp_classes.item) l_ncp_classes.forth end end end end record_suppliers (feat_depend: FEATURE_DEPENDANCE) -- Record suppliers ids in `feat_depend' require good_arg: feat_depend /= Void local type_a: TYPE_A do -- Create the supplier set for the feature type_a := type if type_a /= Void then if type_a.has_associated_class then feat_depend.add_supplier (type_a.associated_class) end type_a.update_dependance (feat_depend) end if has_arguments then from arguments.start until arguments.after loop type_a := arguments.item if type_a.has_associated_class then feat_depend.add_supplier (type_a.associated_class) end arguments.forth end end end suppliers: TWO_WAY_SORTED_SET [INTEGER] -- Class ids of all suppliers of feature require has_dependance: depend_server.has (written_in) local class_dependance: CLASS_DEPENDANCE do class_dependance := depend_server.item (written_in) check class_dependance_not_void: class_dependance /= Void end Result := class_dependance.item (body_index).suppliers end feature -- Check real_body: BODY_AS -- Body of feature local feat_as: FEATURE_AS l_enclosing_feature: FEATURE_I do if not is_inline_agent then feat_as := body if feat_as /= Void then Result := feat_as.body end else if not is_fake_inline_agent then l_enclosing_feature := enclosing_feature if l_enclosing_feature.is_invariant then Result := inline_agent_lookup.lookup_inline_agent_of_invariant ( inv_ast_server.item (written_in), inline_agent_nr) else Result := inline_agent_lookup.lookup_inline_agent_of_feature ( l_enclosing_feature.body, inline_agent_nr) end end end end body: FEATURE_AS -- Body of feature require not_is_inline_agent: not is_inline_agent local class_ast: CLASS_AS bid: INTEGER do bid := body_index if bid > 0 then Result := body_server.item (bid) end if Result = Void then -- Means a degree 4 error has occurred so the -- best we can do is to search through the -- class ast and find the feature as if has_replicated_ast then class_ast := Tmp_ast_server.item (access_in) else class_ast := Tmp_ast_server.item (written_in) end if class_ast /= Void then Result := class_ast.feature_with_name (feature_name_id) end end end -- Note: `require else' can be used even if feature has no -- precursor. There is no problem to raise an error in normal case, -- only case where we cannot do anything is when aliases are used -- and one name references a feature with a predecessor and not -- other one -- Used to be called from `type_check': -- -- check_assertions is -- -- Raise an error if "require else" or "ensure then" is used -- -- but feature has no ancestor -- do -- end check_local_names (a_body: BODY_AS) -- Check conflicts between local names and feature names -- for an unchanged feature do end feature -- IL code generation generate_il -- Generate IL code for current feature. local byte_code: BYTE_CODE do if not is_attribute and then not is_external then byte_code := Byte_server.disk_item (body_index) byte_context.set_byte_code (byte_code) byte_context.set_current_feature (Current) byte_code.generate_il byte_context.clear_feature_data end end custom_attributes: BYTE_LIST [BYTE_NODE] -- Custom attributes of Current if any. local byte_code: BYTE_CODE do if not is_attribute and then not is_external and then not is_il_external then if Byte_server.has (body_index) then byte_code := Byte_server.item (body_index) Result := byte_code.custom_attributes end end end class_custom_attributes: BYTE_LIST [BYTE_NODE] -- Class custom attributes of Current if any. local byte_code: BYTE_CODE do if not is_attribute and then not is_external and then not is_il_external then if Byte_server.has (body_index) then byte_code := Byte_server.item (body_index) Result := byte_code.class_custom_attributes end end end interface_custom_attributes: BYTE_LIST [BYTE_NODE] -- Interface custom attributes of Current if any. local byte_code: BYTE_CODE do if not is_attribute and then not is_external and then not is_il_external then if Byte_server.has (body_index) then byte_code := Byte_server.item (body_index) Result := byte_code.interface_custom_attributes end end end property_custom_attributes: BYTE_LIST [BYTE_NODE] -- Custom attributes of Current if any. do if Byte_server.has (body_index) then Result := Byte_server.item (body_index).property_custom_attributes end end feature -- Byte code computation melt (exec: EXECUTION_UNIT) -- Generate byte code for current feature -- [To be redefined in CONSTANT_I, ATTRIBUTE_I and in EXTERNAL_I]. require good_argument: exec /= Void local byte_code: BYTE_CODE melted_feature: MELT_FEATURE do byte_code := Byte_server.item (body_index) byte_context.set_byte_code (byte_code) byte_context.set_current_feature (Current) Byte_array.clear byte_code.set_real_body_id (exec.real_body_id) byte_code.make_byte_code (Byte_array) byte_context.clear_feature_data melted_feature := Byte_array.melted_feature melted_feature.set_real_body_id (exec.real_body_id) if not System.freeze then Tmp_m_feature_server.put (melted_feature) end Execution_table.mark_melted (exec) end feature -- Polymorphism has_entry: BOOLEAN -- Has feature an associated polymorphic unit ? do Result := True end new_poly_table (rout_id: INTEGER): POLY_TABLE [ENTRY] -- New polymorphic table require positive_rout_id: rout_id > 0 valid_rout_id: rout_id_set.has (rout_id) local seed: FEATURE_I do if not is_attribute or else not Routine_id_counter.is_attribute (rout_id) then -- This is a routine. -- The seed is a routine as well. create {ROUT_TABLE} Result.make (rout_id) else seed := system.seed_of_routine_id (rout_id) if seed.has_formal then -- This is an attribute with a seed of a formal generic type that may become expanded. create {GENERIC_ATTRIBUTE_TABLE} Result.make (rout_id, True) elseif not seed.type.actual_type.is_expanded then -- This is an attribute with a seed of a non-expanded type that may require initialization. create {GENERIC_ATTRIBUTE_TABLE} Result.make (rout_id, False) else -- This is an attribute with a seed that is not of a formal generic type. create {ATTR_TABLE [ATTR_ENTRY]} Result.make (rout_id) end end end new_entry (rout_id: INTEGER): ENTRY -- New polymorphic unit require rout_id_not_void: rout_id /= 0 local r: like new_rout_entry do if is_attribute and then Routine_id_counter.is_attribute (rout_id) then if byte_context.workbench_mode or else has_formal then r := new_rout_entry r.set_is_attribute Result := r else Result := new_attr_entry end else Result := new_rout_entry end end new_rout_entry: ROUT_ENTRY -- New routine unit do create Result Result.set_body_index (body_index) Result.set_type_a (type) if has_replicated_ast then -- If AST has been replicated, then we must use `access_in' -- as this is the new written in value. Result.set_access_in (access_in) Result.set_written_in (written_in) else Result.set_written_in (written_in) Result.set_access_in (written_in) end Result.set_pattern_id (pattern_id) Result.set_feature_id (feature_id) Result.set_is_deferred (is_deferred) end new_attr_entry: ATTR_ENTRY -- New attribute unit require is_attribute: is_attribute do create Result Result.set_type_a (type) Result.set_feature_id (feature_id) end poly_equiv (other: FEATURE_I): BOOLEAN -- Is `other' equivalent to Current from polymorphic table -- implementation point of view ? require good_argument: other /= Void local is_attr: BOOLEAN do is_attr := is_attribute Result := other.is_attribute = is_attr and then type.actual_type.same_as (other.type.actual_type) if Result then if is_attr then Result := feature_id = other.feature_id else Result := written_in = other.written_in and then body_index = other.body_index and then pattern_id = other.pattern_id end end end feature -- Signature instantiation instantiated (parent_type: TYPE_A): FEATURE_I -- Instantiated signature in context of `parent_type'. require good_argument: parent_type /= Void is_solved: type.is_solved local i, nb: INTEGER old_type, new_type: TYPE_A l_arguments: like arguments do -- Instantiation of the type old_type := type new_type := old_type.instantiated_in (parent_type) if new_type /= old_type then Result := duplicate Result.set_type (new_type, assigner_name_id) -- Set arguments to that of `Result' l_arguments := Result.arguments else -- Use `Current' arguments. l_arguments := arguments end -- Instantiation of the arguments from i := 1 if l_arguments /= Void then nb := l_arguments.count end until i > nb loop old_type := l_arguments.i_th (i) new_type := old_type.instantiated_in (parent_type) if old_type /= new_type then if Result = Void then Result := duplicate l_arguments := Result.arguments end l_arguments.put_i_th (new_type, i) end i := i + 1 end -- If no changes have been made then we can return `Current' if Result = Void then Result := Current end end instantiation_in (descendant_type: TYPE_A): FEATURE_I -- Instantiated signature in context of `descendant_type'. require good_argument: descendant_type /= Void is_solved: type.is_solved local i, nb: INTEGER old_type, new_type: TYPE_A l_arguments: like arguments l_written_in: like written_in do l_written_in := written_in -- Instantiation of the type old_type := type new_type := old_type.instantiation_in (descendant_type, l_written_in) if new_type /= old_type then Result := duplicate Result.set_type (new_type, assigner_name_id) l_arguments := Result.arguments else l_arguments := arguments end -- Instantiation of the arguments from i := 1 if l_arguments /= Void then nb := l_arguments.count end until i > nb loop old_type := l_arguments.i_th (i) new_type := old_type.instantiation_in (descendant_type, l_written_in) if new_type /= old_type then if Result = Void then Result := duplicate l_arguments := Result.arguments end l_arguments.put_i_th (new_type, i) end i := i + 1 end -- If no changes have been made then we can return `Current' if Result = Void then -- Return `Current' if no changes have been made. Result := Current end end feature -- Signature checking check_argument_names (feat_table: FEATURE_TABLE) -- Check argument names require argument_names_exists: arguments.argument_names /= Void written_in_class: written_in = feat_table.feat_tbl_id -- The feature must be written in the associated class -- of `feat_table'. local args: like arguments arg_id: INTEGER vreg: VREG vrfa: VRFA vpir: VPIR1 i, nb: INTEGER do from args := arguments i := 1 nb := args.count until i > nb loop arg_id := args.item_id (i) -- Searching to find after the current item another one -- with the same name. -- We do `i + 1' for the start index because we need to go -- one step further (+ 1) if args.argument_position_id (arg_id, i + 1) /= 0 then -- Two arguments with the same name create vreg vreg.set_class (written_class) vreg.set_feature (Current) vreg.set_entity_name (Names_heap.item (arg_id)) Error_handler.insert_error (vreg) end feat_table.search_id (arg_id) if feat_table.found then -- An argument name is a feature name of the feature -- table. create vrfa vrfa.set_class (written_class) vrfa.set_feature (Current) vrfa.set_other_feature (feat_table.found_item) Error_handler.insert_error (vrfa) end if context.is_name_used (arg_id) then -- An argument name is an argument name of an enclosing feature create vpir vpir.set_entity_name (arg_id) vpir.set_class (written_class) vpir.set_feature (Current) Error_handler.insert_error (vpir) end i := i + 1 end end check_types (feat_table: FEATURE_TABLE) -- Check type and arguments types. The objective is -- to deal with anchored types and genericity. All anchored -- types are interpreted here and generic parameter -- instantiated if possible. -- Make sure that `context' is already initialized for `feat_table' before calling. require context_initialize_for_feat_table: context.current_feature_table = feat_table and then context.current_class = feat_table.associated_class local solved_type: TYPE_A vffd5: VFFD5 vffd6: VFFD6 vffd7: VFFD7 l_class: CLASS_C l_error_level: NATURAL_32 do l_class := feat_table.associated_class -- Make sure that context is already initialized for `feat_table' by caller. -- This saves expensive repeated calls to `actual_type'. context.initialize (l_class, l_class.actual_type, feat_table) context.set_current_feature (Current) -- Not that the checks is only done for real `onces'. Constants -- have their checks done through VQMC. if type.has_like and then (is_once and not is_constant) then -- We have an anchored type. -- Check if the feature is not a once feature create vffd7 vffd7.set_class (written_class) vffd7.set_feature_name (feature_name) Error_handler.insert_error (vffd7) end -- Process an actual type for the feature interpret -- anchored types. type_a_checker.init_with_feature_table (Current, feat_table, Void, error_handler) solved_type := type_a_checker.check_and_solved (type, Void) if solved_type /= Void then set_type (solved_type, assigner_name_id) -- Instantitate the feature type in the context of the -- actual type of the class associated to `feat_table'. if (is_once and not is_constant) and then solved_type.has_formal_generic then -- A once funtion cannot have a type with formal generics create vffd7 vffd7.set_class (written_class) vffd7.set_feature_name (feature_name) Error_handler.insert_error (vffd7) end if is_infix and then ((argument_count /= 1) or else (solved_type.is_void)) then -- Infixed features should have only one argument -- and must have a return type. create vffd6 vffd6.set_class (written_class) vffd6.set_feature_name (feature_name) Error_handler.insert_error (vffd6) end if is_prefix and then ((argument_count /= 0) or else (solved_type.is_void)) then -- Prefixed features shouldn't have any argument -- and must have a return type. create vffd5 vffd5.set_class (written_class) vffd5.set_feature_name (feature_name) Error_handler.insert_error (vffd5) end if l_class.class_id = written_in then type_a_checker.check_type_validity (solved_type, Void) solved_type.check_for_obsolete_class (l_class, Current) end if arguments /= Void then -- Check types of arguments l_error_level := error_handler.error_level arguments.check_types (feat_table, Current) if l_class.class_id = written_in and then l_error_level = error_handler.error_level then arguments.check_type_validity (l_class, Current, type_a_checker, True) end end end end check_type_validity (a_context_class: CLASS_C) -- Check type validity. require context_class_not_void: a_context_class /= Void context_initialized: context.current_class = a_context_class and context.current_feature = Current local l_type: TYPE_A do if a_context_class.changed then -- Generic types tracking -- This needs to be called for all features update_instantiator2 (a_context_class) end if a_context_class.class_id = written_in then l_type := type -- We only need to check the features that are actually defined in the current class -- as inherited features should already have been checked. type_a_checker.init_with_feature_table ( Current, a_context_class.feature_table, Void, error_handler) if not l_type.is_void then type_a_checker.check_type_validity (l_type, Void) end if arguments /= Void then -- Check types of arguments arguments.check_type_validity (a_context_class, Current, type_a_checker, False) end end end check_expanded (class_c: CLASS_C) -- Check expanded validity rules require class_c_not_void: class_c /= Void type /= Void local solved_type: TYPE_A vtec: VTEC do debug ("CHECK_EXPANDED") io.error.put_string ("Check expanded of ") io.error.put_string (feature_name) io.error.put_new_line end if class_c.class_id = written_in then -- Check validity of an expanded result type -- `set_type' has been called in `check_types' so -- the reverse assignment is valid. solved_type ?= type.actual_type if solved_type.has_expanded then if solved_type.expanded_deferred then create {VTEC1} vtec elseif not solved_type.valid_expanded_creation (class_c) then create {VTEC2} vtec elseif system.il_generation and then not solved_type.is_ancestor_valid then -- Expanded type cannot be based on a class with external ancestor. create {VTEC3} vtec end if vtec /= Void then -- Report error vtec.set_class (written_class) vtec.set_feature (Current) vtec.set_entity_name (feature_name) Error_handler.insert_error (vtec) end end if solved_type.has_generics then system.expanded_checker.check_actual_type (solved_type) end if arguments /= Void then arguments.check_expanded (class_c, Current) end end end check_signature (old_feature: FEATURE_I; tbl: FEATURE_TABLE) -- Check signature conformance beetween Current -- and inherited feature in `inherit_info' from which Current -- is a redefinition. require old_feature_not_void: old_feature /= Void tbl_not_void: tbl /= Void local old_type, new_type: TYPE_A i, arg_count: INTEGER old_arguments: like arguments current_class: CLASS_C vdrd51: VDRD51 vdrd52: VDRD52 vdrd53: VDRD53 vdrd6: VDRD6 vdrd7: VDRD7 ve02: VE02 l_vtug: VTUG do debug ("ACTIVITY") io.error.put_string ("Check signature of ") io.error.put_string (feature_name) io.error.put_new_line end current_class := System.current_class -- Check if an attribute is redefined in an attribute -- of the same expandedness status if old_feature.is_attribute and then (not is_attribute or else old_feature.type.is_expanded /= type.is_expanded or else old_feature.type.is_reference /= type.is_reference) then create vdrd6 vdrd6.init (old_feature, Current) Error_handler.insert_error (vdrd6) end -- Check if an effective feature is not redefined in a -- non-effective feature if (not old_feature.is_deferred) and then is_deferred then create vdrd7 vdrd7.set_class (current_class) vdrd7.init (old_feature, Current) Error_handler.insert_error (vdrd7) end old_type ?= old_feature.type old_type := old_type.actual_argument_type (special_arguments).actual_type -- `new_type' is the actual type of the redefinition already -- instantiated new_type := type.actual_type debug ("ACTIVITY") io.error.put_string ("Types:%N") if old_type /= Void then io.error.put_string ("old type:%N") io.error.put_string (old_type.dump) io.error.put_new_line end if new_type /= Void then io.error.put_string ("new type:%N") io.error.put_string (new_type.dump) io.error.put_new_line else io.error.put_string ("New type: VOID%Ntype:") io.error.put_string (type.dump) io.error.put_new_line io.error.put_string (type.out) io.error.put_new_line end io.error.put_new_line end if not new_type.good_generics then l_vtug := new_type.error_generics l_vtug.set_class (current_class) l_vtug.set_feature (Current) error_handler.insert_error (l_vtug) elseif not new_type.conform_to (current_class, old_type) then create vdrd51 vdrd51.init (old_feature, Current) Error_handler.insert_error (vdrd51) elseif is_attribute and then new_type.is_expanded /= old_type.is_expanded then create ve02 ve02.init (old_feature, Current) Error_handler.insert_error (ve02) end -- Check the argument count if argument_count /= old_feature.argument_count then create vdrd52 vdrd52.init (old_feature, Current) Error_handler.insert_error (vdrd52) else -- Check the argument conformance from i := 1 arg_count := argument_count old_arguments := old_feature.arguments until i > arg_count loop old_type := old_arguments.i_th (i) old_type := old_type.actual_argument_type (special_arguments).actual_type new_type := arguments.i_th (i).actual_type debug ("ACTIVITY") io.error.put_string ("Types:%N") if old_type /= Void then io.error.put_string ("old type:%N") io.error.put_string (old_type.dump) io.error.put_new_line end if new_type /= Void then io.error.put_string ("new type:%N") io.error.put_string (new_type.dump) io.error.put_new_line end io.error.put_new_line end if not new_type.good_generics then l_vtug := new_type.error_generics l_vtug.set_class (current_class) l_vtug.set_feature (Current) error_handler.insert_error (l_vtug) elseif not new_type.conform_to (current_class, old_type) then create vdrd53 vdrd53.init (old_feature, Current) Error_handler.insert_error (vdrd53) elseif False and then not ( -- new SCOOP redeclaration rules page 187 new_type.conform_to (current_class, old_type) and then -- ((not old_type.conform_to (new_type) or not old_type.is_attached) implies not new_type.is_attached) and then -- (not new_type.is_attached implies True) and then -- True here should be no calls occur on new_type in the post condition -- (new_type.processor_tag.is_equal (old_type.processor_tag) or else new_type.processor_tag.top) True ) then create vdrd53 vdrd53.init (old_feature, Current) Error_handler.insert_error (vdrd53) end i := i + 1 end end -- Check aliases if not is_same_alias (old_feature) then -- Report that aliases are not the same Error_handler.insert_error (create {VDRD7_NEW}.make (system.current_class, Current, old_feature)) end -- Check assigner procedure if not is_same_assigner (old_feature, tbl) then -- Report that assigner commands are not the same Error_handler.insert_error (create {VDRD8_NEW}.make (system.current_class, Current, old_feature)) end end check_same_signature (old_feature: FEATURE_I) -- Check signature equality beetween Current -- and inherited feature in `inherit_info' from which Current -- is a join. require good_argument: old_feature /= Void is_deferred old_feature.is_deferred old_feature_is_solved: old_feature.type.is_solved local old_type, new_type: TYPE_A i, arg_count: INTEGER old_arguments: like arguments vdjr: VDJR vdjr1: VDJR1 vdjr2: VDJR2 do -- Check the result type conformance -- `old_type' is the instantiated inherited type in the -- context of the class where the join takes place: -- i.e the class relative to `access_in'. old_type ?= old_feature.type -- `new_type' is the actual type of the join already -- instantiated new_type ?= type if not new_type.is_safe_equivalent (old_type) then create vdjr1 vdjr1.init (old_feature, Current) vdjr1.set_type (new_type) vdjr1.set_old_type (old_type) Error_handler.insert_error (vdjr1) end -- Check the argument count if argument_count /= old_feature.argument_count then create vdjr vdjr.init (old_feature, Current) Error_handler.insert_error (vdjr) else -- Check the argument equality from i := 1 arg_count := argument_count old_arguments := old_feature.arguments until i > arg_count loop old_type ?= old_arguments.i_th (i) new_type ?= arguments.i_th (i) if not new_type.is_safe_equivalent (old_type) then create vdjr2 vdjr2.init (old_feature, Current) vdjr2.set_type (new_type) vdjr2.set_old_type (old_type) vdjr2.set_argument_number (i) Error_handler.insert_error (vdjr2) end i := i + 1 end end -- Check aliases if not is_same_alias (old_feature) then -- Report that aliases are not the same Error_handler.insert_error (create {VDJR2_NEW}.make (system.current_class, Current, old_feature)) end end special_arguments: ARRAY [TYPE_A] local i, nb: INTEGER do from fixme ("we should resolve argument types early on in `init_arg' from PROCEDURE_I") nb := argument_count create Result.make (1, nb) i := 1 nb := nb + 1 until i = nb loop Result.put (arguments.i_th (i).actual_type, i) i := i + 1 end end has_same_il_signature (a_parent_type, a_written_type: CL_TYPE_A; old_feature: FEATURE_I): BOOLEAN -- Is current feature defined in `a_written_type' same as `old_feature' -- defined in `a_parent_type'? require a_parent_type_not_void: a_parent_type /= Void a_written_type_not_void: a_written_type /= Void old_feature_not_void: old_feature /= Void il_generation: System.il_generation local old_type, new_type: TYPE_A i, arg_count: INTEGER old_arguments: like arguments do old_type ?= old_feature.type old_type := old_type.actual_argument_type (special_arguments). instantiation_in (a_written_type, a_written_type.class_id).actual_type new_type := type.actual_type -- Check exact match of signature for IL generation. Result := old_type.same_as (new_type) -- Check the argument conformance from i := 1 arg_count := argument_count old_arguments := old_feature.arguments until i > arg_count loop old_type ?= old_arguments.i_th (i) old_type := old_type.actual_argument_type (special_arguments). instantiation_in (a_written_type, a_written_type.class_id).actual_type new_type := arguments.i_th (i).actual_type -- Check exact match of signature for IL generation. Result := Result and then old_type.same_as (new_type) i := i + 1 end end solve_types (feat_tbl: FEATURE_TABLE) -- Evaluates signature types in context of `feat_tbl'. -- | Take care of possible anchored types local l_solved_type: TYPE_A do l_solved_type := Result_evaluator.evaluated_type (type, feat_tbl, Current) check l_solved_type_not_void: l_solved_type /= Void end set_type (l_solved_type, assigner_name_id) if arguments /= Void then arguments.solve_types (feat_tbl, Current) end end same_signature (other: FEATURE_I): BOOLEAN -- Has `other' same signature than Current ? require good_argument: other /= Void same_feature_names: feature_name_id = other.feature_name_id local i, nb: INTEGER do Result := type.is_safe_equivalent (other.type) from nb := argument_count Result := Result and then nb = other.argument_count nb := argument_count i := 1 until i > nb or else not Result loop Result := arguments.i_th (i).is_safe_equivalent (other.arguments.i_th (i)) i := i + 1 end end argument_position (arg_id: INTEGER): INTEGER -- Position of argument `arg_id' in list of arguments -- of current feature. 0 if none or not found. require arg_id_not_void: arg_id >= 0 do if arguments /= Void then Result := arguments.argument_position_id (arg_id, 1) end end has_argument_name (arg_id: INTEGER): BOOLEAN -- Has current feature an argument named `arg_id" ? require arg_id_positive: arg_id > 0 do if arguments /= Void then Result := arguments.argument_position_id (arg_id, 1) /= 0 end end property_setter_in (class_type: CLASS_TYPE): FEATURE_I -- Find an associated property setter in `class_type'. require class_type_attached: class_type /= Void local f: FEATURE_I do if type.is_void then f := Current elseif assigner_name_id /= 0 then f := written_class.feature_table.item_id (assigner_name_id) else f := ancestor_property_setter_in (class_type.associated_class) end if f /= Void then Result := class_type.associated_class.feature_of_rout_id (f.rout_id_set.first) end ensure result_attached: (type.is_void or else assigner_name_id /= 0) implies Result /= Void end ancestor_property_setter_in (c: CLASS_C): FEATURE_I -- Find an property setter routine in some ancestor class of the class `c'. require c_not_void: c /= Void local parent_classes: FIXED_LIST [CLASS_C] parent_class: CLASS_C routine_id: INTEGER c_id: like origin_class_id f_id: like origin_feature_id do if type.is_void then Result := c.feature_of_rout_id (rout_id_set.first) elseif assigner_name_id /= 0 then Result := written_class.feature_table.item_id (assigner_name_id) else c_id := origin_class_id if c_id = 0 then c_id := written_in f_id := feature_id else f_id := origin_feature_id end routine_id := system.class_of_id (c_id).feature_of_feature_id (f_id).rout_id_set.first parent_classes := c.parents_classes if parent_classes /= Void then from parent_classes.start until parent_classes.after or else Result /= Void loop parent_class := parent_classes.item Result := parent_class.feature_of_rout_id (routine_id) if Result /= Void then Result := Result.ancestor_property_setter_in (parent_class) end parent_classes.forth end end end ensure result_attached: (type.is_void or else assigner_name_id /= 0) implies Result /= Void end check_assigner (feature_table: FEATURE_TABLE) -- Check if associated assigner is valid. require feature_table_not_void: feature_table /= Void has_assigner: assigner_name_id /= 0 local assigner: FEATURE_I assigner_arguments: like arguments query_arguments: like arguments vfac: VFAC do if feature_table.feat_tbl_id = written_in then -- Lookup feature in `feature_table' as feature table in the current class is not set yet. assigner := feature_table.item_id (assigner_name_id) else assigner := feature_table.feature_of_rout_id (written_class.feature_named (assigner_name).rout_id_set.first) end if assigner = Void or else assigner.has_return_value then create {VFAC1} vfac.make (system.current_class, Current) elseif assigner.argument_count /= argument_count + 1 then create {VFAC2} vfac.make (system.current_class, Current) elseif not assigner.arguments.first.actual_type.conform_to (system.current_class, type.actual_type) then create {VFAC3} vfac.make (system.current_class, Current) elseif argument_count > 0 then assigner_arguments := assigner.arguments query_arguments := arguments from assigner_arguments.start -- Skip first argument assigner_arguments.forth query_arguments.start until assigner_arguments.after loop if not assigner_arguments.item.actual_type.same_as (query_arguments.item.actual_type) then create {VFAC4} vfac.make (system.current_class, Current) assigner_arguments.finish query_arguments.finish end assigner_arguments.forth query_arguments.forth end end if vfac /= Void then if assigner /= Void then vfac.set_assigner (assigner.api_feature (system.current_class.class_id)) end error_handler.insert_error (vfac) end end feature -- Undefinition new_deferred: DEF_PROC_I -- New deferred feature for undefinition require not is_deferred redefinable local ext: EXTERNAL_I do if is_function then create {DEF_FUNC_I} Result else create Result end Result.set_type (type, assigner_name_id) Result.set_arguments (arguments) Result.set_written_in (written_in) Result.set_origin_feature_id (origin_feature_id) Result.set_origin_class_id (origin_class_id) Result.set_rout_id_set (rout_id_set) Result.set_assert_id_set (assert_id_set) Result.set_is_infix (is_infix) Result.set_is_prefix (is_prefix) Result.set_is_frozen (is_frozen) Result.set_feature_name_id (feature_name_id, alias_name_id) Result.set_feature_id (feature_id) Result.set_pattern_id (pattern_id) Result.set_is_require_else (is_require_else) Result.set_is_ensure_then (is_ensure_then) Result.set_export_status (export_status) Result.set_body_index (body_index) Result.set_has_postcondition (has_postcondition) Result.set_has_precondition (has_precondition) Result.set_is_bracket (is_bracket) Result.set_is_binary (is_binary) Result.set_is_unary (is_unary) Result.set_has_convert_mark (has_convert_mark) Result.set_has_rescue_clause (has_rescue_clause) if is_external then ext ?= Current if ext.extension.is_il then Result.set_extension (ext.extension) end end ensure Result_exists: Result /= Void Result_is_deferred: Result.is_deferred end new_rout_id: INTEGER -- New routine id do Result := Routine_id_counter.next_rout_id end Routine_id_counter: ROUTINE_COUNTER -- Routine id counter once Result := System.routine_id_counter end feature -- Replication code_id: INTEGER -- Code id for inheritance analysis do Result := body_index end set_code_id (i: INTEGER) -- Assign `i' to code_id. do -- Do nothing end set_access_in (i: INTEGER_32) -- Assign `i' to access_in do -- Do nothing end access_in: INTEGER -- Id of class where current feature can be accessed -- through its routine id -- Useful for replication do Result := written_in end replicated (in: INTEGER): FEATURE_I -- Replicated feature require in_not_void: in /= 0 deferred ensure Result_exists: Result /= Void access_in_set: Result.access_in = in end new_code_id: INTEGER -- New code id do Result := System.body_index_counter.next_id end selected: FEATURE_I -- Selected feature (used for duplicating inherited features by resetting replication and selection status require do_not_use_yet: False deferred ensure Result_exists: Result /= Void equivalent: Result.equiv (Current) end unselected (in: INTEGER): FEATURE_I -- Unselected feature require in_not_void: in /= 0 deferred ensure Result_exists: Result /= Void end is_unselected: BOOLEAN -- Is current feature an unselected one ? do -- Do nothing end transfer_to (other: FEATURE_I) -- Transfer of datas from Current into `other'. require other_exists: other /= Void do other.set_export_status (export_status) other.set_feature_id (feature_id) other.set_feature_name_id (feature_name_id, alias_name_id) other.set_written_feature_id (written_feature_id) other.set_origin_feature_id (origin_feature_id) other.set_origin_class_id (origin_class_id) other.set_pattern_id (pattern_id) other.set_rout_id_set (rout_id_set) other.set_written_in (written_in) --| IEK: As an minor optimization the flags below internally --| could be set simply with 'other.set_feature_flags (feature_flags)' --| It would also prevents bugs when adding another flag and it doesn't --| get accounted for in this routine. other.set_is_frozen (is_frozen) other.set_is_infix (is_infix) other.set_is_prefix (is_prefix) other.set_is_origin (is_origin) other.set_is_bracket (is_bracket) other.set_is_binary (is_binary) other.set_is_unary (is_unary) other.set_has_convert_mark (has_convert_mark) other.set_body_index (body_index) end transfer_from (other: FEATURE_I) -- Transfer of datas from `other' into `Current'. require do_not_call: False -- Feature not ready yet. other_exists: other /= Void do -- `export_status' needs to be set via `set_export_status' set_export_status (other.export_status) --feature_id := other.feature_id feature_name_id := other.feature_name_id alias_name_id := other.alias_name_id written_feature_id := other.written_feature_id origin_feature_id := other.origin_feature_id origin_class_id := other.origin_class_id pattern_id := other.pattern_id rout_id_set := other.rout_id_set written_in := other.written_in body_index := other.body_index -- Set `feature_flags' directly from `other'. feature_flags := other.feature_flags end feature -- Genericity update_instantiator2 (a_class: CLASS_C) -- Look for generic/expanded types in result and arguments in order -- to update instantiator. require good_argument: a_class /= Void good_context: a_class.changed local i, arg_count: INTEGER do Instantiator.dispatch (type.actual_type, a_class) from i := 1 arg_count := argument_count until i > arg_count loop Instantiator.dispatch (arguments.i_th (i).actual_type, a_class) i := i + 1 end end feature -- Pattern pattern: PATTERN -- Feature pattern do create Result.make (type.meta_type) if argument_count > 0 then Result.set_argument_types (arguments.pattern_types) end end process_pattern -- Process pattern of Current feature local p: PATTERN_TABLE do p := Pattern_table p.insert (generation_class_id, pattern) pattern_id := p.last_pattern_id end feature -- Dead code removal used: BOOLEAN -- Is feature used ? do -- In final mode dead code removal process is on. -- In workbench mode all features are considered used. Result := byte_context.workbench_mode or else System.is_used (Current) end feature -- Byte code access frozen access (access_type: TYPE_A; is_qualified: BOOLEAN): ACCESS_B -- Byte code access for current feature require access_type_not_void: access_type /= Void do Result := access_for_feature (access_type, Void, is_qualified) ensure Result_exists: Result /= Void end frozen access_for_multi_constraint (access_type: TYPE_A; a_static_type: TYPE_A; is_qualified: BOOLEAN): ACCESS_B -- Creates a byte code access for a multi constraint target. -- `a_static_type' is the type where the feature is from. -- It is NOT a static call that will be generated, but a dynamic one. It is only needed for W_bench. require access_type_not_void: access_type /= Void do Result := access (access_type, is_qualified) check Result /= Void end Result.set_multi_constraint_static (a_static_type) ensure Result_exists: Result /= Void end access_for_feature (access_type: TYPE_A; static_type: TYPE_A; is_qualified: BOOLEAN): ACCESS_B -- Byte code access for current feature. Dynamic binding if -- `static_type' is Void, otherwise static binding on `static_type'. require access_type_not_void: access_type /= Void local is_in_op: BOOLEAN l_type: TYPE_A do if is_qualified then -- To fix eweasel test#term155 we remove all anchors from -- calls after the first dot in a call chain. l_type := access_type.context_free_type else l_type := access_type end is_in_op := written_in = System.function_class_id or else written_in = System.predicate_class_id or else written_in = System.procedure_class_id if is_in_op then if feature_name_id = {PREDEFINED_NAMES}.call_name_id then create {AGENT_CALL_B} Result.make (Current, l_type, static_type, False) elseif feature_name_id = {PREDEFINED_NAMES}.item_name_id then create {AGENT_CALL_B} Result.make (Current, l_type, static_type, True) end end if Result = Void then if written_in = System.any_id then -- Feature written in ANY. create {ANY_FEATURE_B} Result.make (Current, l_type, static_type) else create {FEATURE_B} Result.make (Current, l_type, static_type) end end ensure Result_exists: Result /= Void end feature {NONE} -- log file add_in_log (class_type: CLASS_TYPE; encoded_name: STRING) do System.used_features_log_file.add (class_type, feature_name, encoded_name) end feature -- C code generation generate (class_type: CLASS_TYPE; buffer: GENERATION_BUFFER) -- Generate feature written in `class_type' in `buffer'. require valid_buffer: buffer /= Void written_in_type: class_type.associated_class.class_id = generation_class_id or is_replicated not_deferred: not is_deferred local l_byte_code: BYTE_CODE tmp_body_index: INTEGER l_byte_context: like byte_context do if used then -- `generate' from BYTE_CODE will log the feature name -- and encoded name in `used_features_log_file' from SYSTEM_I generate_header (class_type, buffer) tmp_body_index := body_index l_byte_code := tmp_opt_byte_server.disk_item (tmp_body_index) if l_byte_code = Void then l_byte_code := byte_server.disk_item (tmp_body_index) end -- Generation of C code for an Eiffel feature written in -- the associated class of the current type. l_byte_context := byte_context if System.in_final_mode and then System.inlining_on then -- We need to set `{BYTE_CONTEXT}.byte_code', since it is used -- in `inlined_byte_code'. l_byte_context.set_byte_code (l_byte_code) l_byte_code := l_byte_code.inlined_byte_code end -- Generation of the C routine l_byte_context.set_byte_code (l_byte_code) l_byte_context.set_current_feature (Current) l_byte_code.analyze l_byte_code.set_real_body_id (real_body_id (class_type)) l_byte_code.generate l_byte_context.clear_feature_data else System.removed_log_file.add (class_type, feature_name) end end generate_header (a_type: CLASS_TYPE; buffer: GENERATION_BUFFER) -- Generate a header before body of feature require a_type_not_void: a_type /= Void valid_buffer: buffer /= Void do buffer.put_string ("%N/* {") buffer.put_string (a_type.associated_class.name) buffer.put_two_character ('}', '.') buffer.put_string (feature_name) buffer.put_string (" */") end feature -- Debug purpose trace -- Debug purpose do io.error.put_string ("feature name: ") io.error.put_string (feature_name) io.error.put_character (' ') rout_id_set.trace io.error.put_string (" {") io.error.put_string ("fid = ") io.error.put_integer (feature_id) io.error.put_string ("}"); io.error.put_string (" {") io.error.put_string ("body_index = ") io.error.put_integer (body_index) io.error.put_string ("}"); io.error.put_string (" {") io.error.put_string ("written in = ") io.error.put_string (written_class.name) io.error.put_string ("}"); io.error.put_string (" {") io.error.put_string ("body_index = ") if body_index > 0 then io.error.put_integer (body_index) else io.error.put_integer (0) end io.error.put_new_line end feature -- Debugging is_debuggable: BOOLEAN local wc: CLASS_C do if (not is_external) and then (not is_attribute) and then (not is_constant) and then (not is_deferred) and then (not is_unique) then wc := written_class Result := (not wc.is_basic) and then (wc.has_types) end end real_body_id (class_type: CLASS_TYPE): INTEGER -- Real body id at compilation time for `class_type'. -- This id might be obsolete after supermelting this feature. --| In latter case, new real body id is kept --| in DEBUGGABLE objects. require valid_body_id: valid_body_id do Result := execution_table.real_body_id (body_index, class_type) end real_pattern_id (class_type: CLASS_TYPE): INTEGER -- Real pattern id at compilation time for `class_type'. -- This id might be obsolete after supermelting this feature. --| In latter case, new real body id is kept --| in DEBUGGABLE objects. require valid_body_id: valid_body_id do Result := execution_table.real_pattern_id (body_index, class_type) end valid_body_id: BOOLEAN -- Use of this routine as precondition for real_body_id. do Result := ((not is_attribute or else attached {ATTRIBUTE_I} Current as a and then a.has_body) and then (not is_constant) and then (not is_deferred) and then (not is_unique) and then written_class.has_types) or else (is_constant and is_once) end feature -- Api creation e_feature: E_FEATURE do Result := api_feature (written_in) end api_feature (a_class_id: INTEGER): E_FEATURE -- API representation of Current require a_class_id_positive: a_class_id > 0 local e_routine: E_ROUTINE do Result := new_api_feature Result.set_written_feature_id (written_feature_id) Result.set_written_in (written_in) Result.set_associated_class_id (a_class_id) Result.set_body_index (body_index) Result.set_is_origin (is_origin) Result.set_export_status (export_status) Result.set_is_frozen (is_frozen) Result.set_is_infix (is_infix) Result.set_is_prefix (is_prefix) Result.set_rout_id_set (rout_id_set) Result.set_is_il_external (is_il_external) if is_inline_agent then e_routine ?= Result e_routine.set_enclosing_body_id (enclosing_body_id) e_routine.set_inline_agent_nr (inline_agent_nr) end end feature {FEATURE_I} -- Implementation feature_flags: NATURAL_32 -- Property of Current feature, i.e. frozen, -- infix, origin, prefix, selected... new_api_feature: E_FEATURE -- API feature creation deferred ensure non_void_result: Result /= Void end is_frozen_mask: NATURAL_32 = 0x0001 is_origin_mask: NATURAL_32 = 0x0002 is_empty_mask: NATURAL_32 = 0x0004 is_infix_mask: NATURAL_32 = 0x0008 is_prefix_mask: NATURAL_32 = 0x0010 is_require_else_mask: NATURAL_32 = 0x0020 is_ensure_then_mask: NATURAL_32 = 0x0040 has_precondition_mask: NATURAL_32 = 0x0080 has_postcondition_mask: NATURAL_32 = 0x0100 is_bracket_mask: NATURAL_32 = 0x0200 is_binary_mask: NATURAL_32 = 0x0400 is_unary_mask: NATURAL_32 = 0x0800 has_convert_mark_mask: NATURAL_32 = 0x1000 has_property_mask: NATURAL_32 = 0x2000 has_property_getter_mask: NATURAL_32 = 0x4000 has_property_setter_mask: NATURAL_32 = 0x8000 is_fake_inline_agent_mask: NATURAL_32 = 0x10000 has_rescue_clause_mask: NATURAL_32 = 0x20000 is_export_status_none_mask: NATURAL_32 = 0x40000 has_function_origin_mask: NATURAL_32 = 0x80000 -- Used in ATTRIBUTE_I has_replicated_ast_mask: NATURAL_32 = 0x100000 has_body_mask: NATURAL_32 = 0x200000 -- Used in ATTRIBUTE_I is_replicated_directly_mask: NATURAL_32 = 0x400000 from_non_conforming_parent_mask: NATURAL_32 = 0x800000 is_selected_mask: NATURAL_32 = 0x1000000 is_stable_mask: NATURAL_32 = 0x2000000 -- Used in ATTRIBUTE_I -- Mask used for each feature property. internal_export_status: like export_status -- Internal export status object. When it is ANY or NONE -- it is Void to save some space, what help us distinguish -- is the `is_export_status_none_mask'. export_all_status: EXPORT_ALL_I once create Result ensure export_all_status_not_void: Result /= Void end export_none_status: EXPORT_NONE_I once create Result ensure export_none_status_not_void: Result /= Void end feature {INHERIT_TABLE, FEATURE_I} -- Access private_external_name_id: INTEGER -- External name id of feature if any in IL generation. private_external_name: STRING -- External name of feature if any in IL generation. require valid_private_external_name_id: private_external_name_id > 0 do Result := Names_heap.item (private_external_name_id) ensure Result_not_void: Result /= Void Result_not_empty: not Result.is_empty end feature {NONE} -- Debug output debug_output: STRING -- Textual representation of current feature for debugging. do Result := feature_name if Result = Void then Result := "Name not yet assigned" end end invariant valid_enclosing_feature: is_inline_agent implies enclosing_body_id > 0 valid_inline_agent_nr: is_inline_agent implies inline_agent_nr > 0 or is_fake_inline_agent note copyright: "Copyright (c) 1984-2010, Eiffel Software" license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)" licensing_options: "http://www.eiffel.com/licensing" copying: "[ This file is part of Eiffel Software's Eiffel Development Environment. Eiffel Software's Eiffel Development Environment 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, version 2 of the License (available at the URL listed under "license" above). Eiffel Software's Eiffel Development Environment 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 Eiffel Software's Eiffel Development Environment; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ]" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end