Module: CodeModels::NavigationExtensions

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

Instance Method Summary collapse

Instance Method Details

#all_children(flag = nil) ⇒ Object



6
7
8
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
# File 'lib/codemodels/navigation.rb', line 6

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|
    #raise "Too many features with name #{ref.name}. Count: #{features_by_name(ref.name).count}" if features_by_name(ref.name).count!=1
    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



122
123
124
# File 'lib/codemodels/navigation.rb', line 122

def all_children_also_foreign
  all_children(:also_foreign)
end

#all_children_deep(flag = nil) ⇒ Object



35
36
37
38
39
40
41
42
43
44
# File 'lib/codemodels/navigation.rb', line 35

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



126
127
128
# File 'lib/codemodels/navigation.rb', line 126

def all_children_deep_also_foreign
  all_children_deep(:also_foreign)
end

#all_children_deep_of_type(flag = nil, type) ⇒ Object



90
91
92
# File 'lib/codemodels/navigation.rb', line 90

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



86
87
88
# File 'lib/codemodels/navigation.rb', line 86

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

#collect_values_with_countObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/codemodels/navigation.rb', line 61

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



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

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



106
107
108
109
110
111
112
113
114
115
# File 'lib/codemodels/navigation.rb', line 106

def container(flag=nil)
  # 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.
  also_foreign = (flag==:also_foreign)   
  if also_foreign && self.foreign_container
    return self.foreign_container
  else
    return self.eContainer
  end
end

#container_also_foreignObject



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

def container_also_foreign
  container(:also_foreign)
end

#only_child_deep_of_type(flag = nil, type) ⇒ Object



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

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



94
95
96
97
98
# File 'lib/codemodels/navigation.rb', line 94

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



117
118
119
120
# File 'lib/codemodels/navigation.rb', line 117

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

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



46
47
48
49
50
51
# File 'lib/codemodels/navigation.rb', line 46

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



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

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

#values_map(flags = nil) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/codemodels/navigation.rb', line 53

def values_map(flags=nil)
  if flags.include?(:deep)
    collect_values_with_count_subtree(flags[:also_foreign])
  else
    collect_values_with_count
  end
end