Class: RGen::ECore::ECoreToRuby

Inherits:
Object
  • Object
show all
Defined in:
lib/rgen/ecore/ecore_to_ruby.rb

Overview

ECoreToRuby can turn ECore models into their Ruby metamodel representations

Defined Under Namespace

Classes: EmptyConstantOrderHelper, FeatureWrapper

Instance Method Summary collapse

Constructor Details

#initializeECoreToRuby

Returns a new instance of ECoreToRuby.



11
12
13
14
15
16
# File 'lib/rgen/ecore/ecore_to_ruby.rb', line 11

def initialize
  @modules = {}
  @classifiers = {}
  @features_added = {}
  @reserved = Set.new(Object.methods)
end

Instance Method Details

#add_features(eclass) ⇒ Object



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/rgen/ecore/ecore_to_ruby.rb', line 240

def add_features(eclass)
  return false if @features_added[eclass]
  c = @classifiers[eclass]
  eclass.eStructuralFeatures.each do |f|
    w1 = FeatureWrapper.new(f, @classifiers) 
    w2 = FeatureWrapper.new(f.eOpposite, @classifiers) if f.is_a?(RGen::ECore::EReference) && f.eOpposite
    c.module_eval do
      if w1.many?
        _build_many_methods(w1, w2)
      else
        _build_one_methods(w1, w2)
      end
    end
  end
  @features_added[eclass] = true
  eclass.eSuperTypes.each do |t|
    add_features(t)
  end
  true
end

#create_module(epackage, under = Module.new) ⇒ Object

Create a Ruby module representing epackage. This includes all nested modules/packages, classes and enums.

If a parent module is provided with the “under” parameter, the new module will be nested under the parent module.

If the parent module has a non-temporary name, (more precisely: a non-temporary classpath) i.e. if it is reachable via a path of constant names from the root, then the nested modules and classes will also have non-temporary names. In particular, this means that they will keep their names even if they are assigned to new constants.

If no parent module is provided or the parent module has a temporary name by itself, then the nested modules and classes will also have temporary names. This means that their name will stay ‘volatile’ until they are assigned to constants reachable from the root and the Module#name method is called for the first time.

While the second approach is more flexible, it can come with a major performance impact. The reason is that Ruby searches the space of all known non-temporary classes/modules every time the name of a class/module with a temporary name is queried.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rgen/ecore/ecore_to_ruby.rb', line 42

def create_module(epackage, under=Module.new)
  with_empty_constant_order_helper do
    temp = under.to_s.start_with?("#")
    mod = create_module_internal(epackage, under, temp)

    epackage.eAllClassifiers.each do |c| 
      if c.is_a?(RGen::ECore::EClass)
        create_class(c, temp)
      elsif c.is_a?(RGen::ECore::EEnum)
        create_enum(c)
      end
    end

    load_classes_with_reserved_keywords(epackage)
    mod
  end
end