Class: Ionize::Php::Translate::Statements

Inherits:
Translator
  • Object
show all
Includes:
CompositeStringStatements, Debug, IfStatements, MultipleStatements, SwitchCaseStatements, TermStatements
Defined in:
lib/ionize/translate/statements.rb

Constant Summary collapse

IdentityTransforms =
[
 "one_variable", "unmatched", "term", "single_statement", 
 "matched",  "simple", "single_arg", "literal_variable", 
 "array_variable", "one_bracket"
]

Constants inherited from Translator

Translator::SimpleTransforms

Instance Attribute Summary collapse

Attributes inherited from Translator

#parent

Instance Method Summary collapse

Methods included from CompositeStringStatements

#handle_array_lookup_node, #handle_array_lookup_within_string, #handle_composite_double_string, #handle_double_quoted_string_node, #handle_double_string_within_string, #handle_multiple_nodes, #handle_open_double_quoted_string, #handle_single_node, #handle_variable_within_string

Methods included from SwitchCaseStatements

#handle_default_case, #handle_line_statement, #handle_multi_case, #handle_one_case, #handle_switch_case_statement

Methods included from TermStatements

#handle_reference_term, #handle_term_and_expr, #handle_term_and_expr_with_and, #handle_term_array_append, #handle_term_array_assign, #handle_term_assign, #handle_term_error_guard, #handle_term_hashs_to_expr, #handle_term_not_equals_expr, #handle_term_op_expr, #handle_term_or_expr, #handle_term_or_expr_with_or

Methods included from Debug

#debug, #logger

Methods included from IfStatements

#handle_if_else_statement1, #handle_if_else_statement_b, #handle_if_else_statement_b1, #handle_if_statement0, #handle_if_statement_b

Methods included from MultipleStatements

#level, #level=, #multiple_statements

Methods inherited from Translator

handle_node, #handle_num, #initialize, #send, #transform

Constructor Details

This class inherits a constructor from Ionize::Php::Translate::Translator

Instance Attribute Details

#globalsObject



29
30
31
# File 'lib/ionize/translate/statements.rb', line 29

def globals
  @globals ||= []
end

Instance Method Details

#handle_a_variable(node) ⇒ Object

Comment this out and see if it can be refactored with the handler above



273
274
275
276
277
278
279
280
281
# File 'lib/ionize/translate/statements.rb', line 273

def handle_a_variable(node)
  result = transform(node)

  if result.is_a? Array
    result
  else
    [:lvar, result.gsub("$", "").to_id]
  end
end

#handle_array_append(node) ⇒ Object



538
539
540
# File 'lib/ionize/translate/statements.rb', line 538

def handle_array_append(node)
  transform(node.first)
end

#handle_array_lookup(node) ⇒ Object



354
355
356
# File 'lib/ionize/translate/statements.rb', line 354

def handle_array_lookup(node)
  [:call, transform(node.first), :[], [:array, transform(node.third)]]
end

#handle_braced_lookup(node) ⇒ Object



358
359
360
# File 'lib/ionize/translate/statements.rb', line 358

def handle_braced_lookup(node)
  [:call, transform(node.first), :[], [:array, transform(node.third)]]
end

#handle_braced_statements(node) ⇒ Object



243
244
245
# File 'lib/ionize/translate/statements.rb', line 243

def handle_braced_statements(node)
  transform(node.second)
end

#handle_break_statement(node) ⇒ Object



106
107
108
# File 'lib/ionize/translate/statements.rb', line 106

def handle_break_statement(node)
  [:break]
end

#handle_cast(node) ⇒ Object



378
379
380
# File 'lib/ionize/translate/statements.rb', line 378

def handle_cast(node)
  node
end

#handle_class_extends_statement(node) ⇒ Object



230
231
232
233
# File 'lib/ionize/translate/statements.rb', line 230

def handle_class_extends_statement(node)
  [:class, transform(node.second).to_id, [:const, transform(node.fourth).to_id],
   [:scope, transform(node[5]).to_block]]          
end

#handle_class_method_call(node) ⇒ Object



