class Atomy::MessageStructure

Public Class Methods

new(node) click to toggle source
# File lib/atomy/message_structure.rb, line 45
def initialize(node)
  @node = node
end

Public Instance Methods

arguments() click to toggle source
# File lib/atomy/message_structure.rb, line 56
def arguments
  pre, defaults, post, splat = arguments_from(argument_list_from(@node))
  pre
end
block() click to toggle source
# File lib/atomy/message_structure.rb, line 74
def block
  block_from(@node)
end
default_arguments() click to toggle source
# File lib/atomy/message_structure.rb, line 78
def default_arguments
  pre, defaults, post, splat = arguments_from(argument_list_from(@node))
  defaults
end
name() click to toggle source
# File lib/atomy/message_structure.rb, line 49
def name
  # don't treat sole constant as message send
  raise unknown_message if @node.is_a?(Atomy::Grammar::AST::Constant)

  name_from(@node)
end
post_arguments() click to toggle source
# File lib/atomy/message_structure.rb, line 83
def post_arguments
  pre, defaults, post, splat = arguments_from(argument_list_from(@node))
  post
end
proc_argument() click to toggle source
# File lib/atomy/message_structure.rb, line 70
def proc_argument
  proc_argument_from(@node)
end
receiver() click to toggle source
# File lib/atomy/message_structure.rb, line 66
def receiver
  receiver_from(@node)
end
splat_argument() click to toggle source
# File lib/atomy/message_structure.rb, line 61
def splat_argument
  pre, defaults, post, splat = arguments_from(argument_list_from(@node))
  splat
end

Private Instance Methods

argument_list_from(node) click to toggle source
# File lib/atomy/message_structure.rb, line 172
def argument_list_from(node)
  case node
  when Grammar::AST::Apply
    return node.arguments
  when Grammar::AST::Infix
    return [node.right]
  when Grammar::AST::Compose
    case node.right
    when Grammar::AST::Prefix # proc argument
      return argument_list_from(node.left)
    when Grammar::AST::Word, Grammar::AST::Constant, Grammar::AST::Apply # has a receiver
      return argument_list_from(node.right)
    when Grammar::AST::Block # block literal argument
      case node.left
      when Grammar::AST::Compose
        case node.left.right
        when Grammar::AST::List # block args; skip
          return argument_list_from(node.left.left)
        else
          return argument_list_from(node.left)
        end
      else
        return argument_list_from(node.left)
      end
    when Grammar::AST::List # foo[bar]
      return node.right.nodes
    end
  end

  []
end
arguments_from(list) click to toggle source
# File lib/atomy/message_structure.rb, line 143
def arguments_from(list)
  pre = []
  defaults = []
  post = []
  splat = nil

  list.each do |a|
    if a.is_a?(Grammar::AST::Infix) && a.operator == :"="
      if splat || !post.empty?
        raise unknown_message
      end

      defaults << DefaultArgument.new(a.left, a.right)
    elsif a.is_a?(Grammar::AST::Prefix) && a.operator == :"*"
      if splat || !post.empty?
        raise unknown_message
      end

      splat = a.node
    elsif splat || !defaults.empty?
      post << a
    else
      pre << a
    end
  end

  [pre, defaults, post, splat]
end
block_from(node) click to toggle source
# File lib/atomy/message_structure.rb, line 253
def block_from(node)
  case node
  when Grammar::AST::Compose
    blk = nil

    case node.right
    when Grammar::AST::Block
      blk = BlockArgument.new(node.right.nodes)
    else
      return
    end

    case node.left
    when Grammar::AST::Compose
      case node.left.right
      when Grammar::AST::List
        return BlockArgument.new(blk.body, node.left.right.nodes)
      end
    end

    return blk
  end
end
name_from(node) click to toggle source
# File lib/atomy/message_structure.rb, line 94
def name_from(node)
  case node
  when Grammar::AST::Word, Grammar::AST::Constant
    return node.text
  when Grammar::AST::Apply
    return name_from(node.node)
  when Grammar::AST::Infix
    return node.operator
  when Grammar::AST::Postfix
    case node.operator
    when :"!", :"?"
      case node.node
      when Grammar::AST::Word, Grammar::AST::Constant
        return :"#{node.node.text}#{node.operator}"
      end
    end
  when Grammar::AST::Prefix
    return :"#{node.operator}@"
  when Grammar::AST::Compose
    case node.right
    when Grammar::AST::Prefix # proc argument
      return name_from(node.left)
    when Grammar::AST::Word, Grammar::AST::Constant, Grammar::AST::Apply # has a receiver
      return name_from(node.right)
    when Grammar::AST::Postfix
      case node.right.operator
      when :"!", :"?"
        return name_from(node.right)
      end
    when Grammar::AST::Block # block literal argument
      case node.left
      when Grammar::AST::Compose
        case node.left.right
        when Grammar::AST::List # block args; skip
          return name_from(node.left.left)
        else
          return name_from(node.left)
        end
      else
        return name_from(node.left)
      end
    when Grammar::AST::List # foo[bar]
      return :[]
    end
  end

  raise unknown_message
end
proc_argument_from(node) click to toggle source
# File lib/atomy/message_structure.rb, line 204
def proc_argument_from(node)
  case node
  when Grammar::AST::Compose
    case node.right
    when Grammar::AST::Prefix
      if node.right.operator == :"&" # proc argument
        return node.right.node
      end
    end
  end
end
receiver_from(node) click to toggle source
# File lib/atomy/message_structure.rb, line 216
def receiver_from(node)
  case node
  when Grammar::AST::Infix
    return node.left
  when Grammar::AST::Compose
    case node.right
    when Grammar::AST::Word, Grammar::AST::Constant, Grammar::AST::Apply
      return node.left
    when Grammar::AST::Postfix
      case node.right.operator
      when :"!", :"?"
        return node.left
      end
    when Grammar::AST::Block # block literal argument
      case node.left
      when Grammar::AST::Compose
        case node.left.right
        when Grammar::AST::List # block args; skip
          return receiver_from(node.left.left)
        else
          return receiver_from(node.left)
        end
      else
        return receiver_from(node.left)
      end
    when Grammar::AST::List
      return node.left
    when Grammar::AST::Prefix
      if node.right.operator == :"&" # proc argument
        return receiver_from(node.left)
      end
    end
  when Grammar::AST::Prefix
    return node.node
  end
end
unknown_message() click to toggle source
# File lib/atomy/message_structure.rb, line 90
def unknown_message
  UnknownMessageStructure.new(@node)
end