ifdef 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +3 -0
- data/bin/ifdef +52 -0
- data/ifdef.gemspec +23 -0
- data/lib/ifdef.rb +13 -0
- data/lib/ifdef/logic_processor.rb +138 -0
- data/lib/ifdef/rewriter.rb +24 -0
- data/lib/ifdef/truth.rb +37 -0
- data/lib/ifdef/version.rb +3 -0
- data/spec/data/ambiguous_if_statement/output.rb +7 -0
- data/spec/data/ambiguous_if_statement/source.rb +7 -0
- data/spec/data/ambiguous_if_statement/truth.json +3 -0
- data/spec/data/deeply_nested/output.rb +13 -0
- data/spec/data/deeply_nested/source.rb +13 -0
- data/spec/data/deeply_nested/truth.json +3 -0
- data/spec/data/elsif_statement/output.rb +9 -0
- data/spec/data/elsif_statement/source.rb +9 -0
- data/spec/data/elsif_statement/truth.json +4 -0
- data/spec/data/if_statement/output.rb +5 -0
- data/spec/data/if_statement/source.rb +5 -0
- data/spec/data/if_statement/truth.json +3 -0
- data/spec/data/inline_if_statement/output.rb +2 -0
- data/spec/data/inline_if_statement/source.rb +2 -0
- data/spec/data/inline_if_statement/truth.json +4 -0
- data/spec/data/inline_unless_statement/output.rb +2 -0
- data/spec/data/inline_unless_statement/source.rb +2 -0
- data/spec/data/inline_unless_statement/truth.json +4 -0
- data/spec/data/multiple_truth_statements/output.rb +11 -0
- data/spec/data/multiple_truth_statements/source.rb +11 -0
- data/spec/data/multiple_truth_statements/truth.json +3 -0
- data/spec/data/overlapping/output.rb +5 -0
- data/spec/data/overlapping/source.rb +9 -0
- data/spec/data/overlapping/truth.json +4 -0
- data/spec/data/ternary_statement/output.rb +2 -0
- data/spec/data/ternary_statement/source.rb +2 -0
- data/spec/data/ternary_statement/truth.json +4 -0
- data/spec/data/truth.json +4 -0
- data/spec/data/unless_statement/output.rb +5 -0
- data/spec/data/unless_statement/source.rb +5 -0
- data/spec/data/unless_statement/truth.json +3 -0
- data/spec/ifdef/logic_processor_spec.rb +118 -0
- data/spec/ifdef/rewriter_spec.rb +65 -0
- data/spec/ifdef/truth_spec.rb +38 -0
- data/spec/ifdef_spec.rb +9 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8f540bacd021264f26409fec0ce3e0aa9c924272
|
4
|
+
data.tar.gz: 1ac88926ae1d7a303c5b9728d13cb5750700a06c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 39bd24a2be9850beb8ae571f7d29f3369e950ddcca098485e0c3939db213b32769e7948b240d53aa93e7caf7784db6184a66b8230a886f6ecdcb3677154c3fea
|
7
|
+
data.tar.gz: 076ade530eff83823ae239f2ea39e36bba476f18acdf2c827a5c139969d2837e20b354d29d8c148804f8330b7327a35b831f3040ff701e8328147877a01ed8fe
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/bin/ifdef
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
3
|
+
|
4
|
+
begin
|
5
|
+
# Silence Parser version warnings
|
6
|
+
require "stringio"
|
7
|
+
stderr_bak, $stderr = $stderr, StringIO.new
|
8
|
+
require "parser/current"
|
9
|
+
ensure
|
10
|
+
$stderr = stderr_bak
|
11
|
+
end
|
12
|
+
require "optparse"
|
13
|
+
require "ifdef"
|
14
|
+
|
15
|
+
truth = {
|
16
|
+
"true" => [],
|
17
|
+
"false" => []
|
18
|
+
}
|
19
|
+
|
20
|
+
optparser = OptionParser.new do |opts|
|
21
|
+
opts.banner = "Usage: ifdef [options] file"
|
22
|
+
|
23
|
+
opts.on("-a", "--true", "=MANDATORY", Array, "A comma separated list of statements to treat as true") do |t|
|
24
|
+
truth["true"] += t
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on("-b", "--false", "=MANDATORY", Array, "A comma separated list of statements to treat as false") do |f|
|
28
|
+
truth["false"] += f
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on("-c", "--config", "=MANDATORY", String, "The path to a JSON truth config file") do |c|
|
32
|
+
truth.merge!(JSON.parse(File.read(c)))
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
36
|
+
puts opts
|
37
|
+
exit
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
optparser.parse!
|
42
|
+
|
43
|
+
abort(optparser.help) unless file = ARGV.first
|
44
|
+
source = File.read(file)
|
45
|
+
ast = Ifdef.parse(source)
|
46
|
+
buffer = Parser::Source::Buffer.new(file)
|
47
|
+
buffer.source = source
|
48
|
+
|
49
|
+
truth = Ifdef::Truth.parse_hash(truth)
|
50
|
+
rewriter = Ifdef::Rewriter.new(truth)
|
51
|
+
|
52
|
+
puts rewriter.rewrite(buffer, ast)
|
data/ifdef.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
$:.unshift File.expand_path('../lib', __FILE__)
|
3
|
+
require 'ifdef/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "ifdef"
|
7
|
+
spec.version = Ifdef::VERSION
|
8
|
+
spec.authors = ["Ben Toews"]
|
9
|
+
spec.email = ["mastahyeti@gmail.com"]
|
10
|
+
spec.homepage = "https://github.com/mastahyeti/ifdef"
|
11
|
+
spec.summary = "Ruby rewriter to replace false logic branches"
|
12
|
+
spec.description = "Parse source code, looking for conditional statements and replace brances that are known to be false."
|
13
|
+
spec.licenses = ["MIT"]
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = ["ifdef"]
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_dependency "parser", "~> 2.2"
|
20
|
+
|
21
|
+
spec.add_development_dependency "rspec", "~> 3.1"
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
23
|
+
end
|
data/lib/ifdef.rb
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
module Ifdef
|
2
|
+
class LogicProcessor < Parser::AST::Processor
|
3
|
+
class LogicError < StandardError; end
|
4
|
+
|
5
|
+
def initialize(truth)
|
6
|
+
@truth = truth
|
7
|
+
end
|
8
|
+
|
9
|
+
# Evaluate a logical statement and reduce it to true/false if we know
|
10
|
+
# enough to do so.
|
11
|
+
#
|
12
|
+
# ast - the AST to evaluate.
|
13
|
+
#
|
14
|
+
# Returns true if we know the statement to be :true, :false if we know the
|
15
|
+
# statement to be false, and nil otherwise.
|
16
|
+
def result(ast)
|
17
|
+
case @truth.fetch(ast, process(ast))
|
18
|
+
when :true
|
19
|
+
:true
|
20
|
+
when :false
|
21
|
+
:false
|
22
|
+
else
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Handle the `||` statement.
|
28
|
+
#
|
29
|
+
# node - the node to evaluate.
|
30
|
+
#
|
31
|
+
# Returns :true if either side is known to be true, :false if both sides are
|
32
|
+
# known to be false, and nil otherwise.
|
33
|
+
def on_or(node)
|
34
|
+
a, b = node.children.map { |c| @truth.fetch(c, process(c)) }
|
35
|
+
|
36
|
+
if a == :true || b == :true
|
37
|
+
:true
|
38
|
+
elsif a == :false && b == :false
|
39
|
+
:false
|
40
|
+
else
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Handle the `&&` statement.
|
46
|
+
#
|
47
|
+
# node - the node to evaluate.
|
48
|
+
#
|
49
|
+
# Returns :true if both sides are known to be true, :false if either sides
|
50
|
+
# is known to be false, and nil otherwise.
|
51
|
+
def on_and(node)
|
52
|
+
a, b = node.children.map { |c| @truth.fetch(c, process(c)) }
|
53
|
+
|
54
|
+
if a == :true && b == :true
|
55
|
+
:true
|
56
|
+
elsif a == :false || b == :false
|
57
|
+
:false
|
58
|
+
else
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Handles the `!` statement.
|
64
|
+
#
|
65
|
+
#
|
66
|
+
# node - the node to evaluate.
|
67
|
+
#
|
68
|
+
# Returns the inverse of the child expression.
|
69
|
+
def on_send(node)
|
70
|
+
_target, _method, _args = node.children
|
71
|
+
|
72
|
+
if _method == :!
|
73
|
+
case @truth.fetch(_target, process(_target))
|
74
|
+
when :true
|
75
|
+
:false
|
76
|
+
when :false
|
77
|
+
:true
|
78
|
+
else
|
79
|
+
nil
|
80
|
+
end
|
81
|
+
else
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Handle logic statements explicitly wrapped in parenthesis.
|
87
|
+
#
|
88
|
+
# node - the node to evaluate.
|
89
|
+
#
|
90
|
+
# Returns the result of the statement within the parenthesis.
|
91
|
+
def on_begin(node)
|
92
|
+
child, other_children = *node.children
|
93
|
+
|
94
|
+
# Not sure if this can happen in an `if` statement
|
95
|
+
raise LogicError if other_children
|
96
|
+
|
97
|
+
case @truth.fetch(child, process(child))
|
98
|
+
when :true
|
99
|
+
:true
|
100
|
+
when :false
|
101
|
+
:false
|
102
|
+
else
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Handle the `true` statement.
|
108
|
+
#
|
109
|
+
# node - the node to evaluate.
|
110
|
+
#
|
111
|
+
# Returns :true
|
112
|
+
def on_true(node)
|
113
|
+
:true
|
114
|
+
end
|
115
|
+
|
116
|
+
# Handle the `false` statement.
|
117
|
+
#
|
118
|
+
# node - the node to evaluate.
|
119
|
+
#
|
120
|
+
# Returns :false
|
121
|
+
def on_false(node)
|
122
|
+
:false
|
123
|
+
end
|
124
|
+
|
125
|
+
# Handle the `nil` statement.
|
126
|
+
#
|
127
|
+
# node - the node to evaluate.
|
128
|
+
#
|
129
|
+
# Returns :false
|
130
|
+
def on_nil(node)
|
131
|
+
:false
|
132
|
+
end
|
133
|
+
|
134
|
+
def node?(object)
|
135
|
+
object.is_a?(Parser::AST::Node)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Ifdef
|
2
|
+
class Rewriter < ::Parser::Rewriter
|
3
|
+
def initialize(truth)
|
4
|
+
@logic_processor = LogicProcessor.new(truth)
|
5
|
+
super()
|
6
|
+
end
|
7
|
+
|
8
|
+
def on_if(node)
|
9
|
+
_if, _then, _else = *node.children
|
10
|
+
|
11
|
+
case @logic_processor.result(_if)
|
12
|
+
when :true
|
13
|
+
process(_then) if _then
|
14
|
+
replace(_else.loc.expression, "nil") if _else
|
15
|
+
when :false
|
16
|
+
process(_else) if _else
|
17
|
+
replace(_then.loc.expression, "nil") if _then
|
18
|
+
else
|
19
|
+
process(_then) if _then
|
20
|
+
process(_else) if _else
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/ifdef/truth.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Ifdef
|
2
|
+
module Truth
|
3
|
+
# Loads and parseds a truth-hash from a JSON file.
|
4
|
+
#
|
5
|
+
# path - The path of the JSON file.
|
6
|
+
#
|
7
|
+
# Returns a Hash.
|
8
|
+
def load_json(path)
|
9
|
+
parse_hash(JSON.parse(File.read(path)))
|
10
|
+
end
|
11
|
+
|
12
|
+
# Convert a Hash like:
|
13
|
+
#
|
14
|
+
# { "true" => ["statement1", "statement2"], "false" => "statement3"}
|
15
|
+
#
|
16
|
+
# to a Hash like:
|
17
|
+
#
|
18
|
+
# {
|
19
|
+
# s(:send, nil, :statement1) => :true,
|
20
|
+
# s(:send, nil, :statement2) => :true,
|
21
|
+
# s(:send, nil, :statement3) => :false
|
22
|
+
# }
|
23
|
+
#
|
24
|
+
# hash - The Hash to convert.
|
25
|
+
#
|
26
|
+
# Returns a new Hash.
|
27
|
+
def parse_hash(hash)
|
28
|
+
hash.each_with_object({}) do |(key, values), new_hash|
|
29
|
+
Array(values).each do |value|
|
30
|
+
new_hash[Ifdef.parse(value)] = key.to_sym
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
extend self
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require "ifdef"
|
2
|
+
|
3
|
+
describe Ifdef::LogicProcessor, "#result" do
|
4
|
+
include AST::Sexp
|
5
|
+
|
6
|
+
subject do
|
7
|
+
Ifdef::LogicProcessor.new(
|
8
|
+
Ifdef.parse("true_statement") => :true,
|
9
|
+
Ifdef.parse("false_statement") => :false,
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
def result(statement)
|
14
|
+
subject.result(Ifdef.parse(statement))
|
15
|
+
end
|
16
|
+
|
17
|
+
it "handles basic statements" do
|
18
|
+
expect(result("true_statement")).to eq(:true)
|
19
|
+
expect(result("false_statement")).to eq(:false)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "follows basic logic for &&" do
|
23
|
+
expect(result("true && true")).to eq(:true)
|
24
|
+
expect(result("true && false")).to eq(:false)
|
25
|
+
expect(result("false && true")).to eq(:false)
|
26
|
+
expect(result("false && false")).to eq(:false)
|
27
|
+
|
28
|
+
expect(result("true_statement && true")).to eq(:true)
|
29
|
+
expect(result("true_statement && false")).to eq(:false)
|
30
|
+
expect(result("false_statement && true")).to eq(:false)
|
31
|
+
expect(result("false_statement && false")).to eq(:false)
|
32
|
+
|
33
|
+
expect(result("true && true_statement")).to eq(:true)
|
34
|
+
expect(result("true && false_statement")).to eq(:false)
|
35
|
+
expect(result("false && true_statement")).to eq(:false)
|
36
|
+
expect(result("false && false_statement")).to eq(:false)
|
37
|
+
|
38
|
+
expect(result("true_statement && true_statement")).to eq(:true)
|
39
|
+
expect(result("true_statement && false_statement")).to eq(:false)
|
40
|
+
expect(result("false_statement && true_statement")).to eq(:false)
|
41
|
+
expect(result("false_statement && false_statement")).to eq(:false)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "follows basic logic for ||" do
|
45
|
+
expect(result("true || true")).to eq(:true)
|
46
|
+
expect(result("true || false")).to eq(:true)
|
47
|
+
expect(result("false || true")).to eq(:true)
|
48
|
+
expect(result("false || false")).to eq(:false)
|
49
|
+
|
50
|
+
expect(result("true_statement || true")).to eq(:true)
|
51
|
+
expect(result("true_statement || false")).to eq(:true)
|
52
|
+
expect(result("false_statement || true")).to eq(:true)
|
53
|
+
expect(result("false_statement || false")).to eq(:false)
|
54
|
+
|
55
|
+
expect(result("true || true_statement")).to eq(:true)
|
56
|
+
expect(result("true || false_statement")).to eq(:true)
|
57
|
+
expect(result("false || true_statement")).to eq(:true)
|
58
|
+
expect(result("false || false_statement")).to eq(:false)
|
59
|
+
|
60
|
+
expect(result("true_statement || true_statement")).to eq(:true)
|
61
|
+
expect(result("true_statement || false_statement")).to eq(:true)
|
62
|
+
expect(result("false_statement || true_statement")).to eq(:true)
|
63
|
+
expect(result("false_statement || false_statement")).to eq(:false)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "follows basic logic for !" do
|
67
|
+
expect(result("!true")).to eq(:false)
|
68
|
+
expect(result("!false")).to eq(:true)
|
69
|
+
|
70
|
+
expect(result("!true_statement")).to eq(:false)
|
71
|
+
expect(result("!false_statement")).to eq(:true)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "chains logic for implicitly nested statements" do
|
75
|
+
expect(result("true && true && true")).to eq(:true)
|
76
|
+
expect(result("true && true && false")).to eq(:false)
|
77
|
+
|
78
|
+
expect(result("true || true || true")).to eq(:true)
|
79
|
+
expect(result("true || false || true")).to eq(:true)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "chains logic for explicitly nested statements" do
|
83
|
+
expect(result("true || (true || true)")).to eq(:true)
|
84
|
+
expect(result("true && (true || true)")).to eq(:true)
|
85
|
+
expect(result("true || (true && true)")).to eq(:true)
|
86
|
+
expect(result("true && (true && true)")).to eq(:true)
|
87
|
+
|
88
|
+
expect(result("false || (true || true)")).to eq(:true)
|
89
|
+
expect(result("false && (true || true)")).to eq(:false)
|
90
|
+
expect(result("false || (true && true)")).to eq(:true)
|
91
|
+
expect(result("false && (true && true)")).to eq(:false)
|
92
|
+
|
93
|
+
expect(result("true || (false || true)")).to eq(:true)
|
94
|
+
expect(result("true && (false || true)")).to eq(:true)
|
95
|
+
expect(result("true || (false && true)")).to eq(:true)
|
96
|
+
expect(result("true && (false && true)")).to eq(:false)
|
97
|
+
|
98
|
+
expect(result("true || (true || false)")).to eq(:true)
|
99
|
+
expect(result("true && (true || false)")).to eq(:true)
|
100
|
+
expect(result("true || (true && false)")).to eq(:true)
|
101
|
+
expect(result("true && (true && false)")).to eq(:false)
|
102
|
+
|
103
|
+
expect(result("false || (false || true)")).to eq(:true)
|
104
|
+
expect(result("false && (false || true)")).to eq(:false)
|
105
|
+
expect(result("false || (false && true)")).to eq(:false)
|
106
|
+
expect(result("false && (false && true)")).to eq(:false)
|
107
|
+
|
108
|
+
expect(result("true || (false || false)")).to eq(:true)
|
109
|
+
expect(result("true && (false || false)")).to eq(:false)
|
110
|
+
expect(result("true || (false && false)")).to eq(:true)
|
111
|
+
expect(result("true && (false && false)")).to eq(:false)
|
112
|
+
|
113
|
+
expect(result("false || (false || false)")).to eq(:false)
|
114
|
+
expect(result("false && (false || false)")).to eq(:false)
|
115
|
+
expect(result("false || (false && false)")).to eq(:false)
|
116
|
+
expect(result("false && (false && false)")).to eq(:false)
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "ifdef"
|
2
|
+
|
3
|
+
describe Ifdef::Rewriter, "#process" do
|
4
|
+
def run_example(name)
|
5
|
+
example_dir = File.expand_path(File.join(__FILE__, "../../data/", name))
|
6
|
+
|
7
|
+
# What we're expecting the rewriter to output.
|
8
|
+
expected_output = File.read(File.join(example_dir, "output.rb"))
|
9
|
+
|
10
|
+
# The truth to assert on the example source.
|
11
|
+
truth = Ifdef::Truth.load_json(File.join(example_dir, "truth.json"))
|
12
|
+
|
13
|
+
# The source code to operate on.
|
14
|
+
source_path = File.join(example_dir, "source.rb")
|
15
|
+
source = File.read(source_path)
|
16
|
+
ast = Ifdef.parse(source)
|
17
|
+
buffer = Parser::Source::Buffer.new(source_path)
|
18
|
+
buffer.source = source
|
19
|
+
|
20
|
+
# Rewrite the source.
|
21
|
+
rewriter = Ifdef::Rewriter.new(truth)
|
22
|
+
actual_output = rewriter.rewrite(buffer, ast)
|
23
|
+
expect(actual_output).to eq(expected_output)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "replaces else branch in if statement with nil" do
|
27
|
+
run_example("if_statement")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "replaces then branch in unless statement with nil" do
|
31
|
+
run_example("unless_statement")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "replaces else branch in inline if statement with nil" do
|
35
|
+
run_example("inline_if_statement")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "replaces then branch in inline unless statement with nil" do
|
39
|
+
run_example("inline_unless_statement")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "replaces else branch in ternary statement with nil" do
|
43
|
+
run_example("ternary_statement")
|
44
|
+
end
|
45
|
+
|
46
|
+
it "finds statements nested in other code" do
|
47
|
+
run_example("deeply_nested")
|
48
|
+
end
|
49
|
+
|
50
|
+
it "if replaces false branches in elsif sections" do
|
51
|
+
run_example("elsif_statement")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "merges overlapping replacements" do
|
55
|
+
run_example("overlapping")
|
56
|
+
end
|
57
|
+
|
58
|
+
it "allows for multiple truth statements" do
|
59
|
+
run_example("multiple_truth_statements")
|
60
|
+
end
|
61
|
+
|
62
|
+
it "ignores if statements where truth is ambiguous" do
|
63
|
+
run_example("ambiguous_if_statement")
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "ifdef"
|
2
|
+
|
3
|
+
describe Ifdef::Truth, "#load_json" do
|
4
|
+
subject { Ifdef::Truth }
|
5
|
+
|
6
|
+
it "loads json files" do
|
7
|
+
path = File.expand_path("../../data/truth.json", __FILE__)
|
8
|
+
expect(subject.load_json(path)).to be_a(Hash)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe Ifdef::Truth, "#parse_hash" do
|
13
|
+
subject { Ifdef::Truth }
|
14
|
+
|
15
|
+
it "returns a hash whose values are :true/:false" do
|
16
|
+
hash = {
|
17
|
+
"true" => ["true_statement"]
|
18
|
+
}
|
19
|
+
subject.parse_hash(hash).values.each do |value|
|
20
|
+
expect(value).to eq(:true).or(:false)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns a hash whose keys are nodes" do
|
25
|
+
hash = {
|
26
|
+
"true" => ["true_statement"]
|
27
|
+
}
|
28
|
+
subject.parse_hash(hash).keys.each do |key|
|
29
|
+
expect(key).to be_a(Parser::AST::Node)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "allows strings or arrays as input hash values" do
|
34
|
+
with_string = subject.parse_hash("true" => "true_statement")
|
35
|
+
with_array = subject.parse_hash("true" => ["true_statement"])
|
36
|
+
expect(with_array).to eq(with_string)
|
37
|
+
end
|
38
|
+
end
|
data/spec/ifdef_spec.rb
ADDED
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ifdef
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Toews
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: parser
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.1'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.6'
|
55
|
+
description: Parse source code, looking for conditional statements and replace brances
|
56
|
+
that are known to be false.
|
57
|
+
email:
|
58
|
+
- mastahyeti@gmail.com
|
59
|
+
executables:
|
60
|
+
- ifdef
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- ".gitignore"
|
65
|
+
- Gemfile
|
66
|
+
- Gemfile.lock
|
67
|
+
- bin/ifdef
|
68
|
+
- ifdef.gemspec
|
69
|
+
- lib/ifdef.rb
|
70
|
+
- lib/ifdef/logic_processor.rb
|
71
|
+
- lib/ifdef/rewriter.rb
|
72
|
+
- lib/ifdef/truth.rb
|
73
|
+
- lib/ifdef/version.rb
|
74
|
+
- spec/data/ambiguous_if_statement/output.rb
|
75
|
+
- spec/data/ambiguous_if_statement/source.rb
|
76
|
+
- spec/data/ambiguous_if_statement/truth.json
|
77
|
+
- spec/data/deeply_nested/output.rb
|
78
|
+
- spec/data/deeply_nested/source.rb
|
79
|
+
- spec/data/deeply_nested/truth.json
|
80
|
+
- spec/data/elsif_statement/output.rb
|
81
|
+
- spec/data/elsif_statement/source.rb
|
82
|
+
- spec/data/elsif_statement/truth.json
|
83
|
+
- spec/data/if_statement/output.rb
|
84
|
+
- spec/data/if_statement/source.rb
|
85
|
+
- spec/data/if_statement/truth.json
|
86
|
+
- spec/data/inline_if_statement/output.rb
|
87
|
+
- spec/data/inline_if_statement/source.rb
|
88
|
+
- spec/data/inline_if_statement/truth.json
|
89
|
+
- spec/data/inline_unless_statement/output.rb
|
90
|
+
- spec/data/inline_unless_statement/source.rb
|
91
|
+
- spec/data/inline_unless_statement/truth.json
|
92
|
+
- spec/data/multiple_truth_statements/output.rb
|
93
|
+
- spec/data/multiple_truth_statements/source.rb
|
94
|
+
- spec/data/multiple_truth_statements/truth.json
|
95
|
+
- spec/data/overlapping/output.rb
|
96
|
+
- spec/data/overlapping/source.rb
|
97
|
+
- spec/data/overlapping/truth.json
|
98
|
+
- spec/data/ternary_statement/output.rb
|
99
|
+
- spec/data/ternary_statement/source.rb
|
100
|
+
- spec/data/ternary_statement/truth.json
|
101
|
+
- spec/data/truth.json
|
102
|
+
- spec/data/unless_statement/output.rb
|
103
|
+
- spec/data/unless_statement/source.rb
|
104
|
+
- spec/data/unless_statement/truth.json
|
105
|
+
- spec/ifdef/logic_processor_spec.rb
|
106
|
+
- spec/ifdef/rewriter_spec.rb
|
107
|
+
- spec/ifdef/truth_spec.rb
|
108
|
+
- spec/ifdef_spec.rb
|
109
|
+
homepage: https://github.com/mastahyeti/ifdef
|
110
|
+
licenses:
|
111
|
+
- MIT
|
112
|
+
metadata: {}
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubyforge_project:
|
129
|
+
rubygems_version: 2.2.2
|
130
|
+
signing_key:
|
131
|
+
specification_version: 4
|
132
|
+
summary: Ruby rewriter to replace false logic branches
|
133
|
+
test_files: []
|