52
53
54
# File 'lib/ionize/translate/statements.rb', line 52

def handle_class_method_call(node)
  [:call, [:const, transform(node.first).to_id], transform(node.third).to_id, transform(node.fifth)]
end

#handle_class_statement(node) ⇒ Object



225
226
227
228
# File 'lib/ionize/translate/statements.rb', line 225

def handle_class_statement(node)
  [:class, transform(node.second).to_id, nil, 
   [:scope, transform(node.fourth).to_block]]
end

#handle_class_var_statement(node) ⇒ Object



235
236
237
# File 'lib/ionize/translate/statements.rb', line 235

def handle_class_var_statement(node)
  [:fcall, :attr_accessor, [:array, [:lit, transform(node.second).last]]]
end

#handle_class_var_with_default_statement(node) ⇒ Object



239
240
241
# File 'lib/ionize/translate/statements.rb', line 239

def handle_class_var_with_default_statement(node)
  [:fcall, :attr_accessor, [:array, [:lit, transform(node.second).last], transform(node.fourth)]]
end

#handle_double_quoted_string(node) ⇒ Object



580
581
582
# File 'lib/ionize/translate/statements.rb', line 580

def handle_double_quoted_string(node)
  [:str, node]
end

#handle_echo_statement(node) ⇒ Object



251
252
253
# File 'lib/ionize/translate/statements.rb', line 251

def handle_echo_statement(node)
  [:fcall, :echo, [:array, transform(node.second)]]
end

#handle_exit_call_statement(node) ⇒ Object



114
115
116
# File 'lib/ionize/translate/statements.rb', line 114

def handle_exit_call_statement(node)
  [:vcall, :exit]
end

#handle_exit_statement(node) ⇒ Object



110
111
112
# File 'lib/ionize/translate/statements.rb', line 110

def handle_exit_statement(node)
  [:vcall, :exit]
end

#handle_false_value(node) ⇒ Object



572
573
574
# File 'lib/ionize/translate/statements.rb', line 572

def handle_false_value(node)
  [:false]
end

#handle_for_statement(node) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/ionize/translate/statements.rb', line 134

def handle_for_statement(node)
  setup       = transform(node.third)
  condition   = transform(node[4])
  update      = transform(node[6])
  body        = transform(node[8])

  while_body  = if body.composite_node?
                  [:block] + body + [update]
                else
                  [:block] + [body] + [update]
                end

  [setup] + [[:while, condition, while_body, true]]
end

#handle_foreach_statement(node) ⇒ Object

This should get moved to Rewrites..



150
151
152
153
154
155
156
157
158
159
# File 'lib/ionize/translate/statements.rb', line 150

def handle_foreach_statement(node)
  variable = transform(node[4]).last

  body     = transform(node[6])
  body     = body.replace_pattern([:lvar, variable], [:dvar, variable])

  [:iter, 
   [:call, transform(node.third), :each],
   [:dasgn_curr, variable], body.to_block]
end

#handle_fun_args_with_trailing_comma(node) ⇒ Object



440
441
442
443
444
445
446
447
448
449
450
451
452
453
# File 'lib/ionize/translate/statements.rb', line 440

def handle_fun_args_with_trailing_comma(node)
  debug "Fun args with trailing comma #{node.inspect}"
  result = transform(node.first)
  
  if result.empty?
    nil
  elsif result.nil?
    nil
  elsif result.composite_node?
    [:array] + result
  else
    [:array, result]
  end
end

#handle_fun_args_within_call(node) ⇒ Object



425
426
427
428
429
430
431
432
433
434
435
436
437
438
# File 'lib/ionize/translate/statements.rb', line 425

def handle_fun_args_within_call(node)
  debug "Fun args within call #{node.inspect}"
  result = transform(node)
  debug "Fun args within call result #{result.inspect}"      
  if result.empty?
    nil
  elsif result.nil?
    nil
  elsif result.composite_node?
    [:array] + result
  else
    [:array, result]
  end
end

#handle_fun_define(node) ⇒ Object



