indexing description: "Generate Eiffel class from emitter information" external_name: "ISE.Reflection.EiffelCodeGenerator" attribute: create {SYSTEM_RUNTIME_INTEROPSERVICES_CLASSINTERFACEATTRIBUTE}.make_classinterfaceattribute ((create {SYSTEM_RUNTIME_INTEROPSERVICES_CLASSINTERFACETYPE}).auto_dual) end class EIFFEL_CODE_GENERATOR inherit EIFFEL_CODE_GENERATOR_DICTIONARY export {NONE} all end create make_eiffel_code_generator, make_from_info feature {NONE} -- Initialization make_eiffel_code_generator is indexing description: "Creation routine" external_name: "MakeEiffelCodeGenerator" do end make_from_info (an_eiffel_assembly: like eiffel_assembly) is indexing description: "Set `eiffel_assembly' with `an_eiffel_assembly'." external_name: "MakeFromInfo" require non_void_eiffel_assembly: an_eiffel_assembly /= Void non_void_eiffel_assembly_descriptor: an_eiffel_assembly.get_assembly_descriptor /= Void non_void_eiffel_cluster_path: an_eiffel_assembly.get_Eiffel_Cluster_Path /= Void non_void_emitter_version_number: an_eiffel_assembly.get_Emitter_Version_Number /= Void not_empty_emitter_version_number: an_eiffel_assembly.get_Emitter_Version_Number.get_length > 0 local code_generation_support: ISE_REFLECTION_CODEGENERATIONSUPPORT reflection_support: ISE_REFLECTION_REFLECTIONSUPPORT cluster_path: STRING do eiffel_assembly := an_eiffel_assembly create code_generation_support.make_codegenerationsupport code_generation_support.make create reflection_support.make_reflectionsupport reflection_support.make cluster_path := eiffel_assembly.get_eiffel_cluster_path if cluster_path.index_of (reflection_support.eiffel_key) > -1 then cluster_path := cluster_path.replace (reflection_support.eiffel_key, reflection_support.eiffel_delivery_path) end if not code_generation_support.is_valid_directory_path (cluster_path) then code_generation_support.create_folder (cluster_path) end ensure eiffel_assembly_set: eiffel_assembly = an_eiffel_assembly end feature -- Access eiffel_assembly: ISE_REFLECTION_EIFFELASSEMBLY indexing description: "Eiffel assembly generated by the emitter" external_name: "EiffelAssembly" end eiffel_class: ISE_REFLECTION_EIFFELCLASS indexing description: "Eiffel class generated by the emitter" external_name: "EiffelClass" end generated_code: STRING indexing description: "Generated code" external_name: "GeneratedCode" end feature -- Basic Operations generate_eiffel_class (an_eiffel_class: like eiffel_class) is indexing description: "Generate Eiffel class from `eiffel_class'." external_name: "GenerateEiffelClass" require non_void_eiffel_class: an_eiffel_class /= Void non_void_eiffel_class_name: an_eiffel_class.get_eiffel_name /= Void not_empty_eiffel_class_name: an_eiffel_class.get_eiffel_name.get_length > 0 non_void_eiffel_class_full_external_name: an_eiffel_class.get_Full_External_Name /= Void not_empty_eiffel_class_full_external_name: an_eiffel_class.get_Full_External_Name.get_length > 0 non_void_eiffel_assembly: eiffel_assembly /= Void non_void_eiffel_assembly_descriptor: eiffel_assembly.get_assembly_descriptor /= Void non_void_eiffel_cluster_path: eiffel_assembly.get_Eiffel_Cluster_Path /= Void non_void_emitter_version_number: eiffel_assembly.get_Emitter_Version_Number /= Void not_empty_emitter_version_number: eiffel_assembly.get_Emitter_Version_Number.get_length > 0 local eiffel_cluster_path: STRING full_external_name: STRING filename: STRING formatter: FORMATTER reflection_support: ISE_REFLECTION_REFLECTIONSUPPORT do eiffel_class := an_eiffel_class create formatter.make eiffel_cluster_path := eiffel_assembly.get_Eiffel_Cluster_Path if eiffel_cluster_path.get_length > 0 and then not eiffel_cluster_path.Ends_With ("\") then eiffel_cluster_path := eiffel_cluster_path.Concat_String_String (eiffel_cluster_path, "\") end create reflection_support.make_reflectionsupport reflection_support.make if eiffel_cluster_path.index_of (reflection_support.eiffel_key) > -1 then eiffel_cluster_path := eiffel_cluster_path.replace (reflection_support.eiffel_key, reflection_support.eiffel_delivery_path) end intern_generate_eiffel_class (eiffel_cluster_path) end generate_eiffel_class_from_path (an_eiffel_class: like eiffel_class; a_path: STRING) is indexing description: "Generate Eiffel class from `eiffel_class' in folder corresponding to `a_path'." external_name: "GenerateEiffelClassFromPath" require non_void_eiffel_class: an_eiffel_class /= Void non_void_eiffel_class_name: an_eiffel_class.get_eiffel_name /= Void not_empty_eiffel_class_name: an_eiffel_class.get_eiffel_name.get_length > 0 non_void_eiffel_class_full_external_name: an_eiffel_class.get_Full_External_Name /= Void not_empty_eiffel_class_full_external_name: an_eiffel_class.get_Full_External_Name.get_length > 0 non_void_eiffel_assembly: eiffel_assembly /= Void non_void_eiffel_assembly_descriptor: eiffel_assembly.get_assembly_descriptor /= Void non_void_emitter_version_number: eiffel_assembly.get_Emitter_Version_Number /= Void not_empty_emitter_version_number: eiffel_assembly.get_Emitter_Version_Number.get_length > 0 non_void_path: a_path /= Void not_empty_path: a_path.get_length > 0 local code_generation_support: ISE_REFLECTION_CODEGENERATIONSUPPORT reflection_support: ISE_REFLECTION_REFLECTIONSUPPORT path: STRING do eiffel_class := an_eiffel_class create code_generation_support.make_codegenerationsupport code_generation_support.make create reflection_support.make_reflectionsupport reflection_support.make path := a_path if path.index_of (reflection_support.eiffel_key) > -1 then path := path.replace (reflection_support.eiffel_key, reflection_support.eiffel_delivery_path) end if not code_generation_support.is_valid_directory_path (path) then code_generation_support.create_folder (path) end intern_generate_eiffel_class (path) end feature {NONE} -- Implementation intern_generate_eiffel_class (a_filename: STRING) is indexing description: "Generate Eiffel class from `eiffel_class'." external_name: "InternGenerateEiffelClass" require non_void_eiffel_class: eiffel_class /= Void non_void_eiffel_class_name: eiffel_class.get_eiffel_name /= Void not_empty_eiffel_class_name: eiffel_class.get_eiffel_name.get_length > 0 non_void_eiffel_class_full_external_name: eiffel_class.get_Full_External_Name /= Void not_empty_eiffel_class_full_external_name: eiffel_class.get_Full_External_Name.get_length > 0 non_void_filename: a_filename /= Void not_empty_filename: a_filename.get_length > 0 local file_stream: SYSTEM_IO_STREAMWRITER filename: STRING full_external_name: STRING formatter: FORMATTER dir: SYSTEM_IO_DIRECTORY env: SYSTEM_ENVIRONMENT cluster_path: STRING constraints: ARRAY [ANY] a_constraint: STRING class_name: STRING a_generic_type_name: STRING i: INTEGER support: ISE_REFLECTION_CODEGENERATIONSUPPORT generic_type_names: ARRAY [ANY] do create formatter.make full_external_name := eiffel_class.get_Full_External_Name filename := a_filename.Concat_String_String_String (a_filename, formatter.Format_Type_Name (full_external_name).To_Lower, Eiffel_class_extension) create file_stream.make_streamwriter_5 (filename, False, create {SYSTEM_TEXT_ASCIIENCODING}.make_asciiencoding) create generated_code.make_2 ('%U', 0) -- indexing -- Generator: "Eiffel Emitter Version number" -- external_name: "ClassName" generated_code := generated_code.Concat_String_String_String_String (generated_code, Indexing_keyword, Windows_new_line, Tab) generated_code := generated_code.Concat_String_String_String_String (generated_code, Generator_indexing_clause, Colon, Space) generated_code := generated_code.Concat_String_String_String_String (generated_code, Inverted_comma, Generator_name, Space) generated_code := generated_code.Concat_String_String_String_String (generated_code, eiffel_assembly.get_Emitter_Version_Number, Inverted_comma, Windows_new_line) generated_code := generated_code.Concat_String_String_String_String (generated_code, Tab, external_name_keyword, Colon) generated_code := generated_code.Concat_String_String_String_String (generated_code, Space, Inverted_comma, formatter.Format_Strong_Name (eiffel_class.get_Full_External_Name)) generated_code := generated_code.Concat_String_String_String (generated_code, Inverted_comma, Windows_new_line) -- enum_type if eiffel_class.get_Enum_Type /= Void and then eiffel_class.get_Enum_Type.get_length > 0 then generated_code := generated_code.concat_string_string_string_string (generated_code, Tab, Enum_type_keyword, Colon) generated_code := generated_code.concat_string_string_string_string (generated_code, Space, Inverted_comma, eiffel_class.get_Enum_Type) generated_code := generated_code.concat_string_string_string (generated_code, Inverted_comma, Windows_new_line) end -- generic_types and constraints if eiffel_class.get_is_generic then generate_generic_clauses end generated_code := generated_code.concat_string_string (generated_code, Windows_new_line) -- frozen if eiffel_class.get_Is_Frozen then generated_code := generated_code.Concat_String_String_String (generated_code, Frozen_keyword, Space) end -- expanded if eiffel_class.get_Is_Expanded then generated_code := generated_code.Concat_String_String_String (generated_code, Expanded_keyword, Space) end -- deferred if eiffel_class.get_Is_Deferred then generated_code := generated_code.Concat_String_String_String (generated_code, Deferred_keyword, Space) end -- external class -- CLASS_NAME generated_code := generated_code.Concat_String_String_String_String (generated_code, External_keyword, Space, Class_keyword) generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, eiffel_class.get_eiffel_name.To_Upper) if eiffel_class.get_is_generic then class_name := Space class_name := class_name.concat_string_string (class_name, Opening_square_bracket) constraints := eiffel_class.get_constraints create support.make_codegenerationsupport support.make support.compute_generic_names (constraints.count) check non_void_generic_type_names: support.get_generic_type_names /= Void end generic_type_names := support.get_generic_type_names from until i = generic_type_names.count loop a_constraint ?= constraints.item (i) if a_constraint /= Void then a_generic_type_name ?= generic_type_names.item (i) if a_generic_type_name /= Void and then a_generic_type_name.get_length > 0 then class_name := class_name.concat_string_string_string_string (class_name, a_generic_type_name, Space, "->") class_name := class_name.concat_string_string_string (class_name, Space, a_constraint) if i < generic_type_names.count - 1 then class_name := class_name.concat_string_string_string (class_name, Comma, Space) end end end i := i + 1 end class_name := class_name.concat_string_string_string (class_name, Space, Closing_square_bracket) generated_code := generated_code.concat_string_string (generated_code, class_name) end generated_code := generated_code.Concat_String_String_String (generated_code, Windows_new_line, Windows_new_line) -- inherit -- PARENT_NAME -- rename ... -- undefine ... -- redefine ... -- end generate_inherit_clause -- `create {NONE}' or `create make ...' generate_create_clause -- Generate class features (except initialization ones). generate_class_features -- `end -- class CLASS_NAME' generated_code := generated_code.Concat_String_String_String_String (generated_code, End_keyword, Space, Dashes) generated_code := generated_code.Concat_String_String_String_String (generated_code, Space, Class_keyword, Space) generated_code := generated_code.Concat_String_String (generated_code, eiffel_class.get_eiffel_name.To_Upper) if eiffel_class.get_is_generic and then class_name /= Void and then class_name.get_length > 0 then generated_code := generated_code.concat_string_string (generated_code, class_name) end generated_code := generated_code.concat_string_string (generated_code, Windows_new_line) file_stream.Write_String (generated_code) file_stream.Close eiffel_class := Void ensure void_eiffel_class: eiffel_class = Void end parents: SYSTEM_COLLECTIONS_HASHTABLE -- | Key: parent name -- | Value: inheritance clauses (ARRAY [SYSTEM_COLLECTIONS_ARRAYLIST [STRING]]) indexing description: "Class parents" external_name: "Parents" end special_classes: SYSTEM_COLLECTIONS_HASHTABLE is indexing description: "Special classes for which no creation routine should be generated" external_name: "SpecialClasses" once create Result.make Result.extend (Integer_class, Integer_class) Result.extend (Integer_16_class, Integer_16_class) Result.extend (Integer_64_class, Integer_64_class) Result.extend (Integer_8_class, Integer_8_class) Result.extend (Double_class, Double_class) Result.extend (Real_class, Real_class) Result.extend (Boolean_class, Boolean_class) Result.extend (Character_class, Character_class) ensure special_classes_created: Result /= Void valid_special_classes: Result.get_count = 8 end generate_generic_clauses is indexing description: "Generate `generic_types' and `constraints' clauses." external_name: "GenerateGenericClauses" require non_void_eiffel_class: eiffel_class /= Void is_generic: eiffel_class.get_is_generic non_void_generic_derivations: eiffel_class.get_generic_derivations /= Void non_void_constraints: eiffel_class.get_constraints /= Void do generate_generic_types generate_constraints end generate_generic_types is indexing description: "Generate `generic_types' clause." external_name: "GenerateGenericTypes" require non_void_eiffel_class: eiffel_class /= Void is_generic: eiffel_class.get_is_generic non_void_generic_derivations: eiffel_class.get_generic_derivations /= Void not_empty_generic_derivations: eiffel_class.get_generic_derivations.count > 0 local generic_derivations: ARRAY [ANY] a_generic_derivation: ISE_REFLECTION_GENERICDERIVATION generic_types_count: INTEGER i, j: INTEGER generic_types: ARRAY [ANY] a_generic_type: ISE_REFLECTION_SIGNATURETYPE do generated_code := generated_code.concat_string_string_string_string (generated_code, Tab, Generic_types_keyword, Colon) generated_code := generated_code.concat_string_string_string (generated_code, Space, Inverted_comma) generic_derivations := eiffel_class.get_generic_derivations a_generic_derivation ?= generic_derivations.item (0) if a_generic_derivation /= Void then generic_types_count := a_generic_derivation.get_generic_types.count from until i = generic_types_count loop from j := 0 until j = generic_derivations.count loop a_generic_derivation ?= generic_derivations.item (j) if a_generic_derivation /= Void then generic_types := a_generic_derivation.get_generic_types a_generic_type ?= generic_types.item (i) if a_generic_type /= Void then generated_code := generated_code.concat_string_string (generated_code, a_generic_type.type_eiffel_name) if j < generic_derivations.count - 1 then generated_code := generated_code.concat_string_string_string (generated_code, Comma, Space) end end end j := j + 1 end if i < generic_types_count - 1 then generated_code := generated_code.concat_string_string_string (generated_code, Semi_colon, Space) end i := i + 1 end end end generate_constraints is indexing description: "Generate `constraints' clause." external_name: "GenerateConstraints" require non_void_eiffel_class: eiffel_class /= Void is_generic: eiffel_class.get_is_generic non_void_constraints: eiffel_class.get_constraints /= Void local constraints: ARRAY [ANY] a_constraint: STRING i: INTEGER do generated_code := generated_code.concat_string_string_string_string (generated_code, Tab, Constraints_keyword, Colon) generated_code := generated_code.concat_string_string_string (generated_code, Space, Inverted_comma) constraints := eiffel_class.get_constraints from until i = constraints.count loop a_constraint ?= constraints.item (i) if a_constraint /= Void then generated_code := generated_code.concat_string_string (generated_code, a_constraint) if i < constraints.count - 1 then generated_code := generated_code.concat_string_string_string (generated_code, Comma, Space) end end i := i + 1 end generated_code := generated_code.concat_string_string_string (generated_code, Inverted_comma, Windows_new_line) end generate_inherit_clause is indexing description: "Generate inherit clause." external_name: "GenerateInheritClause" require non_void_eiffel_class: eiffel_class /= Void non_void_class_name: eiffel_class.get_eiffel_name /= Void not_empty_class_name: eiffel_class.get_eiffel_name.get_length > 0 local parents_names: SYSTEM_COLLECTIONS_ICOLLECTION enumerator: SYSTEM_COLLECTIONS_IENUMERATOR a_parent: STRING inheritance_clauses: ARRAY [SYSTEM_COLLECTIONS_ARRAYLIST] rename_clauses: SYSTEM_COLLECTIONS_ARRAYLIST undefine_clauses: SYSTEM_COLLECTIONS_ARRAYLIST redefine_clauses: SYSTEM_COLLECTIONS_ARRAYLIST select_clauses: SYSTEM_COLLECTIONS_ARRAYLIST formatted_parents: ARRAY [STRING] i: INTEGER do parents := eiffel_class.get_Parents if parents.get_count > 1 or has_any_rename or has_any_undefine or has_any_redefine or (parents.get_count = 1 and (not parents.has (Any_class))) then generated_code := generated_code.Concat_String_String (generated_code, Inherit_keyword) parents_names := parents.get_Keys enumerator := parents_names.Get_Enumerator from create formatted_parents.make (parents.get_count) until not enumerator.Move_Next loop a_parent ?= enumerator.get_Current if a_parent /= Void then formatted_parents.put (i, a_parent) end i := i + 1 end from i := formatted_parents.count - 1 until i = -1 loop a_parent := formatted_parents.item (i) if a_parent /= Void then if (not a_parent.Equals_String (Any_class)) or has_any_rename or has_any_redefine or has_any_undefine then generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, a_parent) end end inheritance_clauses ?= parents.get_Item (a_parent) if inheritance_clauses /= Void then -- rename clauses if inheritance_clauses.Item (0).get_count > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, Tab) generated_code := generated_code.Concat_String_String (generated_code, Rename_keyword) rename_clauses := inheritance_clauses.Item (0) if rename_clauses /= Void and then rename_clauses.get_count > 0 then generate_inheritance_clauses (rename_clauses) end end -- undefine clauses if inheritance_clauses.Item (1).get_count > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, Tab) generated_code := generated_code.Concat_String_String (generated_code, Undefine_keyword) undefine_clauses := inheritance_clauses.Item (1) if undefine_clauses /= Void and then undefine_clauses.get_count > 0 then generate_inheritance_clauses (undefine_clauses) end end -- redefine clauses if inheritance_clauses.Item (2).get_count > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, Tab) generated_code := generated_code.Concat_String_String (generated_code, Redefine_keyword) redefine_clauses := inheritance_clauses.Item (2) if redefine_clauses /= Void and then redefine_clauses.get_count > 0 then generate_inheritance_clauses (redefine_clauses) end end -- select clauses if inheritance_clauses.Item (3).get_count > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, Tab) generated_code := generated_code.Concat_String_String (generated_code, Select_keyword) select_clauses := inheritance_clauses.Item (3) if select_clauses /= Void and then select_clauses.get_count > 0 then generate_inheritance_clauses (select_clauses) end end -- Add `end' keyword at the end of inheritance clauses if inheritance_clauses.Item (0).get_count > 0 or inheritance_clauses.Item (1).get_count > 0 or inheritance_clauses.Item (2).get_count > 0 or inheritance_clauses.Item (3).get_count > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, Tab) generated_code := generated_code.Concat_String_String (generated_code, End_keyword) end end i := i - 1 end generated_code := generated_code.Concat_String_String_String (generated_code, Windows_new_line, Windows_new_line) end end generate_create_clause is -- | Do not generate creation clause for deferred classes or expanded classes. indexing description: "Generate create clause." external_name: "GenerateCreateClause" require non_void_eiffel_class: eiffel_class /= Void non_void_class_name: eiffel_class.get_eiffel_name /= Void not_empty_class_name: eiffel_class.get_eiffel_name.get_length > 0 local i: INTEGER a_feature_name: STRING a_feature: ISE_REFLECTION_EIFFELFEATURE initialization_features: SYSTEM_COLLECTIONS_ARRAYLIST value: STRING do initialization_features := eiffel_class.get_Initialization_Features if initialization_features.get_count > 0 and not eiffel_class.get_Is_Deferred and not is_special_class then -- Do not generate creation clause for expanded classes if not eiffel_class.get_is_expanded then generated_code := generated_code.Concat_String_String (generated_code, Create_keyword) from i := 0 until i = initialization_features.get_count loop a_feature ?= initialization_features.get_Item (i) if a_feature /= Void then a_feature_name := a_feature.get_eiffel_name if a_feature_name /= Void and then a_feature_name.get_length > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, a_feature_name) if i < (initialization_features.get_count - 1) then generated_code := generated_code.Concat_String_String (generated_code, Comma) end end end i := i + 1 end generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Windows_new_line, Initialization_feature_clause_exported_to_none) else generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Windows_new_line, Initialization_feature_clause) end generated_code := generated_code.Concat_String_String_String (generated_code, Windows_new_line, Windows_new_line) from i := 0 until i = initialization_features.get_count loop a_feature ?= initialization_features.get_Item (i) if a_feature /= Void then if a_feature.get_Is_Field and a_feature.get_Is_Static and not a_feature.get_is_enum_literal and a_feature.get_is_literal then value := a_feature.get_literal_value if value /= Void and then value.get_length > 0 then generate_eiffel_feature (a_feature) end else generate_eiffel_feature (a_feature) end end i := i + 1 end elseif initialization_features.get_count = 0 and not eiffel_class.get_Is_Deferred and not eiffel_class.get_Is_Expanded then generated_code := generated_code.Concat_String_String_String_String (generated_code, Create_none, Windows_new_line, Windows_new_line) end end generate_class_features is indexing description: "Generate class features, except initialization ones." external_name: "GenerateClassFeatures" require non_void_eiffel_class: eiffel_class /= Void non_void_class_name: eiffel_class.get_eiffel_name /= Void not_empty_class_name: eiffel_class.get_eiffel_name.get_length > 0 local access_features: SYSTEM_COLLECTIONS_ARRAYLIST element_change_features: SYSTEM_COLLECTIONS_ARRAYLIST basic_operations_features: SYSTEM_COLLECTIONS_ARRAYLIST unary_operators_features: SYSTEM_COLLECTIONS_ARRAYLIST binary_operators_features: SYSTEM_COLLECTIONS_ARRAYLIST specials_features: SYSTEM_COLLECTIONS_ARRAYLIST implementation_features: SYSTEM_COLLECTIONS_ARRAYLIST do -- Generate access feature clause. access_features := eiffel_class.get_Access_Features if access_features.get_count > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Access_feature_clause, Windows_new_line, Windows_new_line) intern_generate_class_features (access_features) end -- Generate element change feature clause. element_change_features := eiffel_class.get_Element_Change_Features if element_change_features.get_count > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Element_change_feature_clause, Windows_new_line, Windows_new_line) intern_generate_class_features (element_change_features) end -- Generate basic operations feature clause. basic_operations_features := eiffel_class.get_Basic_Operations if basic_operations_features.get_count > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Basic_operations_feature_clause, Windows_new_line, Windows_new_line) intern_generate_class_features (basic_operations_features) end -- Generate unary operators feature clause. unary_operators_features := eiffel_class.get_Unary_Operators_Features if unary_operators_features.get_count > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Unary_operators_feature_clause, Windows_new_line, Windows_new_line) intern_generate_class_features (unary_operators_features) end -- Generate binary operators feature clause. binary_operators_features := eiffel_class.get_Binary_Operators_Features if binary_operators_features.get_count > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Binary_operators_feature_clause, Windows_new_line, Windows_new_line) intern_generate_class_features (binary_operators_features) else if eiffel_class.get_bit_or_infix then generated_code := generated_code.concat_string_string (generated_code, Bit_or_infix_code) end end -- Generate specials feature clause. specials_features := eiffel_class.get_Special_Features if specials_features.get_count > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Specials_feature_clause, Windows_new_line, Windows_new_line) intern_generate_class_features (specials_features) end -- Generate implementation feature clause. implementation_features := eiffel_class.get_Implementation_Features if implementation_features.get_count > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Implementation_feature_clause, Windows_new_line, Windows_new_line) intern_generate_class_features (implementation_features) end end generate_inheritance_clauses (clauses: SYSTEM_COLLECTIONS_ARRAYLIST) is -- | clauses: SYSTEM_COLLECTIONS_ARRAYLIST [ISE_REFLECTION_INHERITANCECLAUSE] indexing description: "Generate inheritance clauses from `clauses'." external_name: "GenerateInheritanceClauses" require non_void_clauses: clauses /= Void not_empty_clauses: clauses.get_count > 0 local i: INTEGER a_clause: ISE_REFLECTION_INHERITANCECLAUSE do from until i = clauses.get_count loop a_clause ?= clauses.get_Item (i) if a_clause /= Void then generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, Tab) generated_code := generated_code.Concat_String_String_String (generated_code, Tab, a_clause.string_representation) if i < (clauses.get_count - 1) then generated_code := generated_code.Concat_String_String (generated_code, Comma) end end i := i + 1 end end is_special_class: BOOLEAN is indexing description: "Is class to be generated a special class?" external_name: "IsSpecialClass" require non_void_special_classes: special_classes /= Void local eiffel_class_name: STRING do eiffel_class_name ?= eiffel_class.get_eiffel_name.clone eiffel_class_name := eiffel_class_name.to_upper Result := special_classes.contains_key (eiffel_class_name) end intern_generate_class_features (a_list: SYSTEM_COLLECTIONS_ARRAYLIST) is -- | Call in loop `generate_eiffel_feature'. indexing description: "Generate class features from `a_list'." external_name: "InternGenerateClassFeatures" local i: INTEGER a_feature: ISE_REFLECTION_EIFFELFEATURE value: STRING do from until i = a_list.get_count loop a_feature ?= a_list.get_Item (i) if a_feature /= Void and then (a_feature.get_eiffel_name /= Void and a_feature.get_eiffel_name.get_length > 0) then if a_feature.get_Is_Field and a_feature.get_Is_Static and not a_feature.get_is_enum_literal and a_feature.get_is_literal then value := a_feature.get_literal_value if value /= Void and then value.get_length > 0 then generate_eiffel_feature (a_feature) end else generate_eiffel_feature (a_feature) end end i := i + 1 end end generate_eiffel_feature (a_feature: ISE_REFLECTION_EIFFELFEATURE) is indexing description: "Generate Eiffel feature from `a_feature'." external_name: "GenerateEiffelFeature" require non_void_feature: a_feature /= Void non_void_feature_name: a_feature.get_eiffel_name /= Void not_empty_feature_name: a_feature.get_eiffel_name.get_length > 0 local is_binary_operator: BOOLEAN is_unary_operator: BOOLEAN unary_operator: STRING binary_operator: STRING arguments: SYSTEM_COLLECTIONS_ARRAYLIST i: INTEGER an_argument: ISE_REFLECTION_INAMEDSIGNATURETYPE formal_argument: ISE_REFLECTION_FORMALNAMEDSIGNATURETYPE generic_parameter_index: INTEGER argument_name: STRING argument_type: STRING formal_return_type: ISE_REFLECTION_FORMALSIGNATURETYPE return_type_name: STRING comments: SYSTEM_COLLECTIONS_ARRAYLIST a_comment: STRING preconditions: SYSTEM_COLLECTIONS_ARRAYLIST postconditions: SYSTEM_COLLECTIONS_ARRAYLIST support: ISE_REFLECTION_CODEGENERATIONSUPPORT generic_type_names: ARRAY [ANY] do create support.make_codegenerationsupport support.make generic_type_names := support.get_generic_type_names is_binary_operator := eiffel_class.get_Binary_Operators_Features.has (a_feature) is_unary_operator := eiffel_class.get_Unary_Operators_Features.has (a_feature) generated_code := generated_code.Concat_String_String (generated_code, Tab) -- frozen if a_feature.get_Is_Frozen then generated_code := generated_code.Concat_String_String_String (generated_code, Frozen_keyword, Space) end -- feature name if is_unary_operator and a_feature.get_Is_Prefix then generated_code := generated_code.Concat_String_String_String (generated_code, Prefix_keyword, a_feature.get_eiffel_name) else --if is_binary_operator and a_feature.IsInfix then if a_feature.get_Is_Infix then generated_code := generated_code.Concat_String_String_String (generated_code, Infix_keyword, a_feature.get_eiffel_name) else generated_code := generated_code.Concat_String_String (generated_code, a_feature.get_eiffel_name) end end -- feature arguments arguments := a_feature.get_Arguments if not is_unary_operator and arguments.get_count > 0 then generated_code := generated_code.Concat_String_String_String (generated_code, Space, Opening_round_bracket) from i := 0 until i = arguments.get_count loop an_argument ?= arguments.get_Item (i) if an_argument /= Void then argument_name := an_argument.eiffel_name formal_argument ?= arguments.get_item (i) if formal_argument /= Void and then generic_type_names /= Void then generic_parameter_index := formal_argument.get_generic_parameter_index if generic_parameter_index < generic_type_names.count then argument_type ?= generic_type_names.item (generic_parameter_index) else argument_type := an_argument.type_eiffel_name end else argument_type := an_argument.type_eiffel_name end end generated_code := generated_code.Concat_String_String_String_String (generated_code, argument_name, Colon, Space) generated_code := generated_code.Concat_String_String (generated_code, argument_type) if i < (arguments.get_count - 1) then generated_code := generated_code.Concat_String_String_String (generated_code, Semi_colon, Space) end i := i + 1 end generated_code := generated_code.Concat_String_String (generated_code, Closing_round_bracket) end -- feature return type if a_feature.get_is_method and then a_feature.get_Return_Type /= Void and then a_feature.get_Return_Type.Type_eiffel_name /= Void then formal_return_type ?= a_feature.get_return_type if formal_return_type /= Void and then generic_type_names /= Void then generic_parameter_index := formal_return_type.get_generic_parameter_index if generic_parameter_index < generic_type_names.count then return_type_name ?= generic_type_names.item (generic_parameter_index) else return_type_name := a_feature.get_return_type.type_eiffel_name end else return_type_name := a_feature.get_return_type.type_eiffel_name end generated_code := generated_code.Concat_String_String_String_String (generated_code, Colon, Space, return_type_name) end if a_feature.get_Is_Field then if a_feature.get_external_name /= Void and then not a_feature.get_external_name.Starts_With (Property_set_prefix) then generated_code := generated_code.Concat_String_String_String_String (generated_code, Colon, Space, a_feature.get_Return_Type.Type_eiffel_name) end end -- `is' keyword generated_code := generated_code.Concat_String_String_String (generated_code, Space, Is_keyword) -- feature comments comments := a_feature.get_Comments from i := 0 until i = comments.get_count loop a_comment ?= comments.get_Item (i) if a_comment /= Void and then a_comment.get_length > 0 then --generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, Tab) --generated_code := generated_code.Concat_String_String_String (generated_code, Tab, Dashes) generated_code := generated_code.Concat_String_String_String_String (generated_code, Tab, Dashes, Space) generated_code := generated_code.Concat_String_String (generated_code, a_comment) end i := i + 1 end -- feature preconditions preconditions := a_feature.get_Preconditions if preconditions.get_count > 0 then generate_feature_assertions (preconditions, Require_keyword) end -- `external' keyword if a_feature.get_is_enum_literal or not a_feature.get_is_literal then generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, Tab) generated_code := generated_code.Concat_String_String_String_String (generated_code, External_keyword, Windows_new_line, Tab) generated_code := generated_code.Concat_String_String_String (generated_code, Tab, Tab) end generate_external_clause (a_feature) -- feature alias if a_feature.get_is_enum_literal or not a_feature.get_is_literal then if a_feature.get_Is_Method or a_feature.get_Is_Field then generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, Tab) generated_code := generated_code.Concat_String_String (generated_code, Alias_keyword) generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, Tab) generated_code := generated_code.Concat_String_String_String_String (generated_code, Tab, Inverted_comma, a_feature.get_External_Name) generated_code := generated_code.Concat_String_String (generated_code, Inverted_comma) end -- feature postconditions postconditions := a_feature.get_Postconditions if postconditions.get_count > 0 then generate_feature_assertions (postconditions, Ensure_keyword) end -- `end' keyword generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab,Tab) generated_code := generated_code.Concat_String_String_String_String (generated_code, End_keyword, Windows_new_line, Windows_new_line) else if generated_code.get_length > 0 then generated_code := generated_code.Concat_String_String_String (generated_code, Windows_new_line, Windows_new_line) end end end generate_feature_assertions (assertions: SYSTEM_COLLECTIONS_ARRAYLIST; keyword: STRING) is indexing description: "Generate feature assertions from `assertions' (include `keyword')." external_name: "GenerateFeatureAssertions" require non_void_assertions: assertions /= Void not_empty_assertions: assertions.get_count > 0 non_void_keyword: keyword /= Void valid_keyword: keyword.Equals_String (Require_keyword) or keyword.Equals_String (Ensure_keyword) local i: INTEGER an_assertion: ARRAY [STRING] an_assertion_tag: STRING an_assertion_text: STRING do from until i = assertions.get_count loop an_assertion ?= assertions.get_Item (i) if an_assertion /= Void and then an_assertion.count >= 1 then if i = 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, Tab) generated_code := generated_code.Concat_String_String (generated_code, keyword) end an_assertion_tag := an_assertion.Item (0) an_assertion_text := an_assertion.Item (1) generated_code := generated_code.Concat_String_String_String_String (generated_code, Windows_new_line, Tab, Tab) generated_code := generated_code.Concat_String_String (generated_code, Tab) if an_assertion_tag /= Void and then an_assertion_tag.get_length > 0 then generated_code := generated_code.Concat_String_String_String_String (generated_code, an_assertion_tag, Colon, Space) end generated_code := generated_code.Concat_String_String_String (generated_code, an_assertion_text, Windows_new_line) end i := i + 1 end end generate_external_clause (a_feature: ISE_REFLECTION_EIFFELFEATURE) is indexing description: "Generate `a_feature' external clause." external_name: "GenerateExternalClause" require non_void_feature: a_feature /= Void non_void_feature_name: a_feature.get_eiffel_name /= Void not_empty_feature_name: a_feature.get_eiffel_name.get_length > 0 local signature: STRING is_binary_operator: BOOLEAN is_unary_operator: BOOLEAN formatter: FORMATTER value: STRING do create formatter.make signature := feature_signature (a_feature) is_binary_operator := eiffel_class.get_Binary_Operators_Features.has (a_feature) is_unary_operator := eiffel_class.get_Unary_Operators_Features.has (a_feature) if a_feature.get_Is_Method then if is_unary_operator or is_binary_operator then -- "IL operator `signature' use `alias' " generated_code := generated_code.Concat_String_String_String_String (generated_code, Inverted_comma, IL, Space) generated_code := generated_code.Concat_String_String_String_String (generated_code, Operator, Space, signature) generated_code := generated_code.Concat_String_String_String_String (generated_code, Use, Space, formatter.Format_Strong_Name (eiffel_class.get_Full_External_Name)) generated_code := generated_code.Concat_String_String (generated_code, Inverted_comma) else if a_feature.get_Is_Static then -- "IL static `signature' use `alias' " generated_code := generated_code.Concat_String_String_String_String (generated_code, Inverted_comma, IL, Space) generated_code := generated_code.Concat_String_String_String_String (generated_code, Static, signature, Use) generated_code := generated_code.Concat_String_String_String_String (generated_code, Space, formatter.Format_Strong_Name (eiffel_class.get_Full_External_Name), Inverted_comma) else if a_feature.get_Is_Abstract then -- "IL deferred `signature' use `alias' " generated_code := generated_code.Concat_String_String_String_String (generated_code, Inverted_comma, IL, Space) generated_code := generated_code.Concat_String_String_String_String (generated_code, Deferred_keyword, signature, Use) generated_code := generated_code.Concat_String_String_String_String (generated_code, Space, formatter.Format_Strong_Name (eiffel_class.get_Full_External_Name), Inverted_comma) else -- "IL `signature' use `alias' " generated_code := generated_code.Concat_String_String_String_String (generated_code, Inverted_comma, IL, signature) generated_code := generated_code.Concat_String_String_String_String (generated_code, Use, Space, formatter.Format_Strong_Name (eiffel_class.get_Full_External_Name)) generated_code := generated_code.Concat_String_String (generated_code, Inverted_comma) end end end else if a_feature.get_Is_Field then if a_feature.get_Is_Static then if not a_feature.get_is_enum_literal and a_feature.get_is_literal then value := a_feature.get_literal_value generated_code := generated_code.concat_string_string (generated_code, value) else if a_feature.get_Is_Enum_Literal then -- "IL enum signature : `type_full_name' use `alias'. generated_code := generated_code.Concat_String_String_String_String (generated_code, Inverted_comma, IL, Space) generated_code := generated_code.Concat_String_String_String (generated_code, Enum_keyword, Space) else -- "IL static_field signature : `type_full_name' use `alias'. generated_code := generated_code.Concat_String_String_String_String (generated_code, Inverted_comma, IL, Space) generated_code := generated_code.Concat_String_String_String (generated_code, Static_field, Space) end generated_code := generated_code.Concat_String_String_String_String (generated_code, Signature_keyword, Space, Colon) generated_code := generated_code.Concat_String_String_String_String (generated_code, a_feature.get_Return_Type.Type_Full_External_Name, Space, Use) generated_code := generated_code.Concat_String_String_String_String (generated_code, Space, formatter.Format_Strong_Name (eiffel_class.get_Full_External_Name), Inverted_comma) end else -- "IL field signature : `type_full_name' use `alias'. generated_code := generated_code.Concat_String_String_String_String (generated_code, Inverted_comma, IL, Space) generated_code := generated_code.Concat_String_String_String_String (generated_code, Field, Space, Signature_keyword) generated_code := generated_code.Concat_String_String_String_String (generated_code, Space, Colon, a_feature.get_Return_Type.Type_Full_External_Name) generated_code := generated_code.Concat_String_String_String_String (generated_code, Space, Use, Space) generated_code := generated_code.Concat_String_String_String (generated_code, formatter.Format_Strong_Name (eiffel_class.get_Full_External_Name), Inverted_comma) end else -- "IL creator `signature' use `alias' " generated_code := generated_code.Concat_String_String_String_String (generated_code, Inverted_comma, IL, Space) generated_code := generated_code.Concat_String_String_String_String (generated_code, Creator, signature, Use) generated_code := generated_code.Concat_String_String_String_String (generated_code, Space, formatter.Format_Strong_Name (eiffel_class.get_Full_External_Name), Inverted_comma) end end end feature_signature (a_feature: ISE_REFLECTION_EIFFELFEATURE): STRING is indexing description: ".Net assembly qualified signature of `a_feature'" external_name: "FeatureSignature" require non_void_feature: a_feature /= Void non_void_feature_name: a_feature.get_eiffel_name /= Void not_empty_feature_name: a_feature.get_eiffel_name.get_length > 0 local is_unary_operator: BOOLEAN is_binary_operator: BOOLEAN arguments: SYSTEM_COLLECTIONS_ARRAYLIST i: INTEGER an_argument: ISE_REFLECTION_NAMEDSIGNATURETYPE temp: STRING do create Result.make_2 ('%U', 0) is_binary_operator := eiffel_class.get_Binary_Operators_Features.has (a_feature) is_unary_operator := eiffel_class.get_Unary_Operators_Features.has (a_feature) if a_feature.get_Is_Method then arguments := a_feature.get_Arguments if not is_unary_operator or arguments.get_count > 0 then Result := Space Result := Result.Concat_String_String_String_String (Result, Signature_keyword, Space, Opening_round_bracket) from i := 0 until i = arguments.get_count loop an_argument ?= arguments.get_Item (i) if an_argument /= Void then Result := Result.Concat_String_String (Result, an_argument.Type_Full_External_Name) if i < arguments.get_count - 1 then Result := Result.Concat_String_String_String (Result, Comma, Space) end end i := i + 1 end Result := Result.Concat_String_String_String_String (Result, Closing_round_bracket, Colon, Space) create temp.make_2 ('%U', 0) else temp := Signature_keyword temp := temp.Concat_String_String_String_String (temp, Space, Colon, Space) end if a_feature.get_Return_Type /= Void and then a_feature.get_Return_Type.Type_Full_External_Name /= Void and then a_feature.get_Return_Type.Type_Full_External_Name.get_length > 0 then Result := Result.Concat_String_String_String (Result, temp, a_feature.get_Return_Type.Type_Full_External_Name) end Result := Result.Concat_String_String (Result, Space) end if not a_feature.get_Is_Method and not a_feature.get_Is_Field then arguments := a_feature.get_Arguments if arguments.get_count > 0 then Result := Space Result := Result.Concat_String_String_String_String (Result, Signature_keyword, Space, Opening_round_bracket) from i := 0 until i = arguments.get_count loop an_argument ?= arguments.get_Item (i) if an_argument /= Void then Result := Result.Concat_String_String (Result, an_argument.Type_Full_External_Name) end if i < arguments.get_count - 1 then Result := Result.Concat_String_String_String (Result, Comma, Space) end i := i + 1 end Result := Result.Concat_String_String (Result, Closing_round_bracket) end Result := Result.Concat_String_String (Result, Space) end ensure signature_built: Result /= Void end has_any_rename: BOOLEAN is indexing description: "Does class have rename clauses for parent `ANY'?" external_name: "HasAnyRename" require non_void_parents: parents /= Void local inheritance_clauses: ARRAY [SYSTEM_COLLECTIONS_ARRAYLIST] do if parents.Contains_Key (Any_class) then inheritance_clauses ?= parents.get_Item (Any_class) if inheritance_clauses /= Void then Result := inheritance_clauses.item (0).get_count > 0 end else Result := False end end has_any_undefine: BOOLEAN is indexing description: "Does class have undefine clauses for parent `ANY'?" external_name: "HasAnyUndefine" require non_void_parents: parents /= Void local inheritance_clauses: ARRAY [SYSTEM_COLLECTIONS_ARRAYLIST] do if parents.Contains_Key (Any_class) then inheritance_clauses ?= parents.get_Item (Any_class) if inheritance_clauses /= Void then Result := inheritance_clauses.item (1).get_count > 0 end else Result := False end end has_any_redefine: BOOLEAN is indexing description: "Does class have redefine clauses for parent `ANY'?" external_name: "HasAnyRedefine" require non_void_parents: parents /= Void local inheritance_clauses: ARRAY [SYSTEM_COLLECTIONS_ARRAYLIST] do if parents.Contains_Key (Any_class) then inheritance_clauses ?= parents.get_Item (Any_class) if inheritance_clauses /= Void then Result := inheritance_clauses.item (2).get_count > 0 end else Result := False end end Bit_or_infix_code: STRING is indexing description: "Code of `|' infix" external_name: "BitOrInfixCode" once Result ?= Basic_operations_feature_clause.clone Result := Result.concat_string_string_string (Result, Windows_new_line, Windows_new_line) Result := Result.concat_string_string_string_string (Result, Tab, Bit_or_infix_signature, Windows_new_line) Result := Result.concat_string_string_string_string (Result, Tab, Tab, Do_keyword) Result := Result.concat_string_string_string_string (Result, Windows_new_line, Tab, Tab) Result := Result.concat_string_string_string_string (Result, Tab, Built_in_comment, Windows_new_line) Result := Result.concat_string_string_string_string (Result, Tab, Tab, End_keyword) Result := Result.concat_string_string_string (Result, Windows_new_line, Windows_new_line) ensure non_void_code: Result /= Void not_empty_code: Result.get_length > 0 end Bit_or_infix_signature: STRING is "infix %"|%" (infix_arg: like Current): like Current is" indexing description: "Bit or infix signature" external_name: "BitOrInfixSignature" end Built_in_comment: STRING is "--Built-in" indexing description: "Comment in infix `|' body" external_name: "BuiltInComment" end end -- class EIFFEL_CODE_GENERATOR