require 'rgen/transformer' require 'rgen/ecore/ecore' require 'concrete/metamodel/concrete_mmm' module Concrete module Metamodel class ECoreToConcrete < RGen::Transformer include RGen::ECore def initialize(env_in, env_out, opts={}) super @featureFilter = opts[:featureFilter] end def transform uniqueClassNameCheck trans(:class => EClass) end transform EClass, :to => ConcreteMMM::Class do { :name => name, :abstract => abstract, :features => trans(eStructuralFeatures.reject{ |f| (f.is_a?(RGen::ECore::EReference) && f.eOpposite && f.eOpposite.containment) || (@featureFilter && !@featureFilter.call(f)) }), :superTypes => trans(eSuperTypes) } end transform EStructuralFeature, :to => ConcreteMMM::Feature do if eType.is_a?(EDataType) && !eType.is_a?(EEnum) _type = primitiveType(eType) else _type = trans(eType) end { :name => name, :type => _type, :kind => (@current_object.is_a?(EAttribute) ? :attribute : (containment ? :containment : :reference)), :lowerLimit => lowerBound, :upperLimit => upperBound } end transform EEnum, :to => ConcreteMMM::Enum do { :name => name, :literals => eLiterals.collect{|l| l.name} } end def primitiveType(eType) @primitiveType ||= {} return @primitiveType[eType] if @primitiveType[eType] if eType == EString @primitiveType[eType] = @env_out.new(ConcreteMMM::Datatype, :name => "String") elsif eType == EInt @primitiveType[eType] = @env_out.new(ConcreteMMM::Datatype, :name => "Integer") elsif eType == EFloat @primitiveType[eType] = @env_out.new(ConcreteMMM::Datatype, :name => "Float") elsif eType == EBoolean @primitiveType[eType] = @env_out.new(ConcreteMMM::Datatype, :name => "Boolean") else # ignore unsupported datatype end end def uniqueClassNameCheck classNames = {} @env_in.find(:class => EClass).each do |c| raise "unqualified class names not unique, concrete does not support packages" if classNames[c.name] classNames[c.name] = true end end end end end