/[eiffelstudio]/branches/eth/eve/Src/framework/code_analysis/ca_code_analyzer.e
ViewVC logotype

Diff of /branches/eth/eve/Src/framework/code_analysis/ca_code_analyzer.e

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 94982 by apaolo, Wed Apr 16 17:42:14 2014 UTC revision 94983 by jasonw, Fri May 2 11:05:28 2014 UTC
# Line 1  Line 1 
1  note  note
2          description: "THE Code Analyzer."          description: "THE Code Analyzer."
3          author: "Stefan Zurfluh"          author: "Stefan Zurfluh"
4          date: "$Date$"          date: "$Date$"
5          revision: "$Revision$"          revision: "$Revision$"
6    
7  class  class
8          CA_CODE_ANALYZER          CA_CODE_ANALYZER
9    
10  inherit  inherit
11          SHARED_EIFFEL_PROJECT          SHARED_EIFFEL_PROJECT
12    
13          CA_SHARED_NAMES          CA_SHARED_NAMES
14    
15  create  create
16          make          make
17    
18  feature {NONE} -- Initialization  feature {NONE} -- Initialization
19    
20          make          make
21                          -- Initialization for `Current'.                          -- Initialization for `Current'.
22                  do                  do
23                          create settings.make                          create settings.make
24                          create rules.make                          create rules.make
25                                  -- Adding the rules.                                  -- Adding the rules.
26                          rules.extend (create {CA_SELF_ASSIGNMENT_RULE}.make)                          rules.extend (create {CA_SELF_ASSIGNMENT_RULE}.make)
27                          rules.extend (create {CA_UNUSED_ARGUMENT_RULE}.make)                          rules.extend (create {CA_UNUSED_ARGUMENT_RULE}.make)
28                          rules.extend (create {CA_NPATH_RULE}.make (settings.preference_manager))                          rules.extend (create {CA_NPATH_RULE}.make (settings.preference_manager))
29                          rules.extend (create {CA_EMPTY_IF_RULE}.make)                          rules.extend (create {CA_EMPTY_IF_RULE}.make)
30                          rules.extend (create {CA_FEATURE_NEVER_CALLED_RULE}.make)                          rules.extend (create {CA_FEATURE_NEVER_CALLED_RULE}.make)
31                          rules.extend (create {CA_CQ_SEPARATION_RULE}.make)                          rules.extend (create {CA_CQ_SEPARATION_RULE}.make)
32                          rules.extend (create {CA_UNNEEDED_OT_LOCAL_RULE}.make)                          rules.extend (create {CA_UNNEEDED_OT_LOCAL_RULE}.make)
33                          rules.extend (create {CA_UNNEEDED_OBJECT_TEST_RULE}.make) -- Needs type info.                          rules.extend (create {CA_UNNEEDED_OBJECT_TEST_RULE}.make) -- Needs type info.
34                          rules.extend (create {CA_NESTED_COMPLEXITY_RULE}.make (settings.preference_manager))                          rules.extend (create {CA_NESTED_COMPLEXITY_RULE}.make (settings.preference_manager))
35                          rules.extend (create {CA_MANY_ARGUMENTS_RULE}.make (settings.preference_manager))                          rules.extend (create {CA_MANY_ARGUMENTS_RULE}.make (settings.preference_manager))
36                          rules.extend (create {CA_CREATION_PROC_EXPORTED_RULE}.make)                          rules.extend (create {CA_CREATION_PROC_EXPORTED_RULE}.make)
37                          rules.extend (create {CA_VARIABLE_NOT_READ_RULE}.make)                          rules.extend (create {CA_VARIABLE_NOT_READ_RULE}.make)
38                          rules.extend (create {CA_SEMICOLON_ARGUMENTS_RULE}.make)                          rules.extend (create {CA_SEMICOLON_ARGUMENTS_RULE}.make)
39                          rules.extend (create {CA_VERY_LONG_ROUTINE_RULE}.make (settings.preference_manager))                          rules.extend (create {CA_VERY_LONG_ROUTINE_RULE}.make (settings.preference_manager))
40                          rules.extend (create {CA_VERY_BIG_CLASS_RULE}.make (settings.preference_manager))                          rules.extend (create {CA_VERY_BIG_CLASS_RULE}.make (settings.preference_manager))
41                          rules.extend (create {CA_FEATURE_SECTION_COMMENT_RULE}.make)                          rules.extend (create {CA_FEATURE_SECTION_COMMENT_RULE}.make)
42                          rules.extend (create {CA_FEATURE_NOT_COMMENTED_RULE}.make)                          rules.extend (create {CA_FEATURE_NOT_COMMENTED_RULE}.make)
43                          rules.extend (create {CA_BOOLEAN_RESULT_RULE}.make)                          rules.extend (create {CA_BOOLEAN_RESULT_RULE}.make)
44                          rules.extend (create {CA_BOOLEAN_COMPARISON_RULE}.make)                          rules.extend (create {CA_BOOLEAN_COMPARISON_RULE}.make)
45                          rules.extend (create {CA_VERY_SHORT_IDENTIFIER_RULE}.make (settings.preference_manager))                          rules.extend (create {CA_VERY_SHORT_IDENTIFIER_RULE}.make (settings.preference_manager))
46                          rules.extend (create {CA_VERY_LONG_IDENTIFIER_RULE}.make (settings.preference_manager))                          rules.extend (create {CA_VERY_LONG_IDENTIFIER_RULE}.make (settings.preference_manager))
47                          rules.extend (create {CA_MISSING_IS_EQUAL_RULE}.make)                          rules.extend (create {CA_MISSING_IS_EQUAL_RULE}.make)
48                          rules.extend (create {CA_SIMPLIFIABLE_BOOLEAN_RULE}.make)                          rules.extend (create {CA_SIMPLIFIABLE_BOOLEAN_RULE}.make)
49                          rules.extend (create {CA_SELF_COMPARISON_RULE}.make)                          rules.extend (create {CA_SELF_COMPARISON_RULE}.make)
50                          rules.extend (create {CA_TODO_RULE}.make)                          rules.extend (create {CA_TODO_RULE}.make)
51                          rules.extend (create {CA_WRONG_LOOP_ITERATION_RULE}.make)                          rules.extend (create {CA_WRONG_LOOP_ITERATION_RULE}.make)
52                          rules.extend (create {CA_INSPECT_INSTRUCTIONS_RULE}.make (settings.preference_manager))                          rules.extend (create {CA_INSPECT_INSTRUCTIONS_RULE}.make (settings.preference_manager))
53                          rules.extend (create {CA_ATTRIBUTE_TO_LOCAL_RULE}.make)                          rules.extend (create {CA_ATTRIBUTE_TO_LOCAL_RULE}.make)
54                          rules.extend (create {CA_EMPTY_EFFECTIVE_ROUTINE_RULE}.make)                          rules.extend (create {CA_EMPTY_EFFECTIVE_ROUTINE_RULE}.make)
55                          rules.extend (create {CA_IF_ELSE_NOT_EQUAL_RULE}.make)                          rules.extend (create {CA_IF_ELSE_NOT_EQUAL_RULE}.make)
56                          rules.extend (create {CA_SHORT_CIRCUIT_IF_RULE}.make)                          rules.extend (create {CA_SHORT_CIRCUIT_IF_RULE}.make)
57                          rules.extend (create {CA_ITERABLE_LOOP_RULE}.make) -- Needs type info.                          rules.extend (create {CA_ITERABLE_LOOP_RULE}.make) -- Needs type info.
58                          rules.extend (create {CA_COUNT_EQUALS_ZERO_RULE}.make) -- Needs type info.                          rules.extend (create {CA_COUNT_EQUALS_ZERO_RULE}.make) -- Needs type info.
59                          rules.extend (create {CA_DEEPLY_NESTED_IF_RULE}.make (settings.preference_manager))                          rules.extend (create {CA_DEEPLY_NESTED_IF_RULE}.make (settings.preference_manager))
60                          rules.extend (create {CA_UNNEEDED_HELPER_VARIABLE_RULE}.make (settings.preference_manager))                          rules.extend (create {CA_UNNEEDED_HELPER_VARIABLE_RULE}.make (settings.preference_manager))
61                          rules.extend (create {CA_UNNEEDED_PARENTHESES_RULE}.make)                          rules.extend (create {CA_UNNEEDED_PARENTHESES_RULE}.make)
62                          rules.extend (create {CA_CLASS_NAMING_CONVENTION_RULE}.make)                          rules.extend (create {CA_CLASS_NAMING_CONVENTION_RULE}.make)
63                          rules.extend (create {CA_FEATURE_NAMING_CONVENTION_RULE}.make)                          rules.extend (create {CA_FEATURE_NAMING_CONVENTION_RULE}.make)
64                          rules.extend (create {CA_VARIABLE_NAMING_CONVENTION_RULE}.make (settings.preference_manager))                          rules.extend (create {CA_VARIABLE_NAMING_CONVENTION_RULE}.make (settings.preference_manager))
65                          rules.extend (create {CA_ARGUMENT_NAMING_CONVENTION_RULE}.make (settings.preference_manager))                          rules.extend (create {CA_ARGUMENT_NAMING_CONVENTION_RULE}.make (settings.preference_manager))
66                          rules.extend (create {CA_UNNECESSARY_SIGN_OPERATOR_RULE}.make)                          rules.extend (create {CA_UNNECESSARY_SIGN_OPERATOR_RULE}.make)
67                          rules.extend (create {CA_EMPTY_UNCOMMENTED_ROUTINE_RULE}.make)                          rules.extend (create {CA_EMPTY_UNCOMMENTED_ROUTINE_RULE}.make)
68                          rules.extend (create {CA_UNNEEDED_ACCESSOR_FUNCTION_RULE}.make)                          rules.extend (create {CA_UNNEEDED_ACCESSOR_FUNCTION_RULE}.make)
69                          rules.extend (create {CA_MERGEABLE_FEATURE_CLAUSES_RULE}.make)                          rules.extend (create {CA_MERGEABLE_FEATURE_CLAUSES_RULE}.make)
70                          rules.extend (create {CA_EMPTY_RESCUE_CLAUSE_RULE}.make)                          rules.extend (create {CA_EMPTY_RESCUE_CLAUSE_RULE}.make)
71                          rules.extend (create {CA_INSPECT_NO_WHEN_RULE}.make)                          rules.extend (create {CA_INSPECT_NO_WHEN_RULE}.make)
72                          rules.extend (create {CA_EXPLICIT_REDUNDANT_INHERITANCE_RULE}.make)                          rules.extend (create {CA_EXPLICIT_REDUNDANT_INHERITANCE_RULE}.make)
73    
74                          settings.initialize_rule_settings (rules)                          settings.initialize_rule_settings (rules)
75    
76                          create classes_to_analyze.make                          create classes_to_analyze.make
77                          create rule_violations.make (100)                          create rule_violations.make (100)
78                          create completed_actions                          create completed_actions
79                          create output_actions                          create output_actions
80    
81                          create ignoredby.make (25)                          create ignoredby.make (25)
82                          create library_class.make (25)                          create library_class.make (25)
83                          create nonlibrary_class.make (25)                          create nonlibrary_class.make (25)
84                  end                  end
85    
86  feature -- Analysis interface  feature -- Analysis interface
87    
88          add_completed_action (a_action: attached PROCEDURE [ANY, TUPLE [ITERABLE [TUPLE [detachable EXCEPTION, CLASS_C]]]])          add_completed_action (a_action: attached PROCEDURE [ANY, TUPLE [ITERABLE [TUPLE [detachable EXCEPTION, CLASS_C]]]])
89                          -- Adds `a_action' to the list of procedures that will be                          -- Adds `a_action' to the list of procedures that will be
90                          -- called when analysis has completed.                          -- called when analysis has completed.
91                  do                  do
92                          completed_actions.extend (a_action)                          completed_actions.extend (a_action)
93                  end                  end
94    
95          add_output_action (a_action: attached PROCEDURE [ANY, TUPLE [READABLE_STRING_GENERAL]])          add_output_action (a_action: attached PROCEDURE [ANY, TUPLE [READABLE_STRING_GENERAL]])
96                          -- Adds `a_action' to the procedures that are called for outputting status. The final results                          -- Adds `a_action' to the procedures that are called for outputting status. The final results
97                          -- (rule violations) are not given to these procedures.                          -- (rule violations) are not given to these procedures.
98                  do                  do
99                          output_actions.extend (a_action)                          output_actions.extend (a_action)
100                  end                  end
101    
102          analyze          analyze
103                          -- Analyze all the classes that have been added.                          -- Analyze all the classes that have been added.
104                  require                  require
105                          not is_running                          not is_running
106                  local                  local
107                          l_rules_checker: CA_ALL_RULES_CHECKER                          l_rules_checker: CA_ALL_RULES_CHECKER
108                          l_task: CA_RULE_CHECKING_TASK                          l_task: CA_RULE_CHECKING_TASK
109                          l_rules_to_check: LINKED_LIST [CA_RULE]                          l_rules_to_check: LINKED_LIST [CA_RULE]
110                  do                  do
111                          is_running := True                          is_running := True
112    
113                          create l_rules_checker.make                          create l_rules_checker.make
114                          create l_rules_to_check.make                          create l_rules_to_check.make
115                          across rules as l_rules loop                          across rules as l_rules loop
116                                  l_rules.item.clear_violations                                  l_rules.item.clear_violations
117                                  if is_rule_checkable (l_rules.item) then                                  if is_rule_checkable (l_rules.item) then
118                                          l_rules_to_check.extend (l_rules.item)                                          l_rules_to_check.extend (l_rules.item)
119                                                  -- Here we only prepare standard rules. The rule checking task will iterate again                                                  -- Here we only prepare standard rules. The rule checking task will iterate again
120                                                  -- through the rules and run the analysis on the enabled rules.                                                  -- through the rules and run the analysis on the enabled rules.
121                                          if attached {CA_STANDARD_RULE} l_rules.item as l_std_rule then                                          if attached {CA_STANDARD_RULE} l_rules.item as l_std_rule then
122                                                  l_std_rule.prepare_checking (l_rules_checker)                                                  l_std_rule.prepare_checking (l_rules_checker)
123                                          end                                          end
124                                  end                                  end
125                          end                          end
126    
127                          create l_task.make (l_rules_checker, l_rules_to_check, classes_to_analyze, agent analysis_completed)                          create l_task.make (l_rules_checker, l_rules_to_check, classes_to_analyze, agent analysis_completed)
128                          l_task.set_output_actions (output_actions)                          l_task.set_output_actions (output_actions)
129                          rota.run_task (l_task)                          rota.run_task (l_task)
130                  end                  end
131    
132          is_rule_checkable (a_rule: attached CA_RULE): BOOLEAN          is_rule_checkable (a_rule: attached CA_RULE): BOOLEAN
133                          -- Will `a_rule' be checked based on the current preferences and based on the current                          -- Will `a_rule' be checked based on the current preferences and based on the current
134                          -- checking scope?                          -- checking scope?
135                  do                  do
136                          Result := a_rule.is_enabled.value                          Result := a_rule.is_enabled.value
137                                                  and then (system_wide_check or else (not a_rule.is_system_wide))                                                  and then (system_wide_check or else (not a_rule.is_system_wide))
138                                                  and then is_severity_enabled (a_rule.severity)                                                  and then is_severity_enabled (a_rule.severity)
139                  end                  end
140    
141          clear_classes_to_analyze          clear_classes_to_analyze
142                          -- Removes all classes that have been added to the list of classes                          -- Removes all classes that have been added to the list of classes
143                          -- to analyze.                          -- to analyze.
144                  do                  do
145                          classes_to_analyze.wipe_out                          classes_to_analyze.wipe_out
146                  end                  end
147    
148          add_whole_system          add_whole_system
149                          -- Adds all the classes that are part of the current system. Classes of referenced libraries                          -- Adds all the classes that are part of the current system. Classes of referenced libraries
150                          -- will not be added.                          -- will not be added.
151                  local                  do
152                          l_cluster: CLUSTER_I                          across
153                  do                                  eiffel_universe.groups as l_groups
154                          across                          loop
155                                  eiffel_universe.groups as l_groups                                          -- Only load top-level clusters, as the others will be loaded recursively afterwards.
156                          loop                                  if attached {CLUSTER_I} l_groups.item as l_cluster and then l_cluster.parent_cluster = Void then
157                                  l_cluster ?= l_groups.item                                          add_cluster (l_cluster)
158                                          -- Only load top-level clusters, as the others will be loaded recursively afterwards.                                  end
159                                  if l_cluster /= Void and then l_cluster.parent_cluster = Void then                          end
160                                          add_cluster (l_cluster)  
161                                  end                          system_wide_check := True
162                          end                  end
163    
164                          system_wide_check := True          add_cluster (a_cluster: attached CLUSTER_I)
165                  end                          -- Add all classes of cluster `a_cluster'.
166                    do
167          add_cluster (a_cluster: attached CLUSTER_I)                          system_wide_check := False
168                          -- Add all classes of cluster `a_cluster'.  
169                  do                          if a_cluster.classes /= Void then
170                          system_wide_check := False                                  across a_cluster.classes as ic loop
171                                            add_class (ic.item)
172                          if a_cluster.classes /= Void then                                  end
173                                  across a_cluster.classes as ic loop                          end
174                                          add_class (ic.item)  
175                                  end                          if a_cluster.sub_clusters /= Void then
176                          end                                  across a_cluster.sub_clusters as ic loop
177                                            add_cluster (ic.item)
178                          if a_cluster.sub_clusters /= Void then                                  end
179                                  across a_cluster.sub_clusters as ic loop                          end
180                                          add_cluster (ic.item)                  end
181                                  end  
182                          end          add_group (a_group: attached CONF_GROUP)
183                  end                          -- Add all classes of the configuration group `a_group'.
184                    require
185          add_group (a_group: attached CONF_GROUP)                          a_group_not_void: a_group /= Void
186                          -- Add all classes of the configuration group `a_group'.                  do
187                  require                          if a_group.classes /= Void then
188                          a_group_not_void: a_group /= Void                                  across a_group.classes as ic loop
189                  do                                          add_class (ic.item)
190                          if a_group.classes /= Void then                                  end
191                                  across a_group.classes as ic loop                          end
192                                          add_class (ic.item)                  end
193                                  end  
194                          end          add_classes (a_classes: attached ITERABLE [attached CONF_CLASS])
195                  end                          -- Add the classes `a_classes'.
196                    do
197          add_classes (a_classes: attached ITERABLE [attached CONF_CLASS])                          system_wide_check := False
198                          -- Add the classes `a_classes'.  
199                  do                          across a_classes as l_classes loop
200                          system_wide_check := False                                  add_class (l_classes.item)
201                            end
202                          across a_classes as l_classes loop                  end
203                                  add_class (l_classes.item)  
204                          end          add_class (a_class: attached CONF_CLASS)
205                  end                          -- Adds class `a_class'.
206                    do
207          add_class (a_class: attached CONF_CLASS)                          system_wide_check := False
208                          -- Adds class `a_class'.  
209                  local                          if attached {EIFFEL_CLASS_I} a_class as l_eiffel_class
210                          l_class_c: CLASS_C                                  and then attached l_eiffel_class.compiled_class as l_compiled
211                  do                          then
212                          system_wide_check := False                                  classes_to_analyze.extend (l_compiled)
213    
214                          if attached {EIFFEL_CLASS_I} a_class as l_eiffel_class                                  extract_indexes (l_compiled)
215                                  and then attached l_eiffel_class.compiled_class as l_compiled                          else
216                          then                                  output_actions.call ([ca_messages.class_skipped (a_class.name)])
217                                  classes_to_analyze.extend (l_compiled)                          end
218                    end
219                                  extract_indexes (l_compiled)  
220                          else  feature -- Properties
221                                  output_actions.call ([ca_messages.class_skipped (a_class.name)])  
222                          end          is_running: BOOLEAN
223                  end                          -- Is code analysis running?
224    
225  feature -- Properties          rules: LINKED_LIST [CA_RULE]
226                            -- List of rules that will be used for analysis.
227          is_running: BOOLEAN  
228                          -- Is code analysis running?          rule_violations: detachable HASH_TABLE [SORTED_TWO_WAY_LIST [CA_RULE_VIOLATION], CLASS_C]
229                            -- All found violations from the last analysis.
230          rules: LINKED_LIST [CA_RULE]  
231                          -- List of rules that will be used for analysis.          settings: CA_SETTINGS
232                            -- The settings manager for Code Analysis.
233          rule_violations: detachable HASH_TABLE [SORTED_TWO_WAY_LIST [CA_RULE_VIOLATION], CLASS_C]  
234                          -- All found violations from the last analysis.          preferences: PREFERENCES
235                            -- Code Analysis preferences.
236          settings: CA_SETTINGS                  do Result := settings.preferences end
237                          -- The settings manager for Code Analysis.  
238            class_list: ITERABLE [CLASS_C]
239          preferences: PREFERENCES                          -- List of classes that have been added.
240                          -- Code Analysis preferences.                  do Result := classes_to_analyze end
241                  do Result := settings.preferences end  
242    feature {NONE} -- Implementation
243          class_list: ITERABLE [CLASS_C]  
244                          -- List of classes that have been added.          csv_file_name: STRING = "last_analysis_result.csv"
245                  do Result := classes_to_analyze end  
246            csv_header: STRING = "Severity;Class;Location;Title;Description;Rule ID;Severity Score"
247  feature {NONE} -- Implementation  
248            analysis_completed (a_exceptions: detachable ITERABLE [TUPLE [detachable EXCEPTION, CLASS_C]])
249          csv_file_name: STRING = "last_analysis_result.csv"                          -- Will be called when the analysis task has finished. `a_exceptions'
250                            -- contains a list of exception that occurred during analysis.
251          csv_header: STRING = "Severity;Class;Location;Title;Description;Rule ID;Severity Score"                  local
252                            l_csv_writer: CA_CSV_WRITER
253          analysis_completed (a_exceptions: detachable ITERABLE [TUPLE [detachable EXCEPTION, CLASS_C]])                  do
254                          -- Will be called when the analysis task has finished. `a_exceptions'                          create l_csv_writer.make (csv_file_name, csv_header)
255                          -- contains a list of exception that occurred during analysis.  
256                  local                          across rules as l_rules loop
257                          l_csv_writer: CA_CSV_WRITER                                  across l_rules.item.violations as l_v loop
258                  do                                                  -- Check the ignore list.
259                          create l_csv_writer.make (csv_file_name, csv_header)                                          if is_violation_valid (l_v.item) then
260                                                            -- Make sure a list for this class exists in the hash table:
261                          across rules as l_rules loop                                                  rule_violations.put (create {SORTED_TWO_WAY_LIST [CA_RULE_VIOLATION]}.make, l_v.item.affected_class)
262                                  across l_rules.item.violations as l_v loop                                                          -- Add the violation.
263                                                  -- Check the ignore list.                                                  rule_violations.at (l_v.item.affected_class).extend (l_v.item)
264                                          if is_violation_valid (l_v.item) then                                                          -- Log it.
265                                                          -- Make sure a list for this class exists in the hash table:                                                  l_csv_writer.add_line (l_v.item.csv_line)
266                                                  rule_violations.put (create {SORTED_TWO_WAY_LIST [CA_RULE_VIOLATION]}.make, l_v.item.affected_class)                                          end
267                                                          -- Add the violation.                                  end
268                                                  rule_violations.at (l_v.item.affected_class).extend (l_v.item)                          end
269                                                          -- Log it.  
270                                                  l_csv_writer.add_line (l_v.item.csv_line)                          l_csv_writer.close_file
271                                          end  
272                                  end                          clear_classes_to_analyze
273                          end  
274                            is_running := False
275                          l_csv_writer.close_file                          completed_actions.call ([a_exceptions])
276                            completed_actions.wipe_out
277                          clear_classes_to_analyze                  end
278    
279                          is_running := False          is_violation_valid (a_viol: attached CA_RULE_VIOLATION): BOOLEAN
280                          completed_actions.call ([a_exceptions])                          -- Is the violation `a_viol' valid under the current settings
281                          completed_actions.wipe_out                          -- such as the rule ignore list of a class, or the library or
282                  end                          -- non-library status of a class?
283                    local
284          is_violation_valid (a_viol: attached CA_RULE_VIOLATION): BOOLEAN                          l_affected_class: CLASS_C
285                          -- Is the violation `a_viol' valid under the current settings                          l_rule: CA_RULE
286                          -- such as the rule ignore list of a class, or the library or                  do
287                          -- non-library status of a class?                          l_affected_class := a_viol.affected_class
288                  local                          l_rule := a_viol.rule
289                          l_affected_class: CLASS_C  
290                          l_rule: CA_RULE                          Result := True
291                  do  
292                          l_affected_class := a_viol.affected_class                          if ignoredby.has (l_affected_class)
293                          l_rule := a_viol.rule                                                          and then (ignoredby.at (l_affected_class)).has (l_rule.id) then
294                                    Result := False
295                          Result := True                          end
296    
297                          if ignoredby.has (l_affected_class)                          if (not l_rule.checks_library_classes) and then library_class.at (l_affected_class) then
298                                                          and then (ignoredby.at (l_affected_class)).has (l_rule.id) then                                  Result := False
299                                  Result := False                          end
300                          end  
301                            if (not l_rule.checks_nonlibrary_classes) and then nonlibrary_class.at (l_affected_class) then
302                          if (not l_rule.checks_library_classes) and then library_class.at (l_affected_class) then                                  Result := False
303                                  Result := False                          end
304                          end                  end
305    
306                          if (not l_rule.checks_nonlibrary_classes) and then nonlibrary_class.at (l_affected_class) then          classes_to_analyze: LINKED_SET [CLASS_C]
307                                  Result := False                          -- List of classes that shall be analyzed.
308                          end  
309                  end          system_wide_check: BOOLEAN
310                            -- Shall the whole system be analyzed?
311          classes_to_analyze: LINKED_SET [CLASS_C]  
312                          -- List of classes that shall be analyzed.          completed_actions: ACTION_SEQUENCE [TUPLE [ITERABLE [TUPLE [detachable EXCEPTION, CLASS_C]]]]
313                            -- List of procedures to call when analysis has completed.
314          system_wide_check: BOOLEAN  
315                          -- Shall the whole system be analyzed?          frozen rota: detachable ROTA_S
316                            -- Accesses the rota service.
317          completed_actions: ACTION_SEQUENCE [TUPLE [ITERABLE [TUPLE [detachable EXCEPTION, CLASS_C]]]]                  local
318                          -- List of procedures to call when analysis has completed.                          l_service_consumer: SERVICE_CONSUMER [ROTA_S]
319                    do
320          frozen rota: detachable ROTA_S                          create l_service_consumer
321                          -- Accesses the rota service.                          if attached l_service_consumer.service as l_service and then l_service.is_interface_usable then
322                  local                                  Result := l_service
323                          l_service_consumer: SERVICE_CONSUMER [ROTA_S]                          end
324                  do                  end
325                          create l_service_consumer  
326                          if attached l_service_consumer.service as l_service and then l_service.is_interface_usable then          is_severity_enabled (a_severity: attached CA_RULE_SEVERITY): BOOLEAN
327                                  Result := l_service                  do
328                          end                          Result := (attached {CA_HINT} a_severity and settings.are_hints_enabled.value)
329                  end                                  or else (attached {CA_SUGGESTION} a_severity and settings.are_suggestions_enabled.value)
330                                    or else (attached {CA_WARNING} a_severity and settings.are_warnings_enabled.value)
331          is_severity_enabled (a_severity: attached CA_RULE_SEVERITY): BOOLEAN                                  or else (attached {CA_ERROR} a_severity and settings.are_errors_enabled.value)
332                  do                  end
333                          Result := (attached {CA_HINT} a_severity and settings.are_hints_enabled.value)  
334                                  or else (attached {CA_SUGGESTION} a_severity and settings.are_suggestions_enabled.value)          output_actions: ACTION_SEQUENCE [TUPLE [READABLE_STRING_GENERAL]]
335                                  or else (attached {CA_WARNING} a_severity and settings.are_warnings_enabled.value)                          -- Will be called whenever there is a message to output.
336                                  or else (attached {CA_ERROR} a_severity and settings.are_errors_enabled.value)  
337                  end  feature {NONE} -- Class-wide Options (From Indexing Clauses)
338    
339          output_actions: ACTION_SEQUENCE [TUPLE [READABLE_STRING_GENERAL]]          extract_indexes (a_class: attached CLASS_C)
340                          -- Will be called whenever there is a message to output.                          -- Extracts options from the indexing clause of class `a_class'.
341                    local
342  feature {NONE} -- Class-wide Options (From Indexing Clauses)                          l_ast: CLASS_AS
343                            l_ignoredby: LINKED_LIST [STRING_32]
344          extract_indexes (a_class: attached CLASS_C)                  do
345                          -- Extracts options from the indexing clause of class `a_class'.                          create l_ignoredby.make
346                  local                          l_ignoredby.compare_objects -- We want to compare the actual strings.
347                          l_ast: CLASS_AS                                  -- Reset the class flags.
348                          l_ignoredby: LINKED_LIST [STRING_32]                          library_class.force (False, a_class)
349                  do                          nonlibrary_class.force (False, a_class)
350                          create l_ignoredby.make                          l_ast := a_class.ast
351                          l_ignoredby.compare_objects -- We want to compare the actual strings.  
352                                  -- Reset the class flags.                          if attached l_ast.internal_top_indexes as l_top then
353                          library_class.force (False, a_class)                                  search_indexing_tags (l_top, a_class, l_ignoredby)
354                          nonlibrary_class.force (False, a_class)                          end
355                          l_ast := a_class.ast                          if attached l_ast.internal_bottom_indexes as l_bottom then
356                                    search_indexing_tags (l_bottom, a_class, l_ignoredby)
357                          if attached l_ast.internal_top_indexes as l_top then                          end
358                                  search_indexing_tags (l_top, a_class, l_ignoredby)  
359                          end                          ignoredby.force (l_ignoredby, a_class)
360                          if attached l_ast.internal_bottom_indexes as l_bottom then                  end
361                                  search_indexing_tags (l_bottom, a_class, l_ignoredby)  
362                          end          search_indexing_tags (a_clause: attached INDEXING_CLAUSE_AS; a_class: attached CLASS_C; a_ignoredby: attached LINKED_LIST [STRING_32])
363                            -- Searches `a_clause' for settings relevant to code analysis.
364                          ignoredby.force (l_ignoredby, a_class)                  local
365                  end                          l_item: STRING_32
366                    do
367          search_indexing_tags (a_clause: attached INDEXING_CLAUSE_AS; a_class: attached CLASS_C; a_ignoredby: attached LINKED_LIST [STRING_32])                          across a_clause as ic loop
368                          -- Searches `a_clause' for settings relevant to code analysis.                                  if ic.item.tag.name_32.is_equal ("ca_ignoredby") then
369                  local                                                  -- Class wants to ignore certain rules.
370                          l_item: STRING_32                                          across ic.item.index_list as l_list loop
371                  do                                                  l_item := l_list.item.string_value_32
372                          across a_clause as ic loop                                                  l_item.prune_all ('%"')
373                                  if ic.item.tag.name_32.is_equal ("ca_ignoredby") then                                                  a_ignoredby.extend (l_item)
374                                                  -- Class wants to ignore certain rules.                                          end
375                                          across ic.item.index_list as l_list loop                                  elseif ic.item.tag.name_32.is_equal ("ca_library") then
376                                                  l_item := l_list.item.string_value_32                                                  -- Class has information on whether it is a library class.
377                                                  l_item.prune_all ('%"')                                          if not ic.item.index_list.is_empty then
378                                                  a_ignoredby.extend (l_item)                                                  l_item := ic.item.index_list.first.string_value_32
379                                          end                                                  l_item.to_lower
380                                  elseif ic.item.tag.name_32.is_equal ("ca_library") then                                                  l_item.prune_all ('%"')
381                                                  -- Class has information on whether it is a library class.                                                  if l_item.is_equal ("true") then
382                                          if not ic.item.index_list.is_empty then                                                          library_class.force (True, a_class)
383                                                  l_item := ic.item.index_list.first.string_value_32                                                  elseif l_item.is_equal ("false") then
384                                                  l_item.to_lower                                                          nonlibrary_class.force (True, a_class)
385                                                  l_item.prune_all ('%"')                                                  end
386                                                  if l_item.is_equal ("true") then                                          end
387                                                          library_class.force (True, a_class)                                  end
388                                                  elseif l_item.is_equal ("false") then                          end
389                                                          nonlibrary_class.force (True, a_class)                  end
390                                                  end  
391                                          end          ignoredby: HASH_TABLE [LINKED_LIST [STRING_32], CLASS_C]
392                                  end                          -- Maps classes to lists of rules (rule IDs) the class wants to be ignored by.
393                          end  
394                  end          library_class, nonlibrary_class: HASH_TABLE [BOOLEAN, CLASS_C]
395                            -- Stores classes that are marked as library or non-library classes.
396          ignoredby: HASH_TABLE [LINKED_LIST [STRING_32], CLASS_C]  
397                          -- Maps classes to lists of rules (rule IDs) the class wants to be ignored by.  invariant
398            --      law_of_non_contradiction: one class must not be both a library_class and a nonlibrary_class
399          library_class, nonlibrary_class: HASH_TABLE [BOOLEAN, CLASS_C]  
400                          -- Stores classes that are marked as library or non-library classes.  end
   
 invariant  
         --      law_of_non_contradiction: one class must not be both a library_class and a nonlibrary_class  
   
 end  

Legend:
Removed from v.94982  
changed lines
  Added in v.94983

  ViewVC Help
Powered by ViewVC 1.1.23