class ADSL::Parser::ASTClass

Public Instance Methods

to_adsl() click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 322
def to_adsl
  par_name = @parent_name.nil? ? "" : "extends #{@parent_name.text} "
  "class #{ @name.text } #{ par_name }{\n#{ @relations.map(&:to_adsl).adsl_indent }}\n"
end
typecheck_and_resolve(context) click to toggle source
# File lib/adsl/parser/ast_nodes.rb, line 286
def typecheck_and_resolve(context)
  klass = context.classes[@name.text][1]
  @relations.each do |rel_node|
    rel = context.relations[@name.text][rel_node.name.text][1]
    klass.relations << rel
    
    if rel_node.cardinality[0] > rel_node.cardinality[1]
      raise ADSLError, "Invalid cardinality of relation #{klass.name}.#{rel_node.name.text} on line #{rel_node.cardinality[2]}: minimum cardinality #{rel_node.cardinality[0]} must not be greater than the maximum cardinality #{rel_node.cardinality[1]}"
    end
    if rel_node.cardinality[1] == 0
      raise ADSLError, "Invalid cardinality of relation #{klass.name}.#{rel_node.name.text} on line #{rel_node.cardinality[2]}: maximum cardinality #{rel_node.cardinality[1]} must be positive"
    end
    unless context.classes.include? rel_node.to_class_name.text
      raise ADSLError, "Unknown class name #{rel_node.to_class_name.text} in relation #{klass.name}.#{rel_node.name.text} on line #{rel_node.to_class_name.lineno}"
    end

    rel.to_class = context.classes[rel_node.to_class_name.text][1]
    rel.cardinality = rel_node.cardinality
    if rel_node.inverse_of_name
      target_class = context.classes[rel.to_class.name][1]
      inverse_of_node, inverse_of = context.relations[target_class.name][rel_node.inverse_of_name.text]

      while inverse_of_node.nil?
        inverse_of_node, inverse_of = context.relations[target_class.name][rel_node.inverse_of_name.text]
        target_class = target_class.parent
        raise ADSLError, "Unknown relation to which #{rel.from_class.name}.#{rel.name} relation is inverse to: #{rel.to_class.name}.#{rel_node.inverse_of_name.text} on line #{rel_node.inverse_of_name.lineno}" if target_class.nil?
      end

      if inverse_of_node.inverse_of_name
        raise ADSLError, "Relation #{rel.from_class.name}.#{rel.name} cannot be inverse to an inverse relation #{rel.to_class.name}.#{rel_node.inverse_of_name.text} on line #{rel_node.inverse_of_name.lineno}"
      end
      rel.inverse_of = inverse_of
    end
  end
end