Module: CodeModels::NavigationExtensions

Included in:
CodeModelsAstNode
Defined in:
lib/codemodels/navigation.rb

Overview

The flag :also_foreign deciced if to consider the AST of embedded code

Instance Method Summary collapse

Instance Method Details

#all_children(flag = nil) ⇒ Object

All direct children



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/codemodels/navigation.rb', line 9

def all_children(flag=nil)
  also_foreign = (flag==:also_foreign)
  arr = []
  ecore = self.class.ecore
  # Awful hack to forbid the same reference is visited twice when
  # two references with the same name are found
  already_used_references = []
  ecore.eAllReferences.sort_by{|r| r.name}.select {|r| r.containment}.each do |ref|
    unless already_used_references.include?(ref.name)
      res = self.send(ref.name.to_sym)
      if ref.many
        d = arr.count
        res.each do |el|
          arr << el unless res==nil
        end
      elsif res!=nil
        d = arr.count
        arr << res
      end
      already_used_references << ref.name
    end
  end
  if also_foreign
    arr.concat(self.foreign_asts)
  end
  arr
end

#all_children_also_foreignObject



135
136
137
# File 'lib/codemodels/navigation.rb', line 135

def all_children_also_foreign
  all_children(:also_foreign)
end

#all_children_deep(flag = nil) ⇒ Object

All direct and indirect children



38
39
40
41
42
43
44
45
46
47
# File 'lib/codemodels/navigation.rb', line 38

def all_children_deep(flag=nil)
  arr = []
  all_children(flag).each do |c|
    arr << c
    c.all_children_deep(flag).each do |cc|
      arr << cc
    end
  end      
  arr
end

#all_children_deep_also_foreignObject



139
140
141
# File 'lib/codemodels/navigation.rb', line 139

def all_children_deep_also_foreign
  all_children_deep(:also_foreign)
end

#all_children_deep_of_type(flag = nil, type) ⇒ Object



102
103
104
# File 'lib/codemodels/navigation.rb', line 102

def all_children_deep_of_type(flag=nil,type)
  all_children_deep(flag).select {|c| c and c.is_a?(type)}
end

#all_children_of_type(flag = nil, type) ⇒ Object



98
99
100
# File 'lib/codemodels/navigation.rb', line 98

def all_children_of_type(flag=nil,type)
  all_children(flag).select {|c| c and c.is_a?(type)}
end

#collect_values_with_countObject

Deprecated, use values_map instead



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/codemodels/navigation.rb', line 72

def collect_values_with_count
  values = Hash.new {|h,k| h[k]=0}
  self.class.ecore.eAllAttributes.each do |a|
    v = self.send(:"#{a.name}")
    if v!=nil
      if a.many
        v.each {|el| values[el]+=1}
      else
        values[v]+=1
      end
    end
  end
  values     
end

#collect_values_with_count_subtree(flag = nil) ⇒ Object

Deprecated, use values_map instead



88
89
90
91
92
93
94
95
96
# File 'lib/codemodels/navigation.rb', line 88

def collect_values_with_count_subtree(flag=nil)
  values = collect_values_with_count
  all_children_deep(flag).each do |c|
    c.collect_values_with_count.each do |k,v|
      values[k]+=v
    end
  end
  values
end

#container(flag = nil) ⇒ Object

Parent of the node. A foreign child could have its own parent in the foreign ast, which is not part of the complexive AST the foreign parent has therefore the precedence.



121
122
123
124
125
126
127
128
# File 'lib/codemodels/navigation.rb', line 121

def container(flag=nil)
  also_foreign = (flag==:also_foreign)   
  if also_foreign && self.foreign_container
    return self.foreign_container
  else
    return self.eContainer
  end
end

#container_also_foreignObject

Deprecated



149
150
151
# File 'lib/codemodels/navigation.rb', line 149

def container_also_foreign
  container(:also_foreign)
end

#only_child_deep_of_type(flag = nil, type) ⇒ Object



112
113
114
115
116
# File 'lib/codemodels/navigation.rb', line 112

def only_child_deep_of_type(flag=nil,type)
  selected = all_children_deep_of_type(flag,type)
  raise "Exactly one child of type #{type} expected, #{selected.count} found on #{self}" unless selected.count==1
  selected[0]
end

#only_child_of_type(flag = nil, type) ⇒ Object



106
107
108
109
110
# File 'lib/codemodels/navigation.rb', line 106

def only_child_of_type(flag=nil,type)
  selected = all_children_of_type(flag,type)
  raise "Exactly one child of type #{type} expected, #{selected.count} found on #{self}" unless selected.count==1
  selected[0]
end

#root(flag = nil) ⇒ Object



130
131
132
133
# File 'lib/codemodels/navigation.rb', line 130

def root(flag=nil)
  return self unless self.container(flag)
  self.container(flag).root(flag)
end

#traverse(flag = nil, &op) ⇒ Object

Execute an operation on the node itself and all children, direct and indirect.



51
52
53
54
55
56
# File 'lib/codemodels/navigation.rb', line 51

def traverse(flag=nil,&op)
  op.call(self)
  all_children_deep(flag).each do |c|
    op.call(c)
  end
end

#traverse_also_foreign(&block) ⇒ Object

Deprecated



144
145
146
# File 'lib/codemodels/navigation.rb', line 144

def traverse_also_foreign(&block)
  traverse(:also_foreign,&block)
end

#values_map(flags = nil) ⇒ Object

All the values considering the node, and the direct and indirect children (if :deep is contained in flags). In that case the presence of :also_foreign determine if also embedded ASTs are considrered



62
63
64
65
66
67
68
69
# File 'lib/codemodels/navigation.rb', line 62

def values_map(flags=nil)
  raise ":also_foreign makes sense only when :deep is used" if flags.include?(:also_foreign) && !flags.include?(:deep)
  if flags.include?(:deep)
    collect_values_with_count_subtree(flags.include?(:also_foreign)?(:also_foreign):nil)
  else
    collect_values_with_count
  end
end