389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# File 'lib/ionize/translate/statements.rb', line 389

def handle_fun_define(node)  
  args = FunctionArgs.new(self).transform(node[3])
  
  debug "Args for fun_define are #{args.inspect}"
  parameters = if args == [:args]
                 [:args]
               elsif args.is_a? Array
                 [:args] + args
               else
                 [:args, args]
               end

  body = transform(node[6])
  body.shift if body.first == :block
  debug "Body is #{body.inspect}"

  if body.composite_node?
    function_block = [:block, parameters] + body
  else
    function_block = [:block, parameters, body]
  end

  [:defn, node.second.to_a.first.second.to_id, 
   [:scope, function_block]]
end

#handle_global_declaration(node) ⇒ Object

We will have to keep track of this at some point to replace every similar pattern in the entire tree



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/ionize/translate/statements.rb', line 83

def handle_global_declaration(node)
  variable = transform(node.second)

  debug "Global variables are #{variable.inspect}"

  # Keeping track of the global variables so we can 
  # replace them as we encounter local variables
  if variable.composite_node?
    multiple_globals = [:array] + variable.map do |lvar|
      self.globals << lvar.last
      lvar.last.to_global_variable
    end
    [:fcall, :global, multiple_globals]
  elsif variable.first == :lvar 
    self.globals << variable.last
    variable.last.to_global_variable
  elsif variable.first == :gvar
    variable
  else
    variable.to_global_variable
  end
end

#handle_html_string(node) ⇒ Object



608
609
610
# File 'lib/ionize/translate/statements.rb', line 608

def handle_html_string(node)
  [:html, node]
end

#handle_html_text_with_php(node) ⇒ Object

html ###



604
605
606
# File 'lib/ionize/translate/statements.rb', line 604

def handle_html_text_with_php(node)
  [:php] + transform(node)
end

#handle_include_once_statement(node) ⇒ Object



130
131
132
# File 'lib/ionize/translate/statements.rb', line 130

def handle_include_once_statement(node)
  [:fcall, :load, [:array, transform(node.second)]]
end

#handle_include_statement(node) ⇒ Object



126
127
128
# File 'lib/ionize/translate/statements.rb', line 126

def handle_include_statement(node)
  [:fcall, :load, [:array, transform(node.second)]]
end

#handle_list_assign(node) ⇒ Object

Yes, Php has a destructuring bind.. kinda ugly, though



196
197
198
199
200
# File 'lib/ionize/translate/statements.rb', line 196

def handle_list_assign(node)
  variables = [:array] + (transform(node.third).rest.map {|v| [:lasgn, v] })
  [:masgn, variables, 
   [:splat, transform(node.sixth)]]
end

#handle_multiple_args(node) ⇒ Object



313
314
315
316
317
318
319
320
321
322
# File 'lib/ionize/translate/statements.rb', line 313

def handle_multiple_args(node)
  debug "Multiple args #{node.inspect}"
  args = FunctionArgs.new(self).handle_multiple_args(node)
  debug "Multiple args transformed is #{args.inspect}"
  unless args == [:args]
    [:args] + args
  else
    [:args]
  end
end

#handle_multiple_args_within_call(node) ⇒ Object



324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/ionize/translate/statements.rb', line 324

def handle_multiple_args_within_call(node)
  debug "Multiple args within fun call #{node.inspect}"

  first  = transform(node.first)
  second = transform(node.third)

  debug "Multiple args first is #{first.inspect} and second is #{second.inspect}"

  result = if first.composite_node?
             first + [second]
           elsif first.first == :hash and second.first == :hash
             first + second.rest
           else
             [first, second]
           end

  debug "Multiple args within fun call result #{result.inspect}"
  result
end

#handle_multiple_statements(node) ⇒ Object

multiple statements ###



460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
# File 'lib/ionize/translate/statements.rb', line 460

