xdry 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.
- data/LICENSE +20 -0
- data/README.md +11 -0
- data/Rakefile +76 -0
- data/VERSION +1 -0
- data/bin/xdry +4 -0
- data/lib/xdry.rb +18 -0
- data/lib/xdry/boxing.rb +212 -0
- data/lib/xdry/generators/ctor_from_field.rb +91 -0
- data/lib/xdry/generators/dealloc.rb +53 -0
- data/lib/xdry/generators/dictionary_coding.rb +129 -0
- data/lib/xdry/generators/field_from_property.rb +20 -0
- data/lib/xdry/generators/property-from-field.rb +22 -0
- data/lib/xdry/generators/storing_constructor.rb +72 -0
- data/lib/xdry/generators/synthesize.rb +25 -0
- data/lib/xdry/generators_support.rb +42 -0
- data/lib/xdry/parsing/driver.rb +106 -0
- data/lib/xdry/parsing/model.rb +272 -0
- data/lib/xdry/parsing/nodes.rb +260 -0
- data/lib/xdry/parsing/parsers.rb +166 -0
- data/lib/xdry/parsing/parts/selectors.rb +95 -0
- data/lib/xdry/parsing/parts/var_types.rb +66 -0
- data/lib/xdry/parsing/pos.rb +75 -0
- data/lib/xdry/parsing/scope_stack.rb +68 -0
- data/lib/xdry/parsing/scopes.rb +61 -0
- data/lib/xdry/parsing/scopes_support.rb +143 -0
- data/lib/xdry/patching/emitter.rb +60 -0
- data/lib/xdry/patching/insertion_points.rb +209 -0
- data/lib/xdry/patching/item_patchers.rb +74 -0
- data/lib/xdry/patching/patcher.rb +139 -0
- data/lib/xdry/run.rb +227 -0
- data/lib/xdry/support/enumerable_additions.rb +35 -0
- data/lib/xdry/support/string_additions.rb +27 -0
- data/lib/xdry/support/symbol_additions.rb +14 -0
- data/site/_config.yml +3 -0
- data/site/_example +9 -0
- data/site/_layouts/default.html +30 -0
- data/site/_plugins/example.rb +16 -0
- data/site/_plugins/highlight_unindent.rb +17 -0
- data/site/index.md +417 -0
- data/site/master.css +94 -0
- data/spec/boxing_spec.rb +80 -0
- data/spec/ctor_from_field_spec.rb +251 -0
- data/spec/dealloc_spec.rb +103 -0
- data/spec/dictionary_coding_spec.rb +132 -0
- data/spec/field_from_prop_spec.rb +72 -0
- data/spec/prop_from_field_spec.rb +39 -0
- data/spec/readme_samples_spec.rb +76 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +53 -0
- data/spec/synthesize_spec.rb +94 -0
- data/xdry.gemspec +103 -0
- metadata +141 -0
@@ -0,0 +1,132 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "dictionary coding generator" do
|
4
|
+
|
5
|
+
it "should implement dictionary coding" do
|
6
|
+
xdry :dict_coding, <<-END
|
7
|
+
@interface Foo {
|
8
|
+
// persistent
|
9
|
+
NSString *_something;
|
10
|
+
}
|
11
|
+
|
12
|
+
- (id)initWithDictionary:(NSDictionary *)dictionary;
|
13
|
+
|
14
|
+
@property(nonatomic, retain) NSString *something;
|
15
|
+
|
16
|
+
@end
|
17
|
+
|
18
|
+
// start impl
|
19
|
+
|
20
|
+
+ #define SomethingKey @"Something"
|
21
|
+
+
|
22
|
+
@implementation Foo
|
23
|
+
|
24
|
+
+ - (id)initWithDictionary:(NSDictionary *)dictionary {
|
25
|
+
+ if (self = [super init]) {
|
26
|
+
+ id somethingRaw = [dictionary objectForKey:SomethingKey];
|
27
|
+
+ if (somethingRaw != nil) {
|
28
|
+
+ _something = [somethingRaw copy];
|
29
|
+
+ }
|
30
|
+
+ }
|
31
|
+
+ return self;
|
32
|
+
+ }
|
33
|
+
+
|
34
|
+
+ - (NSDictionary *)dictionaryRepresentation {
|
35
|
+
+ NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
|
36
|
+
+ [dictionary setObject:_something forKey:SomethingKey];
|
37
|
+
+ return dictionary;
|
38
|
+
+ }
|
39
|
+
+
|
40
|
+
@end
|
41
|
+
END
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should reuse existing initWithDictionary: and dictionaryRepresentation methods" do
|
45
|
+
xdry :dict_coding, <<-END
|
46
|
+
@interface Foo {
|
47
|
+
// persistent
|
48
|
+
NSString *_something;
|
49
|
+
}
|
50
|
+
|
51
|
+
- (id)initWithDictionary:(NSDictionary *)dict;
|
52
|
+
|
53
|
+
@property(nonatomic, retain) NSString *something;
|
54
|
+
|
55
|
+
@end
|
56
|
+
|
57
|
+
// start impl
|
58
|
+
|
59
|
+
+ #define SomethingKey @"Something"
|
60
|
+
+
|
61
|
+
@implementation Foo
|
62
|
+
|
63
|
+
- (id)initWithDictionary:(NSDictionary *)dict {
|
64
|
+
if (self = [super init]) {
|
65
|
+
+ id somethingRaw = [dict objectForKey:SomethingKey];
|
66
|
+
+ if (somethingRaw != nil) {
|
67
|
+
+ _something = [somethingRaw copy];
|
68
|
+
+ }
|
69
|
+
}
|
70
|
+
return self;
|
71
|
+
}
|
72
|
+
|
73
|
+
- (NSDictionary *)dictionaryRepresentation {
|
74
|
+
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];"
|
75
|
+
+ [dictionary setObject:_something forKey:SomethingKey];
|
76
|
+
return dictionary;
|
77
|
+
}
|
78
|
+
|
79
|
+
@end
|
80
|
+
END
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should only add missing persistence code" do
|
84
|
+
xdry :dict_coding, <<-END
|
85
|
+
@interface Foo {
|
86
|
+
// persistent
|
87
|
+
NSString *_something;
|
88
|
+
NSString *_another;
|
89
|
+
}
|
90
|
+
|
91
|
+
- (id)initWithDictionary:(NSDictionary *)dict;
|
92
|
+
|
93
|
+
@property(nonatomic, retain) NSString *something;
|
94
|
+
|
95
|
+
@end
|
96
|
+
|
97
|
+
// start impl
|
98
|
+
|
99
|
+
// persistence keys
|
100
|
+
#define SomethingKey @"Something"
|
101
|
+
+ #define AnotherKey @"Another"
|
102
|
+
|
103
|
+
// other stuff
|
104
|
+
|
105
|
+
@implementation Foo
|
106
|
+
|
107
|
+
- (id)initWithDictionary:(NSDictionary *)dict {
|
108
|
+
if (self = [super init]) {
|
109
|
+
id somethingRaw = [dict objectForKey:SomethingKey];
|
110
|
+
if (somethingRaw != nil) {
|
111
|
+
_something = [somethingRaw copy];
|
112
|
+
}
|
113
|
+
+ id anotherRaw = [dict objectForKey:AnotherKey];
|
114
|
+
+ if (anotherRaw != nil) {
|
115
|
+
+ _another = [anotherRaw copy];
|
116
|
+
+ }
|
117
|
+
}
|
118
|
+
return self;
|
119
|
+
}
|
120
|
+
|
121
|
+
- (NSDictionary *)dictionaryRepresentation {
|
122
|
+
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];"
|
123
|
+
[dictionary setObject:_something forKey:SomethingKey];
|
124
|
+
+ [dictionary setObject:_another forKey:AnotherKey];
|
125
|
+
return dictionary;
|
126
|
+
}
|
127
|
+
|
128
|
+
@end
|
129
|
+
END
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "field from property generator" do
|
4
|
+
|
5
|
+
it "should add missing fields for declared properties" do
|
6
|
+
xdry :field_from_prop, <<-END
|
7
|
+
@interface Foo {
|
8
|
+
+ NSString *_something;
|
9
|
+
}
|
10
|
+
|
11
|
+
@property(nonatomic, retain) NSString *something;
|
12
|
+
|
13
|
+
@end
|
14
|
+
|
15
|
+
@implementation Foo
|
16
|
+
|
17
|
+
@end
|
18
|
+
END
|
19
|
+
end
|
20
|
+
|
21
|
+
it "shouldn't add fields that already exist" do
|
22
|
+
xdry :field_from_prop, <<-END
|
23
|
+
@interface Foo {
|
24
|
+
NSString *something;
|
25
|
+
}
|
26
|
+
|
27
|
+
@property(nonatomic, retain) NSString *something;
|
28
|
+
|
29
|
+
@end
|
30
|
+
|
31
|
+
@implementation Foo
|
32
|
+
|
33
|
+
@end
|
34
|
+
END
|
35
|
+
end
|
36
|
+
|
37
|
+
it "shouldn't add fields that already exist, even if they are prefixed" do
|
38
|
+
xdry :field_from_prop, <<-END
|
39
|
+
@interface Foo {
|
40
|
+
NSString *_something;
|
41
|
+
}
|
42
|
+
|
43
|
+
@property(nonatomic, retain) NSString *something;
|
44
|
+
|
45
|
+
@end
|
46
|
+
|
47
|
+
@implementation Foo
|
48
|
+
|
49
|
+
@end
|
50
|
+
END
|
51
|
+
end
|
52
|
+
|
53
|
+
it "shouldn't add a field if a getter exists" do
|
54
|
+
xdry :field_from_prop, <<-END
|
55
|
+
@interface Foo {
|
56
|
+
}
|
57
|
+
|
58
|
+
@property(nonatomic, retain) NSString *something;
|
59
|
+
|
60
|
+
@end
|
61
|
+
|
62
|
+
@implementation Foo
|
63
|
+
|
64
|
+
- (NSString *)something {
|
65
|
+
return @"foo";
|
66
|
+
}
|
67
|
+
|
68
|
+
@end
|
69
|
+
END
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "property from field generator" do
|
4
|
+
|
5
|
+
it "should add property for a field marked with a full-line marker" do
|
6
|
+
xdry :prop_from_field, <<-END
|
7
|
+
@interface Foo {
|
8
|
+
- !p
|
9
|
+
NSString *_something;
|
10
|
+
}
|
11
|
+
|
12
|
+
+ @property(nonatomic, retain) NSString *something;
|
13
|
+
+
|
14
|
+
@end
|
15
|
+
|
16
|
+
@implementation Foo
|
17
|
+
|
18
|
+
@end
|
19
|
+
END
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should add property for a field marked with an inline marker" do
|
23
|
+
xdry :prop_from_field, <<-END
|
24
|
+
@interface Foo {
|
25
|
+
- NSString *_something; !p
|
26
|
+
+ NSString *_something;
|
27
|
+
}
|
28
|
+
|
29
|
+
+ @property(nonatomic, retain) NSString *something;
|
30
|
+
+
|
31
|
+
@end
|
32
|
+
|
33
|
+
@implementation Foo
|
34
|
+
|
35
|
+
@end
|
36
|
+
END
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Properties Support" do
|
4
|
+
|
5
|
+
it "should add @property" do
|
6
|
+
xdry <<-END
|
7
|
+
@interface Foo {
|
8
|
+
- Bar *value; !p
|
9
|
+
+ Bar *value;
|
10
|
+
}
|
11
|
+
|
12
|
+
+ @property(nonatomic, retain) Bar *value;
|
13
|
+
+
|
14
|
+
@end
|
15
|
+
|
16
|
+
@implementation Foo
|
17
|
+
+
|
18
|
+
+ @synthesize value;
|
19
|
+
+
|
20
|
+
+ - (void)dealloc {
|
21
|
+
+ [value release], value = nil;
|
22
|
+
+ [super dealloc];
|
23
|
+
+ }
|
24
|
+
+
|
25
|
+
@end
|
26
|
+
END
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should add @property" do
|
30
|
+
xdry <<-END
|
31
|
+
@interface Foo {
|
32
|
+
// persistent
|
33
|
+
NSArray *_bars; // of Bar
|
34
|
+
}
|
35
|
+
@end
|
36
|
+
|
37
|
+
+ #define BarsKey @"Bars"
|
38
|
+
+
|
39
|
+
@implementation Foo
|
40
|
+
+
|
41
|
+
+ - (id)initWithDictionary:(NSDictionary *)dictionary {
|
42
|
+
+ if (self = [super init]) {
|
43
|
+
+ id barsRaw = [dictionary objectForKey:BarsKey];
|
44
|
+
+ if (barsRaw != nil) {
|
45
|
+
+ NSMutableArray *barsArray = [[NSMutableArray alloc] init];
|
46
|
+
+ for (NSDictionary *barsItemDictionary in (NSArray *) barsRaw) {
|
47
|
+
+ Bar *barsItem = [[Bar alloc] initWithDictionary:barsItemDictionary];
|
48
|
+
+ [barsArray addObject:barsItem];
|
49
|
+
+ [barsItem release];
|
50
|
+
+ }
|
51
|
+
+ _bars = barsArray;
|
52
|
+
+ }
|
53
|
+
+ }
|
54
|
+
+ return self;
|
55
|
+
+ }
|
56
|
+
+
|
57
|
+
+ - (NSDictionary *)dictionaryRepresentation {
|
58
|
+
+ NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
|
59
|
+
+ NSMutableArray *barsArray = [NSMutableArray array];
|
60
|
+
+ for (Bar *barsItem in _bars) {
|
61
|
+
+ [barsArray addObject:[barsItem dictionaryRepresentation]];
|
62
|
+
+ }
|
63
|
+
+ [dictionary setObject:barsArray forKey:BarsKey];
|
64
|
+
+ return dictionary;
|
65
|
+
+ }
|
66
|
+
+
|
67
|
+
+ - (void)dealloc {
|
68
|
+
+ [_bars release], _bars = nil;
|
69
|
+
+ [super dealloc];
|
70
|
+
+ }
|
71
|
+
+
|
72
|
+
@end
|
73
|
+
END
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'xdry'
|
4
|
+
require 'rspec'
|
5
|
+
require 'rspec/autorun'
|
6
|
+
|
7
|
+
def remove_common_indent content
|
8
|
+
first_line_indent = content.split("\n", 2).first.gsub(/\S.*$/, '')
|
9
|
+
content.gsub(/^#{first_line_indent}/, '')
|
10
|
+
end
|
11
|
+
|
12
|
+
def xdry gens, content=nil
|
13
|
+
if content.nil?
|
14
|
+
content = gens
|
15
|
+
gens = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
config = XDry::Config.new
|
19
|
+
config.verbose = ((ENV['VERBOSE'] || '0').to_i != 0)
|
20
|
+
|
21
|
+
unless gens.nil?
|
22
|
+
gens = [gens] if gens.is_a?(Symbol)
|
23
|
+
config.enable_only = gens.collect { |g| g.to_s.gsub('_', '-') }
|
24
|
+
end
|
25
|
+
|
26
|
+
first_line_indent = content.split("\n", 2).first.gsub(/\S.*$/, '')
|
27
|
+
deleted_indent = first_line_indent.sub(/\s\s$/, '-( |$)')
|
28
|
+
added_indent = first_line_indent.sub(/\s\s$/, "\\\\+( |$)")
|
29
|
+
|
30
|
+
orig_content = content.lines.select { |l| l =~ /^(#{first_line_indent}|#{deleted_indent})|^$/ }.join("")
|
31
|
+
new_content = content.lines.select { |l| l =~ /^(#{first_line_indent}|#{added_indent})|^$/ }.join("")
|
32
|
+
|
33
|
+
orig_content = orig_content.gsub(/^(#{first_line_indent}|#{deleted_indent})/, '')
|
34
|
+
new_content = new_content.gsub(/^(#{first_line_indent}|#{added_indent})/, '')
|
35
|
+
|
36
|
+
if config.verbose
|
37
|
+
puts "-" * 40
|
38
|
+
puts orig_content
|
39
|
+
puts "-" * 40
|
40
|
+
puts new_content
|
41
|
+
puts "-" * 40
|
42
|
+
end
|
43
|
+
|
44
|
+
result = XDry.test_run({'main.m' => orig_content}, config)['main.m']
|
45
|
+
result = orig_content if result.nil?
|
46
|
+
result = result.gsub("\t", " ") # tests use 2 spaces for indentation
|
47
|
+
|
48
|
+
result.should == new_content
|
49
|
+
end
|
50
|
+
|
51
|
+
RSpec.configure do |config|
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "@synthesize support" do
|
4
|
+
|
5
|
+
it "should handle empty input" do
|
6
|
+
xdry :synth, " "
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should add @synthesize when a @property exists" do
|
10
|
+
xdry :synth, <<-END
|
11
|
+
@interface Foo {
|
12
|
+
BOOL value;
|
13
|
+
}
|
14
|
+
@property BOOL value;
|
15
|
+
@end
|
16
|
+
|
17
|
+
@implementation Foo
|
18
|
+
+
|
19
|
+
+ @synthesize value;
|
20
|
+
+
|
21
|
+
@end
|
22
|
+
END
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should reuse existing whitespace when inserting the first @synthesize" do
|
26
|
+
xdry :synth, <<-END
|
27
|
+
@interface Foo {
|
28
|
+
BOOL value;
|
29
|
+
}
|
30
|
+
@property BOOL value;
|
31
|
+
@end
|
32
|
+
|
33
|
+
@implementation Foo
|
34
|
+
+
|
35
|
+
+ @synthesize value;
|
36
|
+
|
37
|
+
@end
|
38
|
+
END
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should add @synthesize after existing @synthesize if any" do
|
42
|
+
xdry :synth, <<-END
|
43
|
+
@interface Foo {
|
44
|
+
BOOL value;
|
45
|
+
}
|
46
|
+
@property BOOL value;
|
47
|
+
@end
|
48
|
+
|
49
|
+
@implementation Foo
|
50
|
+
|
51
|
+
@synthesize something;
|
52
|
+
@synthesize something_else;
|
53
|
+
+ @synthesize value;
|
54
|
+
|
55
|
+
@end
|
56
|
+
END
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should use field name in @synthesize if needed" do
|
60
|
+
xdry :synth, <<-END
|
61
|
+
@interface Foo {
|
62
|
+
BOOL _value;
|
63
|
+
}
|
64
|
+
@property BOOL value;
|
65
|
+
@end
|
66
|
+
|
67
|
+
@implementation Foo
|
68
|
+
|
69
|
+
@synthesize something;
|
70
|
+
+ @synthesize value=_value;
|
71
|
+
|
72
|
+
@end
|
73
|
+
END
|
74
|
+
end
|
75
|
+
|
76
|
+
it "shouldn't add @synthesize if a getter is already implemented" do
|
77
|
+
xdry :synth, <<-END
|
78
|
+
@interface Foo {
|
79
|
+
BOOL _value;
|
80
|
+
}
|
81
|
+
@property BOOL value;
|
82
|
+
@end
|
83
|
+
|
84
|
+
@implementation Foo
|
85
|
+
|
86
|
+
- (BOOL) value {
|
87
|
+
return _value;
|
88
|
+
}
|
89
|
+
|
90
|
+
@end
|
91
|
+
END
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|