Class: RedParse::AssignNode

Inherits:
ValueNode show all
Defined in:
lib/redparse/node.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

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 inherited from ValueNode

#lvalue, #reducer_method

Methods inherited from Node

#+, #+@, #==, [], #[]=, #add_parent_links!, #args_rip, #begin_parsetree, #classic_inspect, #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, 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) ⇒ AssignNode

Returns a new instance of AssignNode.



2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
# File 'lib/redparse/node.rb', line 2351

def initialize(*args)

  if args.size==5
    #this branch should be dead now
    if args[3].ident=="rescue3"
      lhs,op,rescuee,op2,rescuer=*args
      if MULTIASSIGN===lhs or rescuee.is_list?
        huh
      else
        rhs=RescueOpNode.new(rescuee.val,op2,rescuer)
      end
    else
      lhs=args.shift
      op=args.shift
      args.shift #bogus1
      rhs=args.shift
    end
  else
    lhs,op,rhs=*args
    rhs=rhs.val if AssignmentRhsNode===rhs
  end
  case lhs
  when UnaryStarNode         #look for star on lhs
    lhs=MultiAssign.new([lhs]) unless lhs.after_comma
  when ParenedNode
    if !lhs.after_comma      #look for () around lhs
      if CommaOpNode===lhs.first
        lhs=MultiAssign.new(Array.new(lhs.first))
        @lhs_parens=true
      elsif UnaryStarNode===lhs.first
        lhs=MultiAssign.new([lhs.first])
        @lhs_parens=true
      elsif ParenedNode===lhs.first
        @lhs_parens=true
        lhs=lhs.first
      else
        lhs=lhs.first
      end
    end
  when CommaOpNode
    lhs=MultiAssign.new lhs
    #rhs=Array.new(rhs) if CommaOpNode===rhs
  end 

  if CommaOpNode===rhs
    rhs=Array.new(rhs)
    lhs=MultiAssign.new([lhs]) unless MultiAssign===lhs
  end

  op=op.ident

  if Array==rhs.class
    rhs.extend ListInNode
  end

  @offset=lhs.offset
  return super(lhs,op,rhs)  
  #punting, i hope the next layer can handle += and the like

=begin
  #in theory, we should do something more sophisticated, like this:
  #(but the presence of side effects in lhs will screw it up)
  if op=='='
    super
  else
    super(lhs,OpNode.new(lhs,OperatorToken.new(op.chomp('=')),rhs))
  end
=end
end

Class Method Details

.create(*args) ⇒ Object



2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
# File 'lib/redparse/node.rb', line 2334

def self.create(*args)
  if args.size==5
    if args[3].ident=="rescue3"
      lhs,op,rescuee,op2,rescuer=*args
      if MULTIASSIGN===lhs or !rescuee.is_list
        return RescueOpNode.new(AssignNode.new(lhs,op,rescuee),nil,rescuer)
      else
        rhs=RescueOpNode.new(rescuee.val,op2,rescuer)
      end
      super(lhs,op,rhs)
    else
      super(args[0],args[1],args[3])
    end
  else super
  end
end

Instance Method Details

#all_current_lvarsObject



2450
2451
2452
2453
# File 'lib/redparse/node.rb', line 2450

def all_current_lvars
  left.respond_to?(:all_current_lvars) ?
    left.all_current_lvars : []
end

#imageObject



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

def image; '(=)' end

#multi?Boolean

Returns:

  • (Boolean)


2421
2422
2423
# File 'lib/redparse/node.rb', line 2421

def multi?
  MultiAssign===left
end

#parsetree(o) ⇒ Object



2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
# File 'lib/redparse/node.rb', line 2455

