use base ("Understand::Graph::Gv"); use Understand; use Understand::VariableTracker; use strict; # The name of the graph for the menu system sub name { return "Variable Tracker"; } sub description { return "Understand the impact of a variable."; } # Indicate this graph is only available for objects # A return value of -1 means the report is never available for entities sub test_entity { my $ent = shift; if($ent->kind()->check("Object,Parameter,Enumerator")) { return 1; } return 0; } # Indicate this graph is never available as a global graph. sub test_global { my $db = shift; return -1; } sub define_options {} # Indicate this graph does not support the abort method. # return 1 if it is not supported sub support_abort { return 0; } # Abort method. my $Abort=0; sub abort { $Abort = 1; } sub getGuiPosition { if(!Understand::Gui::active()) { return (undef, 0, 0); } my ($file, $line, $column) = (Understand::Gui::file(), Understand::Gui::line(), Understand::Gui::column()); # ::file() method doesn't always work. if(!$file) { my $db = Understand::Gui::db(); my @ents = $db->lookup(Understand::Gui::filename(), "File", 1); if(@ents == 1) { $file = $ents[0]; } } return ($file, $line, $column); } my $nodeId; sub init { my $graph = shift; my $entity = shift; $graph->options->define("Depth",["1","2","3","4","5"],"3"); $nodeId=0; return; } sub do_load { my $graph = shift; my $entity = shift; Understand::VariableTracker::init_all(); my $defRef = $entity->ref("definein, body declarein"); my ($g_file, $g_line, $g_column); if ($defRef){ $g_file = $defRef->file; $g_line = $defRef->line; $g_column = $defRef->column; }else{ ($g_file, $g_line, $g_column) = getGuiPosition(); } my $max_depth = $graph->options->lookup("Depth"); my $root = Understand::VariableTracker::build_tree($entity, $g_file, $g_line, $g_column, $max_depth); draw_tree($graph, $root); return; } sub draw_tree{ my ($graph, # the graph we are building the impact in $root, # the entity associated with the "current node" ) = @_; my $g_node = $graph->node($nodeId++, $root->{'text'}); $g_node->sync($root->{'file'}, $root->{'line'}, $root->{'column'}); draw_tree_aux($graph, $g_node, $root); } sub draw_tree_aux{ my ($graph, $g_node, $node) = @_; foreach my $edge (@{$node->{'right_edges'}}) { my $right_node = $edge->{'right'}; my $n = $graph->node($nodeId++, $right_node->{'text'}); $n->sync($right_node->{'file'}, $right_node->{'line'}, $right_node->{'column'}); my $ref = $edge->{'reference'}; my $e = $graph->edge($g_node, $n, $ref->kindname(), $ref); $e->sync($edge->{'file'}, $edge->{'line'}, $edge->{'column'}); draw_tree_aux($graph, $n, $right_node); } }