Class: RedParse::MethodNode

Inherits:
ValueNode show all
Includes:
HasRescue
Defined in:
lib/redparse/node.rb,
lib/redparse/ripper.rb,
lib/redparse/ReduceWithsFor_RedParse_1_9.rb,
lib/redparse/ReduceWithsFor_RedParse_1_8.rb

Constant Summary

Constants included from FlattenedIvars

FlattenedIvars::EXCLUDED_IVARS

Instance Attribute Summary collapse

Attributes inherited from Node

#endline, #errors, #offset, #parent, #startline

Attributes included from Stackable::Meta

#boolean_identity_params, #identity_params

Class Method Summary collapse

Instance Method Summary collapse

Methods included from HasRescue

#parsetree_and_rescues, #unparse_and_rescues

Methods inherited from ValueNode

#lvalue, #reducer_method

Methods inherited from Node

#+, #+@, #==, [], #[]=, #add_parent_links!, #args_rip, #begin_parsetree, #classic_inspect, create, #data, #deep_copy, #delete_extraneous_ivars!, #delete_linenums!, #depthwalk, #depthwalk_nodes, #error?, #evalable_inspect, #fixup_multiple_assignments!, #fixup_rescue_assignments!, #force_stmt_list_rip, #initialize_ivars, inline_symbols, #inspect, #lhs_unparse, #linerange, #lvalue, #lvars_defined_in, #merge_replacement_session, #negate, #original_brackets_assign, param_names, #parsetrees, #pretty_print, #prohibit_fixup, #replace_ivars_and_self, #replace_value, #rescue_parsetree, #rfind, #rfind_all, #rgrep, #rip_and_rescues, #rip_explode!, #short_inspect, #stmts_rip, #to_parsetree, #to_parsetree_and_warnings, #to_ruby, #to_s, #unary, #walk, #xform_tree!

Methods included from Stackable::Meta

#build_exemplars, #enumerate_exemplars, #identity_param

Methods included from FlattenedIvars

#flattened_ivars, #flattened_ivars_equal?

Methods included from Stackable

#identity_name

Constructor Details

#initialize(defword, header, maybe_eq_, semi_, body, rescues, else_, ensure_, endword_) ⇒ MethodNode

Returns a new instance of MethodNode.



4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
# 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

Instance Attribute Details

#empty_elseObject (readonly)

Returns the value of attribute empty_else.



4799
4800
4801
# File 'lib/redparse/node.rb', line 4799

def empty_else
  @empty_else
end

#empty_ensureObject (readonly)

Returns the value of attribute empty_ensure.



4799
4800
4801
# File 'lib/redparse/node.rb', line 4799

def empty_ensure
  @empty_ensure
end

Class Method Details

.namelistObject



4801
4802
4803
# File 'lib/redparse/node.rb', line 4801

def self.namelist
  %w[receiver name args body rescues elses ensures]
end

Instance Method Details

#else_=(x) ⇒ Object



4821
4822
4823
# File 'lib/redparse/node.rb', line 4821

def else_= x
  self[6]=x      
end

#ensure_=(x) ⇒ Object

def receiver= x

  self[0]=x      
end

def body= x
  self[3]=x      
end


4817
4818
4819
# File 'lib/redparse/node.rb', line 4817

def ensure_= x
  self[5]=x      
end

#get_while(params, should_be) ⇒ Object



289
290
291
292
293
294
295
# File 'lib/redparse/ripper.rb', line 289

def get_while params,should_be
  param=nil
  result=[]
  result<<yield( param )while should_be===params.first and param=params.shift
ensure
  return result unless result.empty?
end

#has_parens?Boolean

Returns:

  • (Boolean)


4805
4806
4807
# File 'lib/redparse/node.rb', line 4805

def has_parens?; 
  @parens if defined? @parens
end

#imageObject



4825
4826
4827
# File 'lib/redparse/node.rb', line 4825

def image
  "(def #{receiver.image.+('.') if receiver}#{name})"
end

#parsetree(o) ⇒ Object



4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
# 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

#reducer_identObject



17350
17351
17352
# File 'lib/redparse/ReduceWithsFor_RedParse_1_9.rb', line 17350

def reducer_ident
  :MethodNode
end

#rip(p) ⇒ Object



297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/redparse/ripper.rb', line 297

def rip p
  params=args ? args.dup : []
  params2=[]
  #param=nil

  params2.push get_while(params,VarNode){|param| p.on_ident param.name}
  params2.push get_while(params,AssignNode){|param| [p.on_ident(param.left.name), param.right.rip(p)]}
  get_while(params,UnaryStarNode){|param| params2.push p.on_rest_param p.on_ident param.val.name; break }
  params2.push get_while(params,VarNode){|param| p.on_ident param.name}
  get_while(params,UnaryAmpNode){|param| params2.push p.on_blockarg p.on_ident param.val.name; break }

  params=p.on_params( *params2 )
  params=p.on_paren( params ) if has_parens?

  result=[p.on_ident(name), params, rip_and_rescues(p)]
  result.unshift receiver.rip(p), p.on_period(".") if receiver
  p.on_def( *result )
end

#to_lispObject



4849
4850
4851
4852
# 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) ⇒ Object



4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
# 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