CA UI Implementation

Revision as of 08:28, 7 March 2014 by Stefan (Talk | contribs) (Graphical User Interface: Caching)

<< 7. Library Implementation |


Graphical User Interface

The classes of the graphical user interface of the code analyzer are all located in the interface cluster of EVE, in the subfolder graphical > tools > code_analysis. Here is a short overview of what the single classes do:

{ES_CODE_ANALYSIS_TOOL} 
Represents the code analysis GUI tool. Contains the tool title and icon, otherwise not much interesting stuff.
{ES_CODE_ANALYSIS_TOOL_PANEL} 
The graphical panel for the code analysis tool. It contains buttons, labels, the rule violations table view, and other user interface elements.
{ES_CODE_ANALYSIS_COMMAND} 
The command to launch the code analyzer. It can be added to toolbars and menus. It can be executed using stones. This class also handles the caching.
{ES_CODE_ANALYSIS_BENCH_HELPER} 
A helper class for the integration of the code analysis tool. It contains shared instances of {CA_CODE_ANALYZER} and {ES_CODE_ANALYSIS_COMMAND}, which are used by the GUI.
{ES_CA_SHOW_PREFERENCES_COMMAND} 
The command is used by the Preferences button in the panel.
{ES_CA_FIX_EXECUTOR} 
This class fixes a rule violation that has been found by the code analysis tool.

These are roughly the class relations for the code analysis GUI:

The most interesting class relations of the code analysis GUI.

Caching

It is a common case that GUI users run the code analyzer again after having made some changes to the code. We do not need to analyze the same unchanged code again and again. Therefore code analysis caches the results in memory. This only applies to the GUI mode.

Code analysis uses cached results exactly in one case: when the whole system is analyzed and the previous analysis was on the whole system, too.

The caching functionality is implemented in {ES_CODE_ANALYSIS_COMMAND}. When the command for analyzing the system is executed, the timestamps of the last modification of the classes are stored in analysis_timestamp : HASH_TABLE [INTEGER, CLASS_I] before the analysis. Note that the cached results (the rule violations) themselves are managed by {CA_CODE_ANALYZER}. The only difference to a non-cached analysis is that the rule violations are not deleted by {ES_CODE_ANALYSIS_COMMAND} before the next analysis. Then, in case the next command is also for analyzing the whole system, the current timestamps are compared to the stored timestamps. Any class that has been changed in the meantime will be analyzed again; for any unchanged class the rule violations are taken from the cache.

Command-line Interface

The whole command-line functionality of the code analyzer is located in the class {EWB_CODE_ANALYSIS}. It is located in the tty cluster of EVE. {EWB_CODE_ANALYSIS} is invoked by {ES}, the root class for the batch (command-line) version of EiffelStudio. In {ES}, the invocation looks as follows:

elseif option.is_equal ("-code-analysis") then
  l_at_args := arguments_in_range (current_option + 1, argument_count)
  current_option := argument_count + 1
  create {EWB_CODE_ANALYSIS} command.make_with_arguments (l_at_args)

Any command-line arguments after -code-analysis are passed on to {EWB_CODE_ANALYSIS}. This class, in its creation procedure, processes the arguments as described in Command Line Usage. Classes that were passed as command-line arguments are added to the analyzer. Then the actual execution happens in the procedure execute. EWB_CODE_ANALYSIS of course uses the code_analysis library and the previously described interface of CA_CODE_ANALYZER. After analysis a list of rule violations is output to the command-line. In the code it looks like this:

across l_code_analyzer.rule_violations as l_vlist loop
  if not l_vlist.item.is_empty then
    l_has_violations := True
      -- Always sort the rule violations by the class they are referring to.
    output_window.add (ca_messages.cmd_class + l_vlist.key.name + "':%N")
 
      -- See `{CA_RULE_VIOLATION}.is_less' for information on the sorting.
    across l_vlist.item as ic loop
      l_rule_name := ic.item.rule.title
      l_rule_id := ic.item.rule.id
      if attached ic.item.location as l_loc then
        l_line := ic.item.location.line.out
        l_col := ic.item.location.column.out
        output_window.add ("  (" + l_line + ":" + l_col + "): "
          + l_rule_name + " (" + l_rule_id + "): ")
      else -- No location attached. Print without location.
        output_window.add ("  "	+ l_rule_name + " (" + l_rule_id + "): ")
      end
      ic.item.format_violation_description (output_window)
      output_window.add ("%N")
    end
  end
end
 
if not l_has_violations then output_window.add (ca_messages.no_issues + "%N") end