farleyknight-ionize 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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