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.
Files changed (52) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +11 -0
  3. data/Rakefile +76 -0
  4. data/VERSION +1 -0
  5. data/bin/xdry +4 -0
  6. data/lib/xdry.rb +18 -0
  7. data/lib/xdry/boxing.rb +212 -0
  8. data/lib/xdry/generators/ctor_from_field.rb +91 -0
  9. data/lib/xdry/generators/dealloc.rb +53 -0
  10. data/lib/xdry/generators/dictionary_coding.rb +129 -0
  11. data/lib/xdry/generators/field_from_property.rb +20 -0
  12. data/lib/xdry/generators/property-from-field.rb +22 -0
  13. data/lib/xdry/generators/storing_constructor.rb +72 -0
  14. data/lib/xdry/generators/synthesize.rb +25 -0
  15. data/lib/xdry/generators_support.rb +42 -0
  16. data/lib/xdry/parsing/driver.rb +106 -0
  17. data/lib/xdry/parsing/model.rb +272 -0
  18. data/lib/xdry/parsing/nodes.rb +260 -0
  19. data/lib/xdry/parsing/parsers.rb +166 -0
  20. data/lib/xdry/parsing/parts/selectors.rb +95 -0
  21. data/lib/xdry/parsing/parts/var_types.rb +66 -0
  22. data/lib/xdry/parsing/pos.rb +75 -0
  23. data/lib/xdry/parsing/scope_stack.rb +68 -0
  24. data/lib/xdry/parsing/scopes.rb +61 -0
  25. data/lib/xdry/parsing/scopes_support.rb +143 -0
  26. data/lib/xdry/patching/emitter.rb +60 -0
  27. data/lib/xdry/patching/insertion_points.rb +209 -0
  28. data/lib/xdry/patching/item_patchers.rb +74 -0
  29. data/lib/xdry/patching/patcher.rb +139 -0
  30. data/lib/xdry/run.rb +227 -0
  31. data/lib/xdry/support/enumerable_additions.rb +35 -0
  32. data/lib/xdry/support/string_additions.rb +27 -0
  33. data/lib/xdry/support/symbol_additions.rb +14 -0
  34. data/site/_config.yml +3 -0
  35. data/site/_example +9 -0
  36. data/site/_layouts/default.html +30 -0
  37. data/site/_plugins/example.rb +16 -0
  38. data/site/_plugins/highlight_unindent.rb +17 -0
  39. data/site/index.md +417 -0
  40. data/site/master.css +94 -0
  41. data/spec/boxing_spec.rb +80 -0
  42. data/spec/ctor_from_field_spec.rb +251 -0
  43. data/spec/dealloc_spec.rb +103 -0
  44. data/spec/dictionary_coding_spec.rb +132 -0
  45. data/spec/field_from_prop_spec.rb +72 -0
  46. data/spec/prop_from_field_spec.rb +39 -0
  47. data/spec/readme_samples_spec.rb +76 -0
  48. data/spec/spec.opts +3 -0
  49. data/spec/spec_helper.rb +53 -0
  50. data/spec/synthesize_spec.rb +94 -0
  51. data/xdry.gemspec +103 -0
  52. 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
@@ -0,0 +1,3 @@
1
+ --color
2
+ --diff unified
3
+ --backtrace
@@ -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