def handle_multiple_statements(node)
  # This implementation is kind of old
  # and stinky.. Could probably be done
  # a lot better
  
  multiple_statements do
    first, second = transform(node.first), transform(node.second)
    result = if second.composite_node?
               if first.composite_node?
                 first + second
               else
                 [first] + second
               end
             else
               [first, second]
             end
    
    final_result = if level == 1
                     [:block] + result
                   else
                     result
                   end            
    final_result
  end        
end

#handle_multiple_variables(node) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/ionize/translate/statements.rb', line 56

def handle_multiple_variables(node)
  first = transform(node.first)
  rest  = transform(node.third)

  debug "Multiple variables #{first.inspect}, #{rest.inspect}"

  result = if rest.composite_node?
             [first] + rest
             if first.composite_node?
               first + rest
             end
           elsif first.composite_node?
             first + [rest]
           else
             [first, rest]
           end

  debug "Multiple variables result #{result.inspect}"      
  result
end

#handle_negative_var(node) ⇒ Object



307
308
309
310
311
# File 'lib/ionize/translate/statements.rb', line 307

def handle_negative_var(node)
  result = transform(node.second)
  result[1] = (-result[1])
  result
end

#handle_new_object(node) ⇒ Object

oo statements ###



206
207
208
# File 'lib/ionize/translate/statements.rb', line 206

def handle_new_object(node)
  [:call, [:const, transform(node.second).to_id], :new]
end

#handle_new_object_with_args(node) ⇒ Object



210
211
212
213
214
215
216
# File 'lib/ionize/translate/statements.rb', line 210

def handle_new_object_with_args(node)
  if node.fourth == {:fun_args_within_call=>[{:no_args_within_call=>[]}]}
    [:call, [:const, transform(node.second).to_id], :new]
  else
    # TODO: Handle this..
  end
end

#handle_new_variable_class_object(node) ⇒ Object



218
219
220
221
222
223
# File 'lib/ionize/translate/statements.rb', line 218

def handle_new_variable_class_object(node)
  [:call, 
   [:call,
    [:const, :Object], :const_get,
    [:array, transform(node.second)]], :new]
end

#handle_no_args(node) ⇒ Object



263
264
265
# File 'lib/ionize/translate/statements.rb', line 263

def handle_no_args(node)
  [:args]
end

#handle_no_args_within_call(node) ⇒ Object



267
268
269
# File 'lib/ionize/translate/statements.rb', line 267

def handle_no_args_within_call(node)
  [:args]
end

#handle_not_var(node) ⇒ Object



291
292
293
294
# File 'lib/ionize/translate/statements.rb', line 291

def handle_not_var(node)
  debug "Not var #{node.inspect}"
  [:not, transform(node.second)]
end

#handle_one_expr_bracket(node) ⇒ Object



350
351
352
# File 'lib/ionize/translate/statements.rb', line 350

def handle_one_expr_bracket(node)
  transform(node.second)
end

#handle_oo_array_assign(node) ⇒ Object



511
512
513
514
515
516
# File 'lib/ionize/translate/statements.rb', line 511

def handle_oo_array_assign(node)
  [:attrasgn, 
   [:call, transform(node.first), transform(node.third).to_id], 
   :[]=, 
   [:array, transform(node.fifth), transform(node[7])]]
end

#handle_oo_array_lookup(node) ⇒ Object



542
543
544
# File 'lib/ionize/translate/statements.rb', line 542

def handle_oo_array_lookup(node)          
  [:call, [:call, transform(node.first), transform(node.third).to_sym], :[], [:array, transform(node.fifth)]]
end

#handle_oo_assign(node) ⇒ Object

oo exprs ###



491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
# File 'lib/ionize/translate/statements.rb', line 491

def handle_oo_assign(node)
  debug "The oo assign node is #{node.inspect}"
  # TODO: Pretty this up some.. If possible..
  object = transform(node.first)

  debug "The object to be set is #{object.inspect}"
  object.shift # discard leading :call

  attribute = object.pop
  debug "The attribute to be set is #{attribute.inspect}"
  
  assigned = attribute.to_s + "=" # pop off assigned to var
  expr = transform(node.fifth)
  
  # TODO: Move this rewrite to the Rewrites class
  object = (if object.first == [:lvar, :this] then [:self] else object.first end)

  [:attrasgn, object, assigned.to_id, [:array, expr]]
