ifdef 0.0.1
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.
- 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: []
|