forked from txus/mutant
/
literal.rb
134 lines (111 loc) · 2.55 KB
/
literal.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
module Mutant
class Literal
def self.literal_class(node)
const_get(node.class.basename)
end
def initialize(node)
@node = node
@class = self.class.literal_class(node)
end
def swap
@class.new(@node).swap
end
class BaseLiteral
def initialize(node)
@node = node
end
end
class FalseLiteral < BaseLiteral
def swap
Rubinius::AST::TrueLiteral.new(@node.line)
end
end
class TrueLiteral < BaseLiteral
def swap
Rubinius::AST::FalseLiteral.new(@node.line)
end
end
class SymbolLiteral < BaseLiteral
def swap
@node.value = Random.symbol
@node
end
end
class StringLiteral < BaseLiteral
def swap
@node.string = Random.string
@node
end
end
class FixnumLiteral < BaseLiteral
def swap
@node.value = Random.fixnum
@node
end
end
class FloatLiteral < BaseLiteral
def swap
@node.value = Random.float
@node
end
end
class Range < BaseLiteral
def swap
range = Random.range
@node.start = Rubinius::AST::FixnumLiteral.new(@node.line, range.min)
@node.finish = Rubinius::AST::FixnumLiteral.new(@node.line, range.max)
@node
end
end
class RegexLiteral < BaseLiteral
def swap
@node.source = Regexp.escape(Random.string)
@node
end
end
class ArrayLiteral < BaseLiteral
def swap
@node.body = @node.body.reverse[1..-1]
@node
end
end
class HashLiteral < BaseLiteral
def swap
new_body = @node.array.each_slice(2).inject([]) do |body, (key, value)|
new_value = literal_class(value).new(value.clone).swap
body << key << new_value
end
@node.array = new_body
@node
end
private
def literal_class(value)
Module.nesting[1].literal_class(value)
end
end
class LocalVariableAssignment < BaseLiteral
def swap
@node.value = literal_class.new(@node.value.clone).swap
@node
end
private
def literal_class
Module.nesting[1].literal_class(@node.value)
end
end
class If < BaseLiteral
def swap
@node.body, @node.else = @node.else, @node.body
@node
end
end
class Send < BaseLiteral
def swap
line = @node.line
@node = Rubinius::AST::NilLiteral.new(line)
@node
end
end
SendWithArguments = Send
end
end