farleyknight-ionize 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. data/README.rdoc +59 -0
  2. data/Rakefile +5 -0
  3. data/bin/ionize +47 -0
  4. data/lib/ionize.rb +75 -0
  5. data/lib/ionize/environment.rb +56 -0
  6. data/lib/ionize/environment/application.rb +58 -0
  7. data/lib/ionize/environment/php_array.rb +95 -0
  8. data/lib/ionize/parser.rb +272 -0
  9. data/lib/ionize/tokenizer.rb +544 -0
  10. data/lib/ionize/translate.rb +34 -0
  11. data/lib/ionize/translate/composite_string_statements.rb +79 -0
  12. data/lib/ionize/translate/debug.rb +16 -0
  13. data/lib/ionize/translate/ext.rb +47 -0
  14. data/lib/ionize/translate/function_args.rb +132 -0
  15. data/lib/ionize/translate/if_statements.rb +42 -0
  16. data/lib/ionize/translate/multiple_statements.rb +22 -0
  17. data/lib/ionize/translate/php_to_ruby.rb +40 -0
  18. data/lib/ionize/translate/rails_for_php.rb +191 -0
  19. data/lib/ionize/translate/rewritable.rb +133 -0
  20. data/lib/ionize/translate/rewrites.rb +51 -0
  21. data/lib/ionize/translate/statements.rb +622 -0
  22. data/lib/ionize/translate/switch_case_statements.rb +52 -0
  23. data/lib/ionize/translate/term_statements.rb +76 -0
  24. data/lib/ionize/translate/translator.rb +52 -0
  25. data/lib/ionize/version.rb +9 -0
  26. data/spec/fixtures/array_lookup.php +10 -0
  27. data/spec/fixtures/boolean_operators.php +5 -0
  28. data/spec/fixtures/boolean_operators.rb +6 -0
  29. data/spec/fixtures/class_def.php +34 -0
  30. data/spec/fixtures/class_def.rb +34 -0
  31. data/spec/fixtures/dangling_else.php +8 -0
  32. data/spec/fixtures/dangling_else.rb +12 -0
  33. data/spec/fixtures/drupal_1.php +663 -0
  34. data/spec/fixtures/drupal_2.php +1152 -0
  35. data/spec/fixtures/empty_string.php +12 -0
  36. data/spec/fixtures/for_loop.php +17 -0
  37. data/spec/fixtures/for_loop2.php +13 -0
  38. data/spec/fixtures/for_loop3.php +16 -0
  39. data/spec/fixtures/for_loop3.rb +17 -0
  40. data/spec/fixtures/for_loop4.php +5 -0
  41. data/spec/fixtures/for_loop4.rb +6 -0
  42. data/spec/fixtures/foreach.php +9 -0
  43. data/spec/fixtures/foreach2.php +8 -0
  44. data/spec/fixtures/foreach3.php +7 -0
  45. data/spec/fixtures/foreach3.rb +7 -0
  46. data/spec/fixtures/fun_def.php +9 -0
  47. data/spec/fixtures/fun_def2.php +30 -0
  48. data/spec/fixtures/fun_def2.rb +30 -0
  49. data/spec/fixtures/fun_def3.php +33 -0
  50. data/spec/fixtures/fun_def4.php +43 -0
  51. data/spec/fixtures/fun_def4.rb +37 -0
  52. data/spec/fixtures/fun_def5.php +36 -0
  53. data/spec/fixtures/fun_with_if.php +6 -0
  54. data/spec/fixtures/fun_with_if.rb +6 -0
  55. data/spec/fixtures/fun_with_ifs.php +12 -0
  56. data/spec/fixtures/fun_with_ifs.rb +14 -0
  57. data/spec/fixtures/hello_world.php +6 -0
  58. data/spec/fixtures/heredoc.php +6 -0
  59. data/spec/fixtures/heredoc.rb +5 -0
  60. data/spec/fixtures/if.php +6 -0
  61. data/spec/fixtures/if.rb +7 -0
  62. data/spec/fixtures/if_boolean.php +5 -0
  63. data/spec/fixtures/if_boolean.rb +5 -0
  64. data/spec/fixtures/if_else.php +11 -0
  65. data/spec/fixtures/if_else1.php +17 -0
  66. data/spec/fixtures/if_else2.php +8 -0
  67. data/spec/fixtures/if_else3.php +15 -0
  68. data/spec/fixtures/if_else_nested.php +14 -0
  69. data/spec/fixtures/if_else_nested.rb +15 -0
  70. data/spec/fixtures/if_else_series.php +12 -0
  71. data/spec/fixtures/if_else_series.rb +12 -0
  72. data/spec/fixtures/if_not.php +5 -0
  73. data/spec/fixtures/if_not.rb +5 -0
  74. data/spec/fixtures/if_with_brackets.php +7 -0
  75. data/spec/fixtures/if_with_brackets.rb +7 -0
  76. data/spec/fixtures/long_if_else.php +10 -0
  77. data/spec/fixtures/long_if_else.rb +9 -0
  78. data/spec/fixtures/oo.php +16 -0
  79. data/spec/fixtures/php_nuke/sql_layer.php +527 -0
  80. data/spec/fixtures/postop.php +3 -0
  81. data/spec/fixtures/preop.php +7 -0
  82. data/spec/fixtures/simple_fun_def.php +4 -0
  83. data/spec/fixtures/switch_case.php +13 -0
  84. data/spec/fixtures/switch_case.rb +14 -0
  85. data/spec/fixtures/switch_case2.php +25 -0
  86. data/spec/fixtures/switch_case3.php +40 -0
  87. data/spec/fixtures/switch_case3.rb +42 -0
  88. data/spec/fixtures/switch_case4.php +56 -0
  89. data/spec/fixtures/switch_case5.php +71 -0
  90. data/spec/fixtures/switch_case_with_rescue_nil.php +43 -0
  91. data/spec/fixtures/switch_case_with_rescue_nil.rb +35 -0
  92. data/spec/fixtures/tertiary.php +3 -0
  93. data/spec/helper.rb +17 -0
  94. data/spec/php_environment_spec.rb +83 -0
  95. data/spec/php_parser_spec.rb +121 -0
  96. data/spec/php_translator_spec.rb +358 -0
  97. data/spec/rails_for_php_spec.rb +303 -0
  98. metadata +191 -0