end

#handle_oo_call(node) ⇒ Object



550
551
552
553
554
555
556
557
558
# File 'lib/ionize/translate/statements.rb', line 550

def handle_oo_call(node)
  debug "oo call node is #{node.inspect}"

  if node.fifth == {:fun_args_within_call=>[{:no_args_within_call=>[]}]}
    [:call, transform(node.first), transform(node.third).to_id]
  else
    [:call, transform(node.first), transform(node.third).to_id, transform(node.fifth)]
  end
end

#handle_oo_expr(node) ⇒ Object



546
547
548
# File 'lib/ionize/translate/statements.rb', line 546

def handle_oo_expr(node)
   transform(node)
end

#handle_oo_regular_fun_call(node) ⇒ Object



560
561
562
# File 'lib/ionize/translate/statements.rb', line 560

def handle_oo_regular_fun_call(node)
  [transform(node.first).to_id, transform(node.third)]
end

#handle_oo_variable(node) ⇒ Object



526
527
528
529
530
531
532
# File 'lib/ionize/translate/statements.rb', line 526

def handle_oo_variable(node)
  debug "oo_variable #{node.inspect}"
  term = transform(node.first) 
  # TODO: Move this rewrite to the Rewrites class
  object = (if term == [:lvar, :this] then [:self] else term end)
  [:call, object, transform(node.third).to_id]
end

#handle_oo_variable_variable(node) ⇒ Object



518
519
520
# File 'lib/ionize/translate/statements.rb', line 518

def handle_oo_variable_variable(node)
  [:call, transform(node.first), :get, [:array, transform(node.third)]]
end

#handle_oo_variable_variable_assign(node) ⇒ Object



522
523
524
# File 'lib/ionize/translate/statements.rb', line 522

def handle_oo_variable_variable_assign(node)
  [:attrasgn, transform(node.first), :[]=, [:array, transform(node.third), transform(node.fifth)]]
end

#handle_op(node) ⇒ Object



283
284
285
286
287
288
289
# File 'lib/ionize/translate/statements.rb', line 283

def handle_op(node)
  if node == ".="
    :<<
  else
    node.to_id
  end
end

#handle_opt_multiple_statements(node) ⇒ Object

recursive switch case statement ###



172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/ionize/translate/statements.rb', line 172

def handle_opt_multiple_statements(node)
  first_node  = [transform(node.first)]
  
  second_node = if (result = transform(node.second)).composite_node?
                  result
                else
                  [result]
                end
  
  result = [:block] + first_node + second_node
  debug "Opt multiple statements result is #{result.inspect}"
  result
end

#handle_opt_no_statements(node) ⇒ Object



186
187
188
# File 'lib/ionize/translate/statements.rb', line 186

def handle_opt_no_statements(node)
  nil
end

#handle_paren_cast(node) ⇒ Object



382
383
384
385
386
387
# File 'lib/ionize/translate/statements.rb', line 382

def handle_paren_cast(node)
  type = ("to_" + transform(node.second).to_s).to_id
  term = transform(node.fourth)

  [:call, term, type]
end

#handle_paren_expr(node) ⇒ Object



362
363
364
# File 'lib/ionize/translate/statements.rb', line 362

def handle_paren_expr(node)
  transform(node.second)
end

#handle_php_end(node) ⇒ Object



616
617
618
# File 'lib/ionize/translate/statements.rb', line 616

def handle_php_end(node)
  [:erb_end, "  %>"]
end

#handle_php_start(node) ⇒ Object



612
613
614
# File 'lib/ionize/translate/statements.rb', line 612

def handle_php_start(node)
  [:erb_start, "<%  "]
end

#handle_post_decrement_var(node) ⇒ Object



302
303
304
305
# File 'lib/ionize/translate/statements.rb', line 302

def handle_post_decrement_var(node)
  variable = transform(node.first)
  [:lasgn, variable.second, [:call, variable, :-, [:array, [:lit, 1]]]]      
