Class: RedParse::CallSiteNode

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

Direct Known Subclasses

CallNode, KWCallNode

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

Instance Method Summary collapse

Methods inherited from ValueNode

#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, #lvars_defined_in, #merge_replacement_session, namelist, #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(*args) ⇒ CallSiteNode

Returns a new instance of CallSiteNode.



3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
# File 'lib/redparse/node.rb', line 3070

def initialize(*args)
  if KeywordToken===args.first and args.first.ident=='('
    method,open_paren,param_list,close_paren,block="()",*args
    parened=open_paren
  else 
    method,open_paren,param_list,close_paren,block=*args
    @not_real_parens=!open_paren || open_paren.not_real?
  end

  if KeywordToken===method and method.ident=='->'
    if SequenceNode===param_list
      blockparams,blocklocals,* = param_list
      if CommaOpNode===blocklocals
        blocklocals=Array(blocklocals)
      else
        blocklocals=[blocklocals]
      end
      blocklocals.map!{|bl| bl.ident}
      blocklocals.extend ListInNode
    else
      blockparams= param_list
    end

    if CommaOpNode===blockparams
      blockparams=Array(blockparams)
    elsif blockparams
      blockparams=[blockparams]
    end

    blockparams=BlockParams.new blockparams if blockparams
    param_list=nil
  end

  case param_list
  when CommaOpNode
    #handle inlined hash pairs in param list (if any)
#          compr=Object.new
#          def compr.==(other) ArrowOpNode===other end
    h,arrowrange=param_list.extract_unbraced_hash
    param_list=Array.new(param_list)
    param_list[arrowrange]=[h] if arrowrange
  
  when ArrowOpNode
    h=HashLiteralNode.new(nil,param_list,nil)
    h.startline=param_list.startline
    h.endline=param_list.endline
    param_list=[h]
#        when KeywordOpNode
#          fail "didn't expect '#{param_list.inspect}' inside actual parameter list"
  when nil
  else
    param_list=[param_list]
  end

  param_list.extend ListInNode if param_list

  if block
    @do_end=block.do_end
    blockparams||=block.params
    blocklocals||=block.locals
    block=block.body #||[]
  end
  if Token===method 
    @offset=method.offset
    method=method.ident
    fail unless String===method
  else
    @offset=parened&&parened.offset
  end

  super(nil,method,param_list,blockparams,blocklocals,block)
  #receiver, if any, is tacked on later
end

Instance Attribute Details

#lvalueObject



3193
3194
3195
3196
# File 'lib/redparse/node.rb', line 3193

def lvalue
  return @lvalue if defined? @lvalue
  @lvalue=true
end

Instance Method Details

#blockformals_parsetree(data, o) ⇒ Object

dead code?



3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
# File 'lib/redparse/node.rb', line 3331

def blockformals_parsetree data,o  #dead code?
  data.empty? and return nil 
  data=data.dup
  star=data.pop if UnaryStarNode===data.last
  result=data.map{|x| x.parsetree(o) }
=begin
 {          if VarNode===x
      ident=x.ident
      ty=x.varname2assigntype
#            ty==:lasgn and ty=:dasgn_curr
      [ty, ident.to_sym] 
    else
      x=x.parsetree(o)
      if x[0]==:call
        x[0]=:attrasgn
        x[2]="#{x[2]}=".to_sym
      end
      x
    end
  }
=end
  if result.size==0
    star or fail
    result=[:masgn, star.parsetree(o).last]
  elsif result.size==1 and !star
    result=result.first
  else
    result=[:masgn, [:array, *result]]
    if star 
      old=star= star.val
      star=star.parsetree(o)
      if star[0]==:call
        star[0]=:attrasgn
        star[2]="#{star[2]}=".to_sym
      end

      if VarNode===old
        ty=old.varname2assigntype
#              ty==:lasgn and ty=:dasgn_curr
        star[0]=ty
      end
      result.push star
    end
  end
  result
end

#imageObject



3175
3176
3177
# File 'lib/redparse/node.rb', line 3175

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

#lvalue_parsetree(o) ⇒ Object

identity_param :with_commas, false, true



3186
3187
3188
3189
3190
3191
# File 'lib/redparse/node.rb', line 3186

def lvalue_parsetree(o)
  result=parsetree(o)
  result[0]=:attrasgn
  result[2]="#{result[2]}=".to_sym
  result
end

#parsetree(o) ⇒ Object



3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
# File 'lib/redparse/node.rb', line 3280

