class RedParse::ListInNode::MethodNode

Attributes

empty_else[R]
empty_ensure[R]

Public Class Methods

namelist() click to toggle source
# File lib/redparse/node.rb, line 4801
def self.namelist
  %w[receiver name args body rescues elses ensures]
end
new(defword,header,maybe_eq_,semi_, body,rescues,else_,ensure_,endword_) click to toggle source
# File lib/redparse/node.rb, line 4769
      def initialize(defword,header,maybe_eq_,semi_,
                     body,rescues,else_,ensure_,endword_)
        @offset=defword.offset
        @empty_else=@empty_ensure=nil
#        if DotCallNode===header
#          header=header.data[1]
#        end
        if CallSiteNode===header
          @parens=header.has_parens?
          receiver=header.receiver
          args=header.args
          header=header.name
        end
        if MethNameToken===header
          header=header.ident 
        end
        unless String===header
          fail "unrecognized method header: #{header}"
        end
        if else_
          else_=else_.val  or @empty_else=true
        end
        if ensure_
          ensure_=ensure_.val or @empty_ensure=true
        end
        args.extend ListInNode if args
        rescues.extend ListInNode if rescues
        replace [receiver,header,args,body,rescues,else_,ensure_]
      end

Public Instance Methods

else_=(x) click to toggle source
# File lib/redparse/node.rb, line 4821
def else_= x
  self[6]=x      
end
ensure_=(x) click to toggle source

def receiver= x

self[0]=x

end

def body= x

self[3]=x

end

# File lib/redparse/node.rb, line 4817
def ensure_= x
  self[5]=x      
end
has_parens?() click to toggle source
# File lib/redparse/node.rb, line 4805
def has_parens?; 
  @parens if defined? @parens
end
image() click to toggle source
# File lib/redparse/node.rb, line 4825
def image
  "(def #{receiver.image.+('.') if receiver}#{name})"
end
parsetree(o) click to toggle source
# File lib/redparse/node.rb, line 4854
def parsetree(o)
  name=name()
  name=name.chop if /^[!~]@$/===name
  name=name.to_sym

  result=[name, target=[:scope, [:block, ]] ]
  if receiver
    result.unshift :defs, receiver.rescue_parsetree(o)
  else
    result.unshift :defn
  end

  goodies= (body or !rescues.empty? or elses or ensures or @empty_ensure) # or args())

  if unamp=args() and unamp=unamp.last and UnOpNode===unamp and unamp.op=="&@"
    receiver and goodies=true
  else 
    unamp=false
  end

  if receiver and !goodies
    target.delete_at 1 #omit :block
  else
    target=target[1]
  end

  target.push args=[:args,]
  target.push unamp.parsetree(o) if unamp

  if args()
    initvals=[]
    args().each{|arg| 
        case arg
            when VarNode
              args.push arg.ident.to_sym
            when UnaryStarNode
              args.push "*#{arg.val.ident}".to_sym
            when UnOpNode
              nil
            when AssignNode
              initvals << arg.parsetree(o)
              initvals[-1][-1]=arg.right.rescue_parsetree(o) #ugly
              args.push arg[0].ident.to_sym
            else 
              fail "unsupported node type in method param list: #{arg}"
        end
    }
    unless initvals.empty?
      initvals.unshift(:block) 
      args << initvals
      #args[-2][0]==:block_arg and target.push args.delete_at(-2)
    end
  end
  target.push [:nil] if !goodies && !receiver

  #it would be better to use parsetree_and_rescues for the rest of this method,
  #just to be DRYer

  target.push ensuretarget=target=[:ensure, ] if ensures or @empty_ensure
  #simple dup won't work... won't copy extend'd modules
  #should use clone here
  body=Marshal.load(Marshal.dump(body())) if body()
  elses=elses()
  if rescues.empty?
    case body
    when SequenceNode; body << elses;elses=nil
    when nil; body=elses;elses=nil
    else nil
    end if elses
  else
    target.push target=[:rescue, ] 
    elses=elses()
  end
  if body
    if BeginNode===body||RescueOpNode===body and 
      body.rescues.empty? and !body.ensure and !body.empty_ensure and body.body and body.body.size>1
        wantblock=true
    end
    if o[:quirks]
      first=body
      first=first.first if SequenceNode===first
      wantblock=true if UndefNode===first and first.size>1
    end
    body=body.parsetree(o)
    if body.first==:block and rescues.empty? and not ensures||@empty_ensure
      if wantblock
        target.push body
      else
        body.shift 
        target.concat body
      end
    else
      #body=[:block, *body] if wantblock
      target.push body
    end
  end
  target.push linked_list(rescues.map{|rescue_| rescue_.parsetree(o) }) unless rescues.empty?
  target.push elses.parsetree(o) if elses
  ensuretarget.push ensures.parsetree(o) if ensures
  ensuretarget.push [:nil] if @empty_ensure

  return result
end
to_lisp() click to toggle source
# File lib/redparse/node.rb, line 4849
def to_lisp
  "(imethod #{name} is\n#{body.to_lisp}\n)\n"
  #no receiver, args, rescues, else_ or ensure_...
end
unparse(o=default_unparse_options) click to toggle source
# File lib/redparse/node.rb, line 4829
      def unparse o=default_unparse_options
        result=[
         "def ",receiver&&receiver.unparse(o)+'.',name, has_parens? ? '(' : ' ', 
           args&&args.map{|arg| arg.unparse o}.join(','), 
         (')' if has_parens?), unparse_nl(body||self,o)
        ]
        result<<unparse_and_rescues(o)
=begin
        body&&result+=body.unparse(o)

        result+=rescues.map{|resc| resc.unparse o}.to_s 
        result+="else #{else_.unparse o}\n"  if else_
        result+="else\n" if @empty_else
        result+="ensure #{ensure_.unparse o}\n"  if ensure_
        result+="ensure\n" if @empty_ensure
=end
        result<<unparse_nl(endline,o)+"end"
        result.join
      end