@@ -0,0 +1,34 @@
1
+
2
+ load 'ionize/translate/debug.rb'
3
+ load 'ionize/translate/ext.rb'
4
+ load 'ionize/translate/translator.rb'
5
+ load 'ionize/translate/function_args.rb'
6
+ load 'ionize/translate/statements.rb'
7
+ load 'ionize/translate/rewrites.rb'
8
+ load 'ionize/translate/php_to_ruby.rb'
9
+
10
+ module Ionize
11
+ module Php
12
+ module Translate
13
+ def self.flatten(node)
14
+ if node.is_a? Array
15
+ node.collect {|n| flatten(n) }
16
+ elsif node.is_a? Dhaka::ParseSuccessResult
17
+ flatten(node.child_nodes)
18
+ elsif node.is_a? Dhaka::ParseTreeCompositeNode
19
+ {node.production.name.to_sym => flatten(node.child_nodes)}
20
+ elsif node.is_a? Dhaka::ParseTreeLeafNode
21
+ flatten(node.token)
22
+ elsif node.is_a? Dhaka::Token
23
+ {node.symbol_name.to_sym => node.value}
24
+ else
25
+ raise "Cannot handle type #{node.class}!"
26
+ end
27
+ end
28
+
29
+ def self.translate(ast)
30
+ Statements.new(self).transform(flatten(ast)).to_block
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,79 @@
1
+ module Ionize
2
+ module Php
3
+ module Translate
4
+ module CompositeStringStatements
5
+ def handle_multiple_nodes(node)
6
+ debug "Multiple nodes #{node.inspect}"
7
+
8
+ first = transform(node.first)
9
+ second = transform(node.second)
10
+
11
+ debug "Multiple nodes results #{first.inspect} #{second.inspect}"
12
+
13
+ if second.nil?
14
+ first
15
+ elsif second.composite_node?
16
+ if first.composite_node?
17
+ first + second
18
+ else
19
+ [first] + second
20
+ end
21
+ elsif first.composite_node?
22
+ first + [second]
23
+ else
24
+ [first, second]
25
+ end
26
+ end
27
+
28
+ def handle_open_double_quoted_string(node)
29
+ node
30
+ end
31
+
32
+ def handle_double_quoted_string_node(node)
33
+ # puts "double_quoted_string_node #{node.inspect}"
34
+ # string = eval(node)
35
+ string = node
36
+ (string.empty?) ? nil : [:str, string]
37
+ end
38
+
39
+ def handle_single_node(node)
40
+ transform(node)
41
+ end
42
+
43
+ def handle_double_string_within_string(node)
44
+ transform(node)
45
+ end
46
+
47
+ def handle_variable_within_string(node)
48
+ [:evstr, transform(node.first)]
49
+ end
50
+
51
+ def handle_array_lookup_within_string(node)
52
+ transform(node)
53
+ end
54
+
55
+ def handle_array_lookup_node(node)
56
+ param = if node =~ /(\$.*?)\[(\$.*)\]/
57
+ match = node.match(/(\$.*?)\[(\$.*)\]/)
58
+ [:lvar, match[2].to_s.gsub("$", "").to_sym]
59
+ elsif node =~ /(\$.*?)\[(.*)\]/
60
+ match = node.match(/(\$.*?)\[(.*)\]/)
61
+ [:str, match[2]]
62
+ end
63
+ [:evstr, [:call, transform(:variable => match[1]), :[], [:array, param]]]
64
+ end
65
+
66
+ def handle_composite_double_string(node)
67
+ initial = transform(node.first)
68
+ body = transform(node.second)
69
+
70
+ if body.composite_node?
71
+ [:dstr, initial] + body
72
+ else
73
+ [:dstr, initial, body]
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,16 @@
1
+
2
+ module Ionize
3
+ module Php
4
+ module Translate
5
+ module Debug
6
+ def logger
7
+ @logger ||= Logger.new("debug.log")
8
+ end
9
+
10
+ def debug(msg)
11
+ logger.debug(msg)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,47 @@
1
+
2
+ class Array
3
+ {:first => 0, :second => 1, :third => 2, :fourth => 3, :fifth => 4, :sixth => 5}.each do |name, value|
4
+ define_method(name) { self[value] }
5
+ end
6
+
7
+ def rest
8
+ self[1..-1]
9
+ end
10
+
11
+ def replace_pattern(pattern, value)
12
+ copy = self.dup
13
+ (0..copy.length).each do |i|
14
+ if copy[i] == pattern
15
+ copy[i] = value
16
+ elsif copy[i].is_a? Array
17
+ copy[i] = copy[i].replace_pattern(pattern, value)
18
+ end
19
+ end
20
+ copy
21
+ end
22
+
23
+ def composite_node?
24
+ self.first.is_a? Array
25
+ end
26
+
27
+ def to_block
28
+ if self.composite_node?
29
+ [:block] + self
30
+ else
31
+ self
32
+ end
33
+ end
34
+ end
35
+
36
+ class Symbol
37
+ def to_global_variable
38
+ [:gvar, ("$" + self.to_s.gsub("$", "")).to_sym]
39
+ end
40
+ end
41
+
42
+ class Hash
43
+ def node_type
44
+ raise "Cannot use hash as node with more than one key!" unless keys.length == 1
45
+ keys.first
46
+ end
47
+ end
@@ -0,0 +1,132 @@
1
+ module Ionize
2
+ module Php
3
+ module Translate
4
+ class FunctionArgs < Translator
5
+ include Debug
6
+
7
+ attr_accessor :assigns
8
+
9
+ def handle_term(node)
10
+ transform(node)
11
+ end
12
+
13
+ def handle_single_arg(node)
14
+ transform(node)
15
+ end
16
+
17
+ def handle_word(node)
18
+ node
19
+ end
20
+
21
+ def handle_no_args(node)
22
+ [:args]
23
+ end
24
+
25
+ def handle_user_constant(node)
26
+ [:const, transform(node).to_sym]
27
+ end
28
+
29
+ # Perhaps these two can be
30
+ # cleaned up? Not sure..
31
+
32
+ def handle_variable(node)
33
+ debug "Variable #{node.inspect}"
34
+ node.first.gsub("$", "").to_sym
35
+ end
36
+
37
+ def handle_a_variable(node)
38
+ debug "Variable inside function args #{node.inspect}"
39
+ transform(node.first)
40
+ end
41
+
42
+ def handle_reference_term(node)
43
+ # For now, I say screw references..
44
+ transform(node.second)
45
+ # TODO: But we might change this in the future.. Who knows.
46
+ end
47
+
48
+ ################
49
+ ### literals ###
50
+ ################
51
+
52
+ def handle_single_quoted_string(node)
53
+ [:str, node]
54
+ end
55
+
56
+ def handle_double_quoted_string(node)
57
+ [:str, node]
58
+ end
59
+
60
+ def handle_regular_fun_call(node)
61
+ debug "Regular fun call #{node.inspect}"
62
+ name = transform(node.first).to_sym
63
+ if node.third.keys == [:no_args]
64
+ [:fcall, name]
65
+ else
66
+ args = transform(node.third)
67
+ if args.nil?
68
+ [:fcall, name]
69
+ else
70
+ [:fcall, name, args]
71
+ end
72
+ end
73
+ end
74
+
75
+ ############
76
+ ### args ###
77
+ ############
78
+
79
+ def handle_fun_args_within_call(node)
80
+ args = node.first.to_a.first.last
81
+ result = transform(args)
82
+ debug "Fun args within call result #{result.inspect}"
83
+ if result.empty?
84
+ nil
85
+ else
86
+ [:array] + result
87
+ end
88
+ end
89
+
90
+ def handle_term_assign(node)
91
+ term, op, expr = *node
92
+ debug "Term assign #{node.inspect}"
93
+ result = transform(expr)
94
+ variable = transform(term)
95
+
96
+ # Okay, so this is kind of crazy but, in Ruby, if you ever use the
97
+ # assignment operation inside the formal parameters, it creates
98
+ # a block inside the function header AST. Run a ParseTree on
99
+ # on a method which has defaults to see what I mean.
100
+
101
+ # AFAICT, the most efficient way to handle this crazy *#$@-ing case
102
+ # is to store the assignments later and only give back just the
103
+ # variable being assigned. The assignment statements are appended
104
+ # later in the transform
105
+
106
+ self.assigns[variable] = if result.is_a? Array
107
+ [:lasgn, variable, result]
108
+ else
109
+ [:lasgn, variable, [result]]
110
+ end
111
+
112
+ variable
113
+ end
114
+
115
+ def handle_multiple_args(node)
116
+ debug "Multiple args on FunctionArgs side #{node.inspect}"
117
+
118
+ # Clear the assignment statements and perform the transformation
119
+ self.assigns = {}
120
+ result = transform(node.select {|c| c.values.first != "," })
121
+
122
+ # Append the assignment statements spoken of in "term_assign"
123
+ unless self.assigns.empty?
124
+ result.flatten + [[:block, self.assigns.values.first]]
125
+ else
126
+ result.flatten
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,42 @@
1
+ module Ionize
2
+ module Php
3
+ module Translate
4
+ module IfStatements
5
+ def handle_if_statement0(node)
6
+ debug "If statement0 #{node.inspect}"
7
+ condition = transform(node.third)
8
+ body = transform(node[4]).to_block
9
+ if condition.first == :not
10
+ [:if, condition.second, nil, body]
11
+ else
12
+ [:if, condition, body, nil]
13
+ end
14
+ end
15
+
16
+ def handle_if_statement_b(node)
17
+ condition = transform(node.third)
18
+ body = transform(node[5]).to_block
19
+ if condition.first == :not
20
+ [:if, condition.second, nil, body]
21
+ else
22
+ [:if, condition, body, nil]
23
+ end
24
+ end
25
+
26
+ def handle_if_else_statement1(node)
27
+ debug "If else statement1 #{node.inspect}"
28
+ [:if, transform(node.third), transform(node[4]).to_block, transform(node[6]).to_block]
29
+ end
30
+
31
+ def handle_if_else_statement_b(node)
32
+ [:if, transform(node.third), transform(node[5]).to_block, transform(node[9]).to_block]
33
+ end
34
+
35
+ def handle_if_else_statement_b1(node)
36
+ debug "If else statement b1 #{node.inspect}"
37
+ [:if, transform(node.third), transform(node[5]).to_block, transform(node[8]).to_block]
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,22 @@
1
+ module Ionize
2
+ module Php
3
+ module Translate
4
+ module MultipleStatements
5
+ def level
6
+ @level ||= 0
7
+ end
8
+
9
+ def level=(other)
10
+ @level = other
11
+ end
12
+
13
+ def multiple_statements
14
+ self.level += 1
15
+ result = yield
16
+ self.level -= 1
17
+ result
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,40 @@
1
+
2
+ require 'ruby2ruby'
3
+
4
+ module Ionize
5
+ module Php
6
+ module Translate
7
+ class Php2Ruby < Ruby2Ruby
8
+ def process_hash(exp)
9
+ result = []
10
+ until exp.empty?
11
+ result << "#{process(exp.shift)} => #{process(exp.shift)}"
12
+ end
13
+ "{#{result.join(', ')}}"
14
+ end
15
+
16
+ def process_php(exp)
17
+ str = ""
18
+ until exp.empty?
19
+ subexp = exp.shift
20
+ str << process(subexp)
21
+ end
22
+ str
23
+ end
24
+
25
+ def process_html(exp)
26
+ exp.shift
27
+ end
28
+
29
+ def process_erb_start(exp)
30
+ exp.shift
31
+ end
32
+
33
+ def process_erb_end(exp)
34
+ exp.shift
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
@@ -0,0 +1,191 @@
1
+ module Ionize
2
+ module Php
3
+ module Translate
4
+ module RailsForPhp
5
+ # lasgn rewrites
6
+ def rewrite_lasgn_preg_match(var, expr)
7
+ regex, object, matches = *expr.last.rest
8
+
9
+ [:masgn,
10
+ [:array, [:lasgn, var], [:lasgn, matches.last]],
11
+ [:to_ary, [:call, object, :preg_match, [:array, [:lit, eval(regex.last)]]]]]
12
+ end
13
+
14
+ def rewrite_lasgn_preg_match_all(var, expr)
15
+ regex, object, matches = *expr.last.rest
16
+
17
+ [:masgn,
18
+ [:array, [:lasgn, var], [:lasgn, matches.last]],
19
+ [:to_ary, [:call, object, :preg_match_all, [:array, [:lit, eval(regex.last)]]]]]
20
+ end
21
+
22
+ # fcall rewrites..
23
+
24
+ def rewrite_fcall_implode(args)
25
+ [:call, args.third, :join, [:array, args.second]]
26
+ end
27
+
28
+ def rewrite_fcall_explode(args)
29
+ [:call, args.third, :split, [:array, args.second]]
30
+ end
31
+
32
+ def rewrite_fcall_in_array(args)
33
+ if args.last == [:true]
34
+ [:call, args.third, :include?, [:array, args.second]]
35
+ else
36
+ raise "Cannot handle non-strict version of in_array!"
37
+ end
38
+ end
39
+
40
+ # files
41
+
42
+ def rewrite_fcall_file(args)
43
+ [:call, [:const, :File], :readlines, args]
44
+ end
45
+
46
+ # hashing algorithms..
47
+
48
+ def rewrite_fcall_md5(args)
49
+ [:call, [:colon2, [:const, :Digest], :MD5], :hexdigest, [:array, args.second]]
50
+ end
51
+
52
+ def rewrite_fcall_md5_file(args)
53
+ [:call, [:colon2, [:const, :Digest], :MD5], :hexdigest, [:array, [:call, [:const, :File], :read, [:array, args.second]]]]
54
+ end
55
+
56
+ def rewrite_fcall_sha1(args)
57
+ [:call, [:colon2, [:const, :Digest], :SHA1], :hexdigest, [:array, args.second]]
58
+ end
59
+
60
+ def rewrite_fcall_sha1_file(args)
61
+ [:call, [:colon2, [:const, :Digest], :SHA1], :hexdigest, [:array, [:call, [:const, :File], :read, [:array, args.second]]]]
62
+ end
63
+
64
+ # arrays
65
+
66
+ def rewrite_fcall_count(args)
67
+ [:call, args.second, :length]
68
+ end
69
+
70
+ def rewrite_fcall_array_combine(args)
71
+ [:call, args.second, :combine, [:array, args.third]]
72
+ end
73
+
74
+ def rewrite_fcall_array_merge(args)
75
+ [:call, args.second, :merge, [:array, args.third]]
76
+ end
77
+
78
+ # strings..
79
+
80
+ def rewrite_fcall_strrev(args)
81
+ [:call, args.second, :reverse]
82
+ end
83
+
84
+ def rewrite_fcall_stripslashes(args)
85
+ [:call, args.second, :gsub, [:array, [:str, "\\"], [:str, ""]]]
86
+ end
87
+
88
+ def rewrite_fcall_strlen(args)
89
+ [:call, args.second, :length]
90
+ end
91
+
92
+ def rewrite_fcall_rtrim(args)
93
+ if args.length == 2
94
+ [:call, args.second, :rstrip]
95
+ elsif args.length == 3
96
+ regex = [:lit, eval(Regexp.new("[#{args.third.last}]+$").inspect)]
97
+ [:call, args.second, :gsub, [:array, regex, [:str, '']]]
98
+ end
99
+ end
100
+
101
+ def rewrite_fcall_ltrim(args)
102
+ if args.length == 2
103
+ [:call, args.second, :lstrip]
104
+ elsif args.length == 3
105
+ regex = [:lit, eval(Regexp.new("^[#{args.third.last}]+").inspect)]
106
+ [:call, args.second, :gsub, [:array, regex, [:str, '']]]
107
+ end
108
+ end
109
+
110
+ def rewrite_fcall_trim(args)
111
+ if args.length == 2
112
+ [:call, args.second, :strip]
113
+ elsif args.length == 3
114
+ regex = [:lit, eval(Regexp.new("^[#{args.third.last}]+|[#{args.third.last}]+$").inspect)]
115
+ [:call, args.second, :gsub, [:array, regex, [:str, '']]]
116
+ end
117
+ end
118
+
119
+ def rewrite_fcall_ucfirst(args)
120
+ [:call, args.second, :capitalize]
121
+ end
122
+
123
+ def rewrite_fcall_strtolower(args)
124
+ [:call, args.second, :downcase]
125
+ end
126
+
127
+ def rewrite_fcall_strtoupper(args)
128
+ [:call, args.second, :upcase]
129
+ end
130
+
131
+ def rewrite_fcall_strtr(args)
132
+ [:call, args.second, :tr, [:array, args.third, args.fourth]]
133
+ end
134
+
135
+ def rewrite_fcall_strpos(args)
136
+ [:call, args.second, :index, [:array, args.third]]
137
+ end
138
+
139
+ def rewrite_fcall_strrpos(args)
140
+ [:call, args.second, :rindex, [:array, args.third]]
141
+ end
142
+
143
+ def rewrite_fcall_substr(args)
144
+ if args.length == 4
145
+ [:call, args.second, :slice, [:array, args.third, args.fourth]]
146
+ elsif args.length == 3
147
+ single_arg = args.third.last
148
+ if single_arg < 0
149
+ positive_arg = [:lit, (-single_arg)]
150
+ [:call, args.second, :slice, [:array, args.third, positive_arg]]
151
+ else
152
+ range = [:lit, eval(single_arg.to_s + "..-1")]
153
+ [:call, args.second, :slice, [:array, range]]
154
+ end
155
+ end
156
+ end
157
+
158
+ # string replacement
159
+
160
+ def rewrite_fcall_substr_replace(args)
161
+ if args.length == 5
162
+ [:attrasgn, args.second, :[]=, [:array, args.fourth, args.fifth, args.third]]
163
+ elsif args.length == 4
164
+ single_arg = args.fourth.last
165
+ range = [:lit, eval(single_arg.to_s + "..-1")]
166
+ [:attrasgn, args.second, :[]=, [:array, range, args.third]]
167
+ end
168
+ end
169
+
170
+ def rewrite_fcall_str_replace(args)
171
+ [:call, args.fourth, :gsub, [:array, args.second, args.third]]
172
+ end
173
+
174
+ def rewrite_fcall_str_ireplace(args)
175
+ regex = [:lit, eval(Regexp.new(args.second.last, Regexp::IGNORECASE).inspect)]
176
+ [:call, args.fourth, :gsub, [:array, regex, args.third]]
177
+ end
178
+
179
+ def rewrite_fcall_preg_replace(args)
180
+ regex = [:lit, eval(args.second.last)]
181
+ [:call, args.fourth, :gsub, [:array, regex, args.third]]
182
+ end
183
+
184
+ def rewrite_fcall_preg_split(args)
185
+ regex = [:lit, eval(args.second.last)]
186
+ [:call, args.third, :split, [:array, regex]]
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end