def parsetree(o)
  case left
  when ParenedNode; huh
  when RescueOpNode; huh
  when BeginNode; huh
  when ConstantNode;
    left.lvalue_parsetree(o) << right.parsetree(o)

  when MultiAssign;
  lhs=left.lvalue_parsetree(o)
  rhs= right.class==Array ? right.dup : [right]
  star=rhs.pop if UnaryStarNode===rhs.last
  rhs=rhs.map{|x| x.rescue_parsetree(o)}
  if rhs.size==0
    star or fail
    rhs= star.parsetree(o)
  elsif rhs.size==1 and !star and !(UnaryStarNode===left.first)
    rhs.unshift :to_ary
  else
    rhs.unshift(:array) 
    if star
      splat=star.val.rescue_parsetree(o)
      #if splat.first==:call #I don't see how this can be right....
      #  splat[0]=:attrasgn
      #  splat[2]="#{splat[2]}=".to_sym
      #end
      rhs=[:argscat, rhs, splat] 
    end
    if left.size==1 and !(UnaryStarNode===left.first) and !(NestedAssign===left.first)
      rhs=[:svalue, rhs]
      if CallNode===left.first
        rhs=[:array, rhs]
      end
    end
  end
  if left.size==1 and BracketsGetNode===left.first and right.class==Array #hack
    lhs.last<<rhs
    lhs
  else
    lhs<< rhs
  end

  when CallSiteNode
  op=op().chomp('=')
  rcvr=left.receiver.parsetree(o)
  prop=left.name.+('=').to_sym
  args=right.rescue_parsetree(o)
  UnaryStarNode===right and args=[:svalue, args]
  if op.empty?
    [:attrasgn, rcvr, prop, [:array, args] ]
  else
    [:op_asgn2, rcvr,prop,  op.to_sym, args]
  end

  when BracketsGetNode
  args=left.params
  if op()=='='
    result=left.lvalue_parsetree(o) #[:attrasgn, left[0].parsetree(o), :[]=]
    result.size==3 and result.push [:array]
    rhs=right.rescue_parsetree(o)
    UnaryStarNode===right and rhs=[:svalue, rhs]
    if args 
      result[-1]=[:argspush,result[-1]] if UnaryStarNode===args.last
    #else result[-1]=[:zarray]
    end
    result.last << rhs
    result            
    
  else
=begin
    args&&=args.map{|x| x.parsetree(o)}.unshift(:array)
    splat=args.pop if :splat==args.last.first
    if splat and left.params.size==1
      args=splat
    elsif splat
      args=[:argscat, args, splat.last]
    end
=end
    lhs=left.parsetree(o)
    if lhs.first==:fcall
      rcvr=[:self]
      args=lhs[2]
    else
      rcvr=lhs[1]
      args=lhs[3]
    end
    args||=[:zarray]
    result=[
      :op_asgn1, rcvr, args,
      op().chomp('=').to_sym, 
      right.rescue_parsetree(o)
    ]
  end

  when VarNode
  node_type=left.varname2assigntype
  if /^(&&|\|\|)=$/===op()
    
    return ["op_asgn_#{$1[0]==?& ? "and" : "or"}".to_sym, 
            left.parsetree(o),
            [node_type, left.ident.to_sym, 
             right.rescue_parsetree(o)]
           ]
  end

  if op()=='='
    rhs=right.rescue_parsetree(o)
    UnaryStarNode===right and rhs=[:svalue, rhs]
    
#          case left
#          when VarNode; 
         [node_type, left.ident.to_sym, rhs]
#          else [node_type, left.data[0].parsetree(o), left.data[1].data[0].ident.+('=').to_sym  ,[:array, rhs]]
#          end

=begin these branches shouldn't be necessary now
  elsif node_type==:op_asgn2
    [node_type, @data[0].data[0].parsetree(o), 
      @data[0].data[1].data[0].ident.+('=').to_sym,
      op().ident.chomp('=').to_sym,
       @data[2].parsetree(o)
    ]
  elsif node_type==:attrasgn
    [node_type]
=end
  else
    [node_type, left.ident.to_sym,
      [:call,
       left.parsetree(o), 
         op().chomp('=').to_sym, 
       [:array, right.rescue_parsetree(o)]
      ]
    ]
  end
  else 
    huh
  end
end

#reducer_identObject



17380
17381
17382
# File 'lib/redparse/ReduceWithsFor_RedParse_1_9.rb', line 17380

def reducer_ident
  :AssignNode
end

#to_lispObject



2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
# File 'lib/redparse/node.rb', line 2427

def to_lisp
  case left
  when ParenedNode; huh
  when BeginNode; huh
  when RescueOpNode; huh
  when ConstantNode; huh
  when BracketsGetNode; huh
  when VarNode
    "(set #{left.to_lisp} (#{op.chomp('=')} #{left.to_lisp} #{right.to_lisp}))"
  when CallSiteNode
  if op=='='
    "(#{left.receiver.to_lisp} #{left.name}= #{right.to_lisp})"
  else
    op_=op.chomp('=')
    varname=nil
    "(let #{varname=huh} #{left.receiver.to_lisp} "+
      "(#{varname} #{left.name}= "+
        "(#{op_} (#{varname} #{op}) #{right.to_lisp})))"
  end
  else  huh
  end
end

#unparse(o = default_unparse_options) ⇒ Object



2594
2595
2596
2597
2598
2599
2600
2601
2602
# File 'lib/redparse/node.rb', line 2594

def unparse(o=default_unparse_options)
  result=lhs.lhs_unparse(o)
  result="(#{result})" if defined? @lhs_parens
  result+' '+op+' '+
    (rhs.class==Array ? 
      rhs.map{|rv| rv.unparse o}.join(',') :
      rhs.unparse(o) 
    )
end