/[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 93168 by zurfluhs, Thu Oct 24 19:43:13 2013 UTC revision 93428 by zurfluhs, Tue Nov 19 13:09:13 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 23  feature {NONE} -- Initialization Line 24  feature {NONE} -- Initialization
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    
34                            -- Issues (contract violations, exceptions) with {EPA_CFG_BUILDER} and
35                            -- classes from library 'program_analysis' in general.
36    --                      rules.extend (create {CA_VARIABLE_NOT_READ_RULE}.make)
37    
38                            create classes_to_analyze.make
39                            create rule_violations.make (100)
40                            create completed_actions
41    
42                            create ignoredby.make (25)
43                            create library_class.make (25)
44                            create nonlibrary_class.make (25)
45                  end                  end
46    
47  feature  feature -- Analysis interface
48    
49          analyze_system          add_completed_action (a_action: PROCEDURE [ANY, TUPLE [BOOLEAN] ])
50                    do
51                            completed_actions.extend (a_action)
52                    end
53    
54            analyze
55                    require
56                            not is_running
57                  local                  local
58                          l_groups: LIST [CONF_GROUP]                          l_rules_checker: CA_ALL_RULES_CHECKER
59                          l_cluster: CLUSTER_I                          l_task: CA_RULE_CHECKING_TASK
60                  do                  do
61                          create rules_checker.make                          is_running := True
62                                    -- TODO: caching
63                            rule_violations.wipe_out
64    
65                            create l_rules_checker.make
66                          across rules as l_rules loop                          across rules as l_rules loop
67                                    l_rules.item.clear_violations
68                                  if l_rules.item.is_enabled then -- important: only add enabled rules                                  if l_rules.item.is_enabled then -- important: only add enabled rules
69                                          rules_checker.add_rule_checker (l_rules.item.rule_checker)                                          if system_wide_check or else (not l_rules.item.is_system_wide) then
70                                                            -- do not add system wide rules if we check only parts of the system
71                                                    if attached {CA_STANDARD_RULE} l_rules.item as l_std_rule then
72    
73                                                            l_std_rule.prepare_checking (l_rules_checker)
74                                                                    -- TODO: prepare rules of other types?
75                                                    end
76                                            end
77                                  end                                  end
78                          end                          end
79    
80                            create l_task.make (l_rules_checker, rules, classes_to_analyze, agent analysis_completed)
81                            rota.run_task (l_task)
82                    end
83    
84            clear_classes_to_analyze
85                    do
86                            classes_to_analyze.wipe_out
87                    end
88    
89            add_whole_system
90                    local
91                            l_groups: LIST [CONF_GROUP]
92                            l_cluster: CLUSTER_I
93                    do
94                          from                          from
95                                  l_groups := eiffel_universe.groups                                  l_groups := eiffel_universe.groups
96                                  l_groups.start                                  l_groups.start
# Line 48  feature Line 100  feature
100                                  l_cluster ?= l_groups.item_for_iteration                                  l_cluster ?= l_groups.item_for_iteration
101                                          -- Only load top-level clusters, as they are loaded recursively afterwards                                          -- Only load top-level clusters, as they are loaded recursively afterwards
102                                  if l_cluster /= Void and then l_cluster.parent_cluster = Void then                                  if l_cluster /= Void and then l_cluster.parent_cluster = Void then
103                                          analyze_cluster (l_cluster)                                          add_cluster (l_cluster)
104                                  end                                  end
105                                  l_groups.forth                                  l_groups.forth
106                          end                          end
107    
108                          analysis_successful := rules_checker.last_run_successful                          system_wide_check := True
                         if analysis_successful then  
                                 rule_violations := rules_checker.last_result  
                         end  
                 ensure  
                         violation_list_exists: analysis_successful implies rule_violations /= Void  
109                  end                  end
110    
111          analyze_cluster (a_cluster: CLUSTER_I)          add_cluster (a_cluster: CLUSTER_I)
112                  local                  local
113                          l_conf_class: CONF_CLASS                          l_conf_class: CONF_CLASS
114                          l_class_i: CLASS_I                          l_class_i: CLASS_I
115                  do                  do
116                            system_wide_check := False
117    
118                          from                          from
119                                  a_cluster.classes.start                                  a_cluster.classes.start
120                          until                          until
# Line 73  feature Line 122  feature
122                          loop                          loop
123                                  l_conf_class := a_cluster.classes.item_for_iteration                                  l_conf_class := a_cluster.classes.item_for_iteration
124                                  l_class_i := eiffel_universe.class_named (l_conf_class.name, a_cluster)                                  l_class_i := eiffel_universe.class_named (l_conf_class.name, a_cluster)
125                                  analyze_class_if_compiled (l_class_i)                                  add_class (l_class_i)
126                                  a_cluster.classes.forth                                  a_cluster.classes.forth
127                          end                          end
128                          if a_cluster.sub_clusters /= Void then                          if a_cluster.sub_clusters /= Void then
# Line 82  feature Line 131  feature
131                                  until                                  until
132                                          a_cluster.sub_clusters.after                                          a_cluster.sub_clusters.after
133                                  loop                                  loop
134                                          analyze_cluster (a_cluster.sub_clusters.item_for_iteration)                                          add_cluster (a_cluster.sub_clusters.item_for_iteration)
135                                          a_cluster.sub_clusters.forth                                          a_cluster.sub_clusters.forth
136                                  end                                  end
137                          end                          end
138                  end                  end
139    
140          analyze_classes (classes: LINKED_LIST[CLASS_AS])          add_group (a_group: CONF_GROUP)
141                    require
142                            a_group_not_void: a_group /= Void
143                    local
144                            l_conf_class: CONF_CLASS
145                            l_class_i: CLASS_I
146                  do                  do
147                            from
148                  ensure                                  a_group.classes.start
149                          violation_list_exists: analysis_successful implies rule_violations /= Void                          until
150                                    a_group.classes.after
151                            loop
152                                    l_conf_class := a_group.classes.item_for_iteration
153                                    l_class_i := eiffel_universe.class_named (l_conf_class.name, a_group)
154                                    add_class (l_class_i)
155                                    a_group.classes.forth
156                            end
157                  end                  end
158    
159          analyze_class (a_class_to_analyze: CLASS_AS)          add_classes (a_classes: ITERABLE[CLASS_I])
160                  do                  do
161                          create rules_checker.make                          system_wide_check := False
162                          across rules as l_rules loop  
163                                  if l_rules.item.is_enabled then -- important: only add enabled rules                          across a_classes as l_classes loop
164                                          rules_checker.add_rule_checker (l_rules.item.rule_checker)                                  add_class (l_classes.item)
                                 end  
165                          end                          end
166                    end
167    
168            add_class (a_class: CLASS_I)
169                    local
170                            l_class_c: CLASS_C
171                    do
172                            system_wide_check := False
173    
174                            if a_class.is_compiled then
175                                    l_class_c := a_class.compiled_class
176                                    check l_class_c /= Void end
177                                    classes_to_analyze.extend (l_class_c)
178    
179                          rules_checker.run_on_class (a_class_to_analyze)                                  extract_indexes (l_class_c)
180                          analysis_successful := rules_checker.last_run_successful                          else
181                          if analysis_successful then                                  print ("Class " + a_class.name + " not compiled (skipped).%N")
                                 rule_violations := rules_checker.last_result  
182                          end                          end
                 ensure  
                         violation_list_exists: analysis_successful implies rule_violations /= Void  
183                  end                  end
184    
185  feature  feature -- Properties
186    
187            is_running: BOOLEAN
188    
189          analysis_successful: BOOLEAN          analysis_successful: BOOLEAN
190    
191          rules: LINKED_LIST[CA_RULE]          rules: LINKED_LIST[CA_RULE]
192    
193          rule_violations: detachable LINKED_LIST[CA_RULE_VIOLATION]          rule_violations: detachable HASH_TABLE[SORTED_TWO_WAY_LIST[CA_RULE_VIOLATION], CLASS_C]
194    
195  feature {NONE} -- Implementation  feature {NONE} -- Implementation
196    
197            analysis_completed
198                    do
199                            across classes_to_analyze as l_classes loop
200                                    rule_violations.extend (create {SORTED_TWO_WAY_LIST[CA_RULE_VIOLATION]}.make, l_classes.item)
201                            end
202    
203                            across rules as l_rules loop
204                                    across l_rules.item.violations as l_v loop
205                                                    -- check the ignore list
206                                            if is_violation_valid (l_v.item) then
207                                                    rule_violations.at (l_v.item.affected_class).extend (l_v.item)
208                                            end
209                                    end
210                            end
211    
212                            clear_classes_to_analyze
213    
214                            is_running := False
215                            completed_actions.call ([True])
216                            completed_actions.wipe_out
217                    end
218    
219            is_violation_valid (a_viol: CA_RULE_VIOLATION): BOOLEAN
220                    local
221                            l_affected_class: CLASS_C
222                            l_rule: CA_RULE
223                    do
224                            l_affected_class := a_viol.affected_class
225                            l_rule := a_viol.rule
226    
227                            Result := True
228    
229                            if (ignoredby.has (l_affected_class))
230                                                            and then (ignoredby.at (l_affected_class)).has (l_rule.id) then
231                                    Result := False
232                            end
233    
234                            if (not l_rule.checks_library_classes) and then library_class.at (l_affected_class) = True then
235                                    Result := False
236                            end
237    
238                            if (not l_rule.checks_nonlibrary_classes) and then nonlibrary_class.at (l_affected_class) = True then
239                                    Result := False
240                            end
241                    end
242    
243          settings: CA_SETTINGS          settings: CA_SETTINGS
244    
245          analyze_class_if_compiled (a_class: CLASS_I)          classes_to_analyze: LINKED_SET [CLASS_C]
246    
247            system_wide_check: BOOLEAN
248    
249            completed_actions: ACTION_SEQUENCE [TUPLE [BOOLEAN]]
250    
251            frozen rota: detachable ROTA_S
252                            -- Access to rota service
253                  local                  local
254                          l_class_c: CLASS_C                          l_service_consumer: SERVICE_CONSUMER [ROTA_S]
255                  do                  do
256                          if a_class.is_compiled then                          create l_service_consumer
257                                  l_class_c := a_class.compiled_class                          if l_service_consumer.is_service_available and then l_service_consumer.service.is_interface_usable then
258                                  check l_class_c /= Void end                                  Result := l_service_consumer.service
259                                  print ("Analyzing class " + a_class.name + "...%N")                          end
260                                  rules_checker.run_on_class (l_class_c.ast)                  end
261                          else  
262                                  print ("Class " + a_class.name + " not compiled (skipped).%N")  
263    feature {NONE} -- Class-wide Options (From Indexing Clauses)
264    
265            extract_indexes (a_class: CLASS_C)
266                    local
267                            l_ast: CLASS_AS
268                            l_item: STRING
269                            l_ignoredby: LINKED_LIST [STRING]
270                    do
271                            create l_ignoredby.make
272                            l_ignoredby.compare_objects
273                            library_class.force (False, a_class)
274                            nonlibrary_class.force (False, a_class)
275                            l_ast := a_class.ast
276    
277                            across l_ast.internal_top_indexes as l_indexes loop
278    
279                                    if l_indexes.item.tag.name_8.is_equal ("ca_ignoredby") then
280                                            across l_indexes.item.index_list as l_list loop
281                                                    l_item := l_list.item.string_value_32
282                                                    l_item.prune_all ('%"')
283                                                    l_ignoredby.extend (l_item)
284                                            end
285                                    elseif l_indexes.item.tag.name_8.is_equal ("ca_library") then
286                                            if not l_indexes.item.index_list.is_empty then
287                                                    l_item := l_indexes.item.index_list.first.string_value_32
288                                                    l_item.to_lower
289                                                    l_item.prune_all ('%"')
290                                                    if l_item.is_equal ("true") then
291                                                            library_class.force (True, a_class)
292                                                    elseif l_item.is_equal ("false") then
293                                                            nonlibrary_class.force (True, a_class)
294                                                    end
295                                            end
296                                    end
297                          end                          end
298    
299                            ignoredby.force (l_ignoredby, a_class)
300                  end                  end
301    
302          rules_checker: CA_ALL_RULES_CHECKER          ignoredby: HASH_TABLE [LINKED_LIST [STRING], CLASS_C]
303    
304            library_class, nonlibrary_class: HASH_TABLE [BOOLEAN, CLASS_C]
305    
306    invariant
307    --      law_of_non_contradiction: one class must not be both a library_class and a nonlibrary_class
308    
309  end  end

Legend:
Removed from v.93168  
changed lines
  Added in v.93428

  ViewVC Help
Powered by ViewVC 1.1.23