end

#handle_post_increment_var(node) ⇒ Object



296
297
298
299
300
# File 'lib/ionize/translate/statements.rb', line 296

def handle_post_increment_var(node)
  debug "Post increment var #{node.inspect}"
  variable = transform(node.first)
  [:lasgn, variable.second, [:call, variable, :+, [:array, [:lit, 1]]]]
end

#handle_print(arg) ⇒ Object



592
593
594
# File 'lib/ionize/translate/statements.rb', line 592

def handle_print(arg)
  nil
end

#handle_print_statement(node) ⇒ Object



247
248
249
# File 'lib/ionize/translate/statements.rb', line 247

def handle_print_statement(node)
  [:fcall, :print, [:array, transform(node).first]]
end

#handle_regular_fun_call(node) ⇒ Object

TODO: This is such a stupid name for a node



46
47
48
49
50
# File 'lib/ionize/translate/statements.rb', line 46

def handle_regular_fun_call(node)
  # TODO: Move rewrites into it's own pass,
  # instead of injecting it into this one..
  Rewrites.new(self).handle_regular_fun_call(node)
end

#handle_require_once_statement(node) ⇒ Object



122
123
124
# File 'lib/ionize/translate/statements.rb', line 122

def handle_require_once_statement(node)
  [:fcall, :require, [:array, transform(node.second)]]
end

#handle_require_statement(node) ⇒ Object



118
119
120
# File 'lib/ionize/translate/statements.rb', line 118

def handle_require_statement(node)
  [:fcall, :require, [:array, transform(node.second)]]
end

#handle_return_one(node) ⇒ Object



366
367
368
# File 'lib/ionize/translate/statements.rb', line 366

def handle_return_one(node)
  [:return, transform(node.second)]
end

#handle_return_zero(node) ⇒ Object



370
371
372
# File 'lib/ionize/translate/statements.rb', line 370

def handle_return_zero(node)
  [:return]
end

#handle_single_arg_within_call(node) ⇒ Object



344
345
346
347
348
# File 'lib/ionize/translate/statements.rb', line 344

def handle_single_arg_within_call(node)
  result = transform(node)      
  debug "Single arg within fun call #{result.inspect}"
  result
end

#handle_single_oo_fragment(node) ⇒ Object



534
535
536
# File 'lib/ionize/translate/statements.rb', line 534

def handle_single_oo_fragment(node)
  transform(node.second)
end

#handle_single_quoted_string(node) ⇒ Object



576
577
578
# File 'lib/ionize/translate/statements.rb', line 576

def handle_single_quoted_string(node)
  [:str, node]
end

#handle_tertiary(node) ⇒ Object



374
375
376
# File 'lib/ionize/translate/statements.rb', line 374

def handle_tertiary(node)
  [:if, transform(node.first), transform(node.third), transform(node.fifth)]
end

#handle_true_value(node) ⇒ Object

literals ###



568
569
570
# File 'lib/ionize/translate/statements.rb', line 568

def handle_true_value(node)
  [:true]
end

#handle_user_constant(node) ⇒ Object



255
256
257
# File 'lib/ionize/translate/statements.rb', line 255

def handle_user_constant(node)
  [:const, transform(node).to_id]
end

#handle_variable(node) ⇒ Object



415
416
417
418
419
420
421
422
423
# File 'lib/ionize/translate/statements.rb', line 415

def handle_variable(node)
  result = node.gsub("$", "").to_id

  if self.globals.include? result
    [:gvar, ("$" + result.to_s.gsub("$", "")).to_id]
  else
    [:lvar, result]
  end
end

#handle_while_statement(node) ⇒ Object



161
162
163
164
165
166
# File 'lib/ionize/translate/statements.rb', line 161

def handle_while_statement(node)
  condition = transform(node.third)
  body      = transform(node.fifth).to_block
  
  [:while, condition, body, true]
end

#handle_word(node) ⇒ Object



259
260
261
# File 'lib/ionize/translate/statements.rb', line 259

def handle_word(node)
  node
end