def parsetree(o)
  callsite=parsetree_with_params o
  return callsite unless blockparams or block
  call=name
  callsite[0]=:fcall  if callsite[0]==:call or callsite[0]==:vcall
  unless receiver
    case call
    when "BEGIN"
      if o[:quirks]
        return []
      else
        callsite=[:preexe] 
      end
    when "END"; callsite=[:postexe]
    end
  else
    callsite[0]=:call if callsite[0]==:fcall
  end

  if blockparams
    bparams=blockparams.dup
    lastparam=bparams.last
    amped=bparams.pop.val if UnOpNode===lastparam and lastparam.op=="&@"
    bparams=bparams.parsetree(o)||0
    if amped
      bparams=[:masgn, [:array, bparams]] unless bparams==0 or bparams.first==:masgn
      bparams=[:block_pass, amped.lvalue_parsetree(o), bparams]
    end
  else
    bparams=nil
  end
  result=[:iter, callsite, bparams]
  unless block.empty?
    body=block.parsetree(o)
    if curr_vars=block.lvars_defined_in
      curr_vars-=blockparams.all_current_lvars if blockparams
      if curr_vars.empty?
        result.push body
      else
        curr_vars.map!{|cv| [:dasgn_curr, cv.to_sym] }
        (0...curr_vars.size-1).each{|i| curr_vars[i]<<curr_vars[i+1] }
        #body.first==:block ? body.shift : body=[body]
        result.push((body)) #.unshift curr_vars[0]))
      end
    else
      result.push body
    end
  end 
  result
end

#parsetree_with_params(o) ⇒ Object



3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
# File 'lib/redparse/node.rb', line 3212

def parsetree_with_params o
  args=args()||[]
  if (UnOpNode===args.last and args.last.ident=="&@")
    lasti=args.size-2
    unamp_expr=args.last.val
  else
    lasti=args.size-1
  end
  methodname= name
  methodname= methodname.chop if /^[~!]@$/===methodname
  methodsym=methodname.to_sym
  is_kw= RubyLexer::FUNCLIKE_KEYWORDS&~/^(BEGIN|END|raise)$/===methodname

  result=
  if lasti==-1
    [(@not_real_parens and /[!?]$/!~methodname and !unamp_expr) ? 
       :vcall : :fcall, methodsym
    ]
  elsif (UnaryStarNode===args[lasti])
    if lasti.zero?
      [:fcall, methodsym, args.first.rescue_parsetree(o)]
    else
      [:fcall, methodsym, 
       [:argscat, 
         [:array, *args[0...lasti].map{|x| x.rescue_parsetree(o) } ], 
            args[lasti].val.rescue_parsetree(o) 
       ]
      ]
    end         
  else
    singlearg= lasti.zero?&&args.first
    [:fcall, methodsym, 
     [:array, *args[0..lasti].map{|x| x.rescue_parsetree(o) } ]
    ]
  end

  result[0]=:vcall if block #and /\Af?call\Z/===result[0].to_s

  if is_kw and !receiver
    if singlearg and "super"!=methodname
      result=[methodsym, singlearg.parsetree(o)]
      result.push(true) if methodname=="yield" and ArrayLiteralNode===singlearg #why???!!
      return result
    end
    breaklike=  /^(break|next|return)$/===methodname
    if @not_real_parens
        return [:zsuper] if "super"==methodname and !args()
    else
        return [methodsym, [:nil]] if breaklike and args.size.zero?
    end
    result.shift 
    arg=result[1]
    result[1]=[:svalue,arg] if arg and arg[0]==:splat and breaklike
  end

  if receiver
    result.shift if result.first==:vcall or result.first==:fcall #if not kw
    result=[:call, receiver.rescue_parsetree(o), *result]
  end

  if unamp_expr
#          result[0]=:fcall if lasti.zero?
    result=[:block_pass, unamp_expr.rescue_parsetree(o), result]
  end

  return result
end

#real_parensObject Also known as: has_parens?



3144
# File 'lib/redparse/node.rb', line 3144

def real_parens; @not_real_parens||=nil; !@not_real_parens end

#real_parens=(x) ⇒ Object



3145
# File 'lib/redparse/node.rb', line 3145

def real_parens= x; @not_real_parens=!x end

#reducer_identObject



17390
17391
17392
# File 'lib/redparse/ReduceWithsFor_RedParse_1_9.rb', line 17390

def reducer_ident
  :CallSiteNode
end

#set_receiver!(expr) ⇒ Object



3208
3209
3210
# File 'lib/redparse/node.rb', line 3208

def set_receiver!(expr)
  self[0]=expr
end

#to_lispObject



3201
3202
3203
# File 'lib/redparse/node.rb', line 3201

def to_lisp
  "(#{receiver.to_lisp} #{self[1..-1].map{|x| x.to_lisp}.join(' ')})"
end

#unparse(o = default_unparse_options) ⇒ Object



3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
# File 'lib/redparse/node.rb', line 3148

def unparse o=default_unparse_options
  fail if block==false
  parensadded=[false]
  params=params()
  params&&=params.map{|param|  
    unparse_nl(param,o,'',"\\\n")+param.unparse_maybe_parens(o,parensadded)  
  }.join(', ')
  real_parens=real_parens() || parensadded[0]
  result=[
   receiver&&receiver.unparse(o)+'.',
   name=='()' ? '' : name,
   real_parens ? '(' : (' ' if params),
   params,
   real_parens ? ')' : nil,
  
   block&&[
     @do_end ? " do " : "{", 
       block_params&&block_params.unparse(o),
       unparse_nl(block,o," "),
       block.unparse(o),
       unparse_nl(endline,o),
     @do_end ? " end" : "}"
   ]
  ]
  return result.join
end

#with_commasObject



3179
3180
3181
3182
# File 'lib/redparse/node.rb', line 3179

def with_commas
   !real_parens and 
   args and args.size>0
end