/[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 93177 by zurfluhs, Mon Oct 28 22:16:38 2013 UTC revision 93475 by zurfluhs, Wed Nov 20 16:09:46 2013 UTC
# Line 9  class Line 9  class
9    
10  inherit {NONE}  inherit {NONE}
11          SHARED_EIFFEL_PROJECT          SHARED_EIFFEL_PROJECT
12            CA_SHARED_NAMES
13    
14  create  create
15          make          make
# Line 18  feature {NONE} -- Initialization Line 19  feature {NONE} -- Initialization
19          make          make
20                          -- Initialization for `Current'.                          -- Initialization for `Current'.
21                  do                  do
22                          create settings                          create settings.make
23                          create rules.make                          create rules.make
24                          -- Adding example rules                          -- Adding example rules
25                          rules.extend (create {CA_SELF_ASSIGNMENT_RULE}.make)                          rules.extend (create {CA_SELF_ASSIGNMENT_RULE}.make)
26                          rules.extend (create {CA_UNUSED_ARGUMENT_RULE}.make)                          rules.extend (create {CA_UNUSED_ARGUMENT_RULE}.make)
27                            rules.extend (create {CA_NPATH_RULE}.make)
28                            rules.extend (create {CA_EMPTY_IF_RULE}.make)
29                            rules.extend (create {CA_FEATURE_NEVER_CALLED_RULE}.make)
30                            rules.extend (create {CA_CQ_SEPARATION_RULE}.make)
31                            rules.extend (create {CA_UNNEEDED_OT_LOCAL_RULE}.make)
32                            rules.extend (create {CA_UNNEEDED_OBJECT_TEST_RULE}.make)
33                            rules.extend (create {CA_NESTED_COMPLEXITY_RULE}.make)
34    
35                            -- Issues (contract violations, exceptions) with {EPA_CFG_BUILDER} and
36                            -- classes from library 'program_analysis' in general.
37    --                      rules.extend (create {CA_VARIABLE_NOT_READ_RULE}.make)
38    
39                          create classes_to_analyze.make                          create classes_to_analyze.make
40                          create rule_violations.make (100)                          create rule_violations.make (100)
41                            create completed_actions
42    
43                            create ignoredby.make (25)
44                            create library_class.make (25)
45                            create nonlibrary_class.make (25)
46                  end                  end
47    
48  feature -- Analysis interface  feature -- Analysis interface
49    
50            add_completed_action (a_action: PROCEDURE [ANY, TUPLE [BOOLEAN] ])
51                    do
52                            completed_actions.extend (a_action)
53                    end
54    
55          analyze          analyze
56                    require
57                            not is_running
58                  local                  local
59                          l_rules_checker: CA_ALL_RULES_CHECKER                          l_rules_checker: CA_ALL_RULES_CHECKER
60                            l_task: CA_RULE_CHECKING_TASK
61                  do                  do
62                            is_running := True
63                                    -- TODO: caching
64                            rule_violations.wipe_out
65    
66                          create l_rules_checker.make                          create l_rules_checker.make
67                          across rules as l_rules loop                          across rules as l_rules loop
68                                    l_rules.item.clear_violations
69                                  if l_rules.item.is_enabled then -- important: only add enabled rules                                  if l_rules.item.is_enabled then -- important: only add enabled rules
70                                          if system_wide_check or else (not l_rules.item.is_system_wide) then                                          if system_wide_check or else (not l_rules.item.is_system_wide) then
71                                                  -- do not add system wide rules if we check only parts of the system                                                          -- do not add system wide rules if we check only parts of the system
72                                                  l_rules.item.prepare_checking (l_rules_checker)                                                  if attached {CA_STANDARD_RULE} l_rules.item as l_std_rule then
                                         end  
                                 end  
                         end  
   
                         across classes_to_analyze as l_classes loop  
73    
74                                  -- TODO: more elegant and performant solution?                                                          l_std_rule.prepare_checking (l_rules_checker)
75                                  across rules as l_rules loop                                                                  -- TODO: prepare rules of other types?
76                                          l_rules.item.set_checking_class (l_classes.item)                                                  end
77                                  end                                          end
   
                                 l_rules_checker.run_on_class (l_classes.item)  
   
                                 rule_violations.extend (create {SORTED_TWO_WAY_LIST[CA_RULE_VIOLATION]}.make, l_classes.item)  
                         end  
   
                         across rules as l_rules loop  
                                 across l_rules.item.violations as l_v loop  
                                         rule_violations.at (l_v.item.affected_class).extend (l_v.item)  
78                                  end                                  end
79                          end                          end
80    
81                          clear_classes_to_analyze                          create l_task.make (l_rules_checker, rules, classes_to_analyze, agent analysis_completed)
82                  ensure                          rota.run_task (l_task)
                         violation_list_exists: analysis_successful implies rule_violations /= Void  
83                  end                  end
84    
85          clear_classes_to_analyze          clear_classes_to_analyze
# Line 123  feature -- Analysis interface Line 138  feature -- Analysis interface
138                          end                          end
139                  end                  end
140    
141            add_group (a_group: CONF_GROUP)
142                    require
143                            a_group_not_void: a_group /= Void
144                    local
145                            l_conf_class: CONF_CLASS
146                            l_class_i: CLASS_I
147                    do
148                            from
149                                    a_group.classes.start
150                            until
151                                    a_group.classes.after
152                            loop
153                                    l_conf_class := a_group.classes.item_for_iteration
154                                    l_class_i := eiffel_universe.class_named (l_conf_class.name, a_group)
155                                    add_class (l_class_i)
156                                    a_group.classes.forth
157                            end
158                    end
159    
160          add_classes (a_classes: ITERABLE[CLASS_I])          add_classes (a_classes: ITERABLE[CLASS_I])
161                  do                  do
162                          system_wide_check := False                          system_wide_check := False
# Line 141  feature -- Analysis interface Line 175  feature -- Analysis interface
175                          if a_class.is_compiled then                          if a_class.is_compiled then
176                                  l_class_c := a_class.compiled_class                                  l_class_c := a_class.compiled_class
177                                  check l_class_c /= Void end                                  check l_class_c /= Void end
                                 print ("Analyzing class " + a_class.name + "...%N")  
178                                  classes_to_analyze.extend (l_class_c)                                  classes_to_analyze.extend (l_class_c)
179    
180                                    extract_indexes (l_class_c)
181                          else                          else
182                                  print ("Class " + a_class.name + " not compiled (skipped).%N")                                  print ("Class " + a_class.name + " not compiled (skipped).%N")
183                          end                          end
# Line 150  feature -- Analysis interface Line 185  feature -- Analysis interface
185    
186  feature -- Properties  feature -- Properties
187    
188            is_running: BOOLEAN
189    
190          analysis_successful: BOOLEAN          analysis_successful: BOOLEAN
191    
192          rules: LINKED_LIST[CA_RULE]          rules: LINKED_LIST[CA_RULE]
193    
194          rule_violations: detachable HASH_TABLE[SORTED_TWO_WAY_LIST[CA_RULE_VIOLATION], CLASS_C]          rule_violations: detachable HASH_TABLE[SORTED_TWO_WAY_LIST[CA_RULE_VIOLATION], CLASS_C]
195    
196            preferences: PREFERENCES
197                    do Result := settings.preferences end
198    
199  feature {NONE} -- Implementation  feature {NONE} -- Implementation
200    
201            analysis_completed
202                    do
203                            across classes_to_analyze as l_classes loop
204                                    rule_violations.extend (create {SORTED_TWO_WAY_LIST[CA_RULE_VIOLATION]}.make, l_classes.item)
205                            end
206    
207                            across rules as l_rules loop
208                                    across l_rules.item.violations as l_v loop
209                                                    -- check the ignore list
210                                            if is_violation_valid (l_v.item) then
211                                                    rule_violations.at (l_v.item.affected_class).extend (l_v.item)
212                                            end
213                                    end
214                            end
215    
216                            clear_classes_to_analyze
217    
218                            is_running := False
219                            completed_actions.call ([True])
220                            completed_actions.wipe_out
221                    end
222    
223            is_violation_valid (a_viol: CA_RULE_VIOLATION): BOOLEAN
224                    local
225                            l_affected_class: CLASS_C
226                            l_rule: CA_RULE
227                    do
228                            l_affected_class := a_viol.affected_class
229                            l_rule := a_viol.rule
230    
231                            Result := True
232    
233                            if (ignoredby.has (l_affected_class))
234                                                            and then (ignoredby.at (l_affected_class)).has (l_rule.id) then
235                                    Result := False
236                            end
237    
238                            if (not l_rule.checks_library_classes) and then library_class.at (l_affected_class) = True then
239                                    Result := False
240                            end
241    
242                            if (not l_rule.checks_nonlibrary_classes) and then nonlibrary_class.at (l_affected_class) = True then
243                                    Result := False
244                            end
245                    end
246    
247          settings: CA_SETTINGS          settings: CA_SETTINGS
248    
249          classes_to_analyze: LINKED_SET[CLASS_C]          classes_to_analyze: LINKED_SET [CLASS_C]
250    
251          system_wide_check: BOOLEAN          system_wide_check: BOOLEAN
252    
253            completed_actions: ACTION_SEQUENCE [TUPLE [BOOLEAN]]
254    
255            frozen rota: detachable ROTA_S
256                            -- Access to rota service
257                    local
258                            l_service_consumer: SERVICE_CONSUMER [ROTA_S]
259                    do
260                            create l_service_consumer
261                            if l_service_consumer.is_service_available and then l_service_consumer.service.is_interface_usable then
262                                    Result := l_service_consumer.service
263                            end
264                    end
265    
266    
267    feature {NONE} -- Class-wide Options (From Indexing Clauses)
268    
269            extract_indexes (a_class: CLASS_C)
270                    local
271                            l_ast: CLASS_AS
272                            l_item: STRING_32
273                            l_ignoredby: LINKED_LIST [STRING_32]
274                    do
275                            create l_ignoredby.make
276                            l_ignoredby.compare_objects
277                            library_class.force (False, a_class)
278                            nonlibrary_class.force (False, a_class)
279                            l_ast := a_class.ast
280    
281                            across l_ast.internal_top_indexes as l_indexes loop
282    
283                                    if l_indexes.item.tag.name_32.is_equal ("ca_ignoredby") then
284                                            across l_indexes.item.index_list as l_list loop
285                                                    l_item := l_list.item.string_value_32
286                                                    l_item.prune_all ('%"')
287                                                    l_ignoredby.extend (l_item)
288                                            end
289                                    elseif l_indexes.item.tag.name_32.is_equal ("ca_library") then
290                                            if not l_indexes.item.index_list.is_empty then
291                                                    l_item := l_indexes.item.index_list.first.string_value_32
292                                                    l_item.to_lower
293                                                    l_item.prune_all ('%"')
294                                                    if l_item.is_equal ("true") then
295                                                            library_class.force (True, a_class)
296                                                    elseif l_item.is_equal ("false") then
297                                                            nonlibrary_class.force (True, a_class)
298                                                    end
299                                            end
300                                    end
301                            end
302    
303                            ignoredby.force (l_ignoredby, a_class)
304                    end
305    
306            ignoredby: HASH_TABLE [LINKED_LIST [STRING_32], CLASS_C]
307    
308            library_class, nonlibrary_class: HASH_TABLE [BOOLEAN, CLASS_C]
309    
310    invariant
311    --      law_of_non_contradiction: one class must not be both a library_class and a nonlibrary_class
312    
313  end  end

Legend:
Removed from v.93177  
changed lines
  Added in v.93475

  ViewVC Help
Powered by ViewVC 1.1.23