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
data/site/master.css
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
/* @override file:///Users/andreyvit/Dropbox/projects/active/xdry/site/_site/master.css */
|
2
|
+
|
3
|
+
* { margin: 0px; padding: 0px; }
|
4
|
+
|
5
|
+
#container { margin: 0 auto; width: 900px; }
|
6
|
+
|
7
|
+
body { margin: 50px 20px; font: 16px 'PT Serif', arial, sans-serif; line-height: 24px; background: #fff; color: #222; }
|
8
|
+
|
9
|
+
h1, h2 { font-family: 'Pacifico', arial, sans-serif; color: #333; }
|
10
|
+
h1 { font-size: 40px; margin: 0px 0px 40px; line-height: 56px; }
|
11
|
+
h2 { font-size: 24px; margin: 30px 0px 0px; line-height: 42px; }
|
12
|
+
|
13
|
+
p { margin: 10px 0px 0px; }
|
14
|
+
|
15
|
+
ul { margin: 10px 0px; }
|
16
|
+
li { list-style-position: inside; }
|
17
|
+
|
18
|
+
pre { background: #f0f0ff; border: 1px solid #000; padding: 12px 20px; font: 14px Monaco, Menlo, monospace; line-height: 15px; }
|
19
|
+
pre, .highlight { margin: 20px 0px; }
|
20
|
+
.highlight pre { margin: 0px; }
|
21
|
+
|
22
|
+
a { color: #222; }
|
23
|
+
a:visited { color: #666; }
|
24
|
+
a:hover { color: #000; }
|
25
|
+
|
26
|
+
.example { }
|
27
|
+
.example:after { content: ""; display: block; clear: both; }
|
28
|
+
.example .highlight { float: left; width: 380px; margin-right: 10px; }
|
29
|
+
.example .highlight + .highlight { width: 510px; margin-right: 0px; }
|
30
|
+
.example .highlight:before { content: "Before"; font-size: 13px; line-height: 12px; }
|
31
|
+
.example .highlight + .highlight:before { content: "After"; }
|
32
|
+
.example pre { font-size: 12px; padding: 12px 10px; }
|
33
|
+
ul + .example .highlight { margin-top: 0px; }
|
34
|
+
|
35
|
+
.highlight { background: #ffffff; }
|
36
|
+
.highlight .c { color: #999988; font-style: italic } /* Comment */
|
37
|
+
/* .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
|
38
|
+
.highlight .k { font-weight: bold } /* Keyword */
|
39
|
+
.highlight .o { font-weight: bold } /* Operator */
|
40
|
+
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
|
41
|
+
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
|
42
|
+
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
|
43
|
+
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
|
44
|
+
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
|
45
|
+
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
|
46
|
+
.highlight .ge { font-style: italic } /* Generic.Emph */
|
47
|
+
.highlight .gr { color: #aa0000 } /* Generic.Error */
|
48
|
+
.highlight .gh { color: #999999 } /* Generic.Heading */
|
49
|
+
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
|
50
|
+
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
|
51
|
+
.highlight .go { color: #888888 } /* Generic.Output */
|
52
|
+
.highlight .gp { color: #555555 } /* Generic.Prompt */
|
53
|
+
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
54
|
+
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
|
55
|
+
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
|
56
|
+
.highlight .kc { font-weight: bold } /* Keyword.Constant */
|
57
|
+
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
|
58
|
+
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
|
59
|
+
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
|
60
|
+
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
|
61
|
+
.highlight .m { color: #009999 } /* Literal.Number */
|
62
|
+
.highlight .s { color: #d14 } /* Literal.String */
|
63
|
+
.highlight .na { color: #008080 } /* Name.Attribute */
|
64
|
+
.highlight .nb { color: #0086B3 } /* Name.Builtin */
|
65
|
+
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
|
66
|
+
.highlight .no { color: #008080 } /* Name.Constant */
|
67
|
+
.highlight .ni { color: #800080 } /* Name.Entity */
|
68
|
+
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
|
69
|
+
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
|
70
|
+
.highlight .nn { color: #555555 } /* Name.Namespace */
|
71
|
+
.highlight .nt { color: #000080 } /* Name.Tag */
|
72
|
+
.highlight .nv { color: #008080 } /* Name.Variable */
|
73
|
+
.highlight .ow { font-weight: bold } /* Operator.Word */
|
74
|
+
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
75
|
+
.highlight .mf { color: #009999 } /* Literal.Number.Float */
|
76
|
+
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
|
77
|
+
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
|
78
|
+
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
|
79
|
+
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
|
80
|
+
.highlight .sc { color: #d14 } /* Literal.String.Char */
|
81
|
+
.highlight .sd { color: #d14 } /* Literal.String.Doc */
|
82
|
+
.highlight .s2 { color: #d14 } /* Literal.String.Double */
|
83
|
+
.highlight .se { color: #d14 } /* Literal.String.Escape */
|
84
|
+
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
|
85
|
+
.highlight .si { color: #d14 } /* Literal.String.Interpol */
|
86
|
+
.highlight .sx { color: #d14 } /* Literal.String.Other */
|
87
|
+
.highlight .sr { color: #009926 } /* Literal.String.Regex */
|
88
|
+
.highlight .s1 { color: #d14 } /* Literal.String.Single */
|
89
|
+
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
|
90
|
+
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
|
91
|
+
.highlight .vc { color: #008080 } /* Name.Variable.Class */
|
92
|
+
.highlight .vg { color: #008080 } /* Name.Variable.Global */
|
93
|
+
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
|
94
|
+
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
|
data/spec/boxing_spec.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "boxing support" do
|
4
|
+
|
5
|
+
def box expected
|
6
|
+
expected = remove_common_indent(expected)
|
7
|
+
unless expected.lines.first.strip =~ %r,^- \(id\)box:\(([^)]+)\)(\w+) \{$,
|
8
|
+
raise StandardError, "Invalid first line: #{expected.lines.first}"
|
9
|
+
end
|
10
|
+
type_string, var_name = $1.strip, $2.strip
|
11
|
+
type = XDry::VarType.parse(type_string)
|
12
|
+
raise "Invalid variable type '#{type_string}'" if type.nil?
|
13
|
+
boxer = XDry::Boxing.converter_for(type)
|
14
|
+
raise "No boxer available for variable type '#{type_string}'" if boxer.nil?
|
15
|
+
lines = XDry::Emitter.capture do |o|
|
16
|
+
o.block "- (id)box:(#{type.to_s})#{var_name}" do
|
17
|
+
o << "return " + boxer.box(o, var_name, "#{var_name}fix") + ";"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
result = lines.join("\n").gsub("\t", " ")
|
21
|
+
result.strip.should == expected.strip
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should box NSString verbatim" do
|
25
|
+
box <<-END
|
26
|
+
- (id)box:(NSString *)foo {
|
27
|
+
return foo;
|
28
|
+
}
|
29
|
+
END
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should box int via NSNumber" do
|
33
|
+
box <<-END
|
34
|
+
- (id)box:(int)foo {
|
35
|
+
return [NSNumber numberWithInt:foo];
|
36
|
+
}
|
37
|
+
END
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should box NSInteger via NSNumber" do
|
41
|
+
box <<-END
|
42
|
+
- (id)box:(NSInteger)foo {
|
43
|
+
return [NSNumber numberWithInteger:foo];
|
44
|
+
}
|
45
|
+
END
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should box float via NSNumber" do
|
49
|
+
box <<-END
|
50
|
+
- (id)box:(float)foo {
|
51
|
+
return [NSNumber numberWithFloat:foo];
|
52
|
+
}
|
53
|
+
END
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should box double via NSNumber" do
|
57
|
+
box <<-END
|
58
|
+
- (id)box:(double)foo {
|
59
|
+
return [NSNumber numberWithDouble:foo];
|
60
|
+
}
|
61
|
+
END
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should box NSTimeInterval as double via NSNumber" do
|
65
|
+
box <<-END
|
66
|
+
- (id)box:(NSTimeInterval)foo {
|
67
|
+
return [NSNumber numberWithDouble:foo];
|
68
|
+
}
|
69
|
+
END
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should box CGFloat as float via NSNumber" do
|
73
|
+
box <<-END
|
74
|
+
- (id)box:(CGFloat)foo {
|
75
|
+
return [NSNumber numberWithFloat:foo];
|
76
|
+
}
|
77
|
+
END
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,251 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "constructor from fields generator" do
|
4
|
+
|
5
|
+
it "should add a constructor for NSString *_something field marked with a full-line marker" do
|
6
|
+
xdry :ctor_from_field, <<-END
|
7
|
+
@interface Foo {
|
8
|
+
- !c
|
9
|
+
NSString *_something;
|
10
|
+
}
|
11
|
+
|
12
|
+
+ - (id)initWithSomething:(NSString *)something;
|
13
|
+
+
|
14
|
+
@end
|
15
|
+
|
16
|
+
@implementation Foo
|
17
|
+
+
|
18
|
+
+ - (id)initWithSomething:(NSString *)something {
|
19
|
+
+ if (self = [super init]) {
|
20
|
+
+ _something = [something copy];
|
21
|
+
+ }
|
22
|
+
+ return self;
|
23
|
+
+ }
|
24
|
+
|
25
|
+
@end
|
26
|
+
END
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should add a constructor for NSString *_something field marked with an inline marker" do
|
30
|
+
xdry :ctor_from_field, <<-END
|
31
|
+
@interface Foo {
|
32
|
+
- NSString *_something; !c
|
33
|
+
+ NSString *_something;
|
34
|
+
}
|
35
|
+
|
36
|
+
+ - (id)initWithSomething:(NSString *)something;
|
37
|
+
+
|
38
|
+
@end
|
39
|
+
|
40
|
+
@implementation Foo
|
41
|
+
+
|
42
|
+
+ - (id)initWithSomething:(NSString *)something {
|
43
|
+
+ if (self = [super init]) {
|
44
|
+
+ _something = [something copy];
|
45
|
+
+ }
|
46
|
+
+ return self;
|
47
|
+
+ }
|
48
|
+
|
49
|
+
@end
|
50
|
+
END
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should do nothing when a constructor already exists" do
|
54
|
+
xdry :ctor_from_field, <<-END
|
55
|
+
@interface Foo {
|
56
|
+
- NSString *_something; !c
|
57
|
+
+ NSString *_something;
|
58
|
+
}
|
59
|
+
|
60
|
+
- (id)initWithSomething:(NSString *)something;
|
61
|
+
|
62
|
+
@end
|
63
|
+
|
64
|
+
@implementation Foo
|
65
|
+
|
66
|
+
- (id)initWithSomething:(NSString *)something {
|
67
|
+
if (self = [super init]) {
|
68
|
+
_something = [something copy];
|
69
|
+
}
|
70
|
+
return self;
|
71
|
+
}
|
72
|
+
|
73
|
+
@end
|
74
|
+
END
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should add a missing interface declaration when an implementation already exists" do
|
78
|
+
xdry :ctor_from_field, <<-END
|
79
|
+
@interface Foo {
|
80
|
+
- NSString *_something; !c
|
81
|
+
+ NSString *_something;
|
82
|
+
}
|
83
|
+
+
|
84
|
+
+ - (id)initWithSomething:(NSString *)something;
|
85
|
+
|
86
|
+
@end
|
87
|
+
|
88
|
+
@implementation Foo
|
89
|
+
|
90
|
+
- (id)initWithSomething:(NSString *)something {
|
91
|
+
if (self = [super init]) {
|
92
|
+
_something = [something copy];
|
93
|
+
}
|
94
|
+
return self;
|
95
|
+
}
|
96
|
+
|
97
|
+
@end
|
98
|
+
END
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should add a missing implementation when an interface declaration already exists" do
|
102
|
+
xdry :ctor_from_field, <<-END
|
103
|
+
@interface Foo {
|
104
|
+
- NSString *_something; !c
|
105
|
+
+ NSString *_something;
|
106
|
+
}
|
107
|
+
|
108
|
+
- (id)initWithSomething:(NSString *)something;
|
109
|
+
|
110
|
+
@end
|
111
|
+
|
112
|
+
@implementation Foo
|
113
|
+
+
|
114
|
+
+ - (id)initWithSomething:(NSString *)something {
|
115
|
+
+ if (self = [super init]) {
|
116
|
+
+ _something = [something copy];
|
117
|
+
+ }
|
118
|
+
+ return self;
|
119
|
+
+ }
|
120
|
+
|
121
|
+
@end
|
122
|
+
END
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should use aSomething as arg name if a field is not prefixed" do
|
126
|
+
xdry :ctor_from_field, <<-END
|
127
|
+
@interface Foo {
|
128
|
+
- NSString *something; !c
|
129
|
+
+ NSString *something;
|
130
|
+
}
|
131
|
+
|
132
|
+
+ - (id)initWithSomething:(NSString *)something;
|
133
|
+
+
|
134
|
+
@end
|
135
|
+
|
136
|
+
@implementation Foo
|
137
|
+
+
|
138
|
+
+ - (id)initWithSomething:(NSString *)aSomething {
|
139
|
+
+ if (self = [super init]) {
|
140
|
+
+ something = [aSomething copy];
|
141
|
+
+ }
|
142
|
+
+ return self;
|
143
|
+
+ }
|
144
|
+
|
145
|
+
@end
|
146
|
+
END
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should use 'an' prefix if an unprefixed field name starts with a vowel" do
|
150
|
+
xdry :ctor_from_field, <<-END
|
151
|
+
@interface Foo {
|
152
|
+
- NSString *apple; !c
|
153
|
+
+ NSString *apple;
|
154
|
+
}
|
155
|
+
|
156
|
+
+ - (id)initWithApple:(NSString *)apple;
|
157
|
+
+
|
158
|
+
@end
|
159
|
+
|
160
|
+
@implementation Foo
|
161
|
+
+
|
162
|
+
+ - (id)initWithApple:(NSString *)anApple {
|
163
|
+
+ if (self = [super init]) {
|
164
|
+
+ apple = [anApple copy];
|
165
|
+
+ }
|
166
|
+
+ return self;
|
167
|
+
+ }
|
168
|
+
|
169
|
+
@end
|
170
|
+
END
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should add a missing assignment to an already defined implementation" do
|
174
|
+
xdry :ctor_from_field, <<-END
|
175
|
+
@interface Foo {
|
176
|
+
- NSString *something; !c
|
177
|
+
+ NSString *something;
|
178
|
+
}
|
179
|
+
|
180
|
+
- (id)initWithSomething:(NSString *)something;
|
181
|
+
|
182
|
+
@end
|
183
|
+
|
184
|
+
@implementation Foo
|
185
|
+
|
186
|
+
- (id)initWithSomething:(NSString *)aSomething {
|
187
|
+
if (self = [super init]) {
|
188
|
+
+ something = [aSomething copy];
|
189
|
+
}
|
190
|
+
return self;
|
191
|
+
}
|
192
|
+
|
193
|
+
@end
|
194
|
+
END
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should use self->something if the arg name == field name in an already defined implementation" do
|
198
|
+
xdry :ctor_from_field, <<-END
|
199
|
+
@interface Foo {
|
200
|
+
- NSString *something; !c
|
201
|
+
+ NSString *something;
|
202
|
+
}
|
203
|
+
|
204
|
+
- (id)initWithSomething:(NSString *)something;
|
205
|
+
|
206
|
+
@end
|
207
|
+
|
208
|
+
@implementation Foo
|
209
|
+
|
210
|
+
- (id)initWithSomething:(NSString *)something {
|
211
|
+
if (self = [super init]) {
|
212
|
+
+ self->something = [something copy];
|
213
|
+
}
|
214
|
+
return self;
|
215
|
+
}
|
216
|
+
|
217
|
+
@end
|
218
|
+
END
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should add a constructor for several fields" do
|
222
|
+
xdry :ctor_from_field, <<-END
|
223
|
+
@interface Foo {
|
224
|
+
- NSString *_foo; !c
|
225
|
+
- NSInteger _bar; !c
|
226
|
+
- Boz *_boz; !c
|
227
|
+
+ NSString *_foo;
|
228
|
+
+ NSInteger _bar;
|
229
|
+
+ Boz *_boz;
|
230
|
+
}
|
231
|
+
|
232
|
+
+ - (id)initWithFoo:(NSString *)foo bar:(NSInteger)bar boz:(Boz *)boz;
|
233
|
+
+
|
234
|
+
@end
|
235
|
+
|
236
|
+
@implementation Foo
|
237
|
+
+
|
238
|
+
+ - (id)initWithFoo:(NSString *)foo bar:(NSInteger)bar boz:(Boz *)boz {
|
239
|
+
+ if (self = [super init]) {
|
240
|
+
+ _foo = [foo copy];
|
241
|
+
+ _bar = bar;
|
242
|
+
+ _boz = [boz retain];
|
243
|
+
+ }
|
244
|
+
+ return self;
|
245
|
+
+ }
|
246
|
+
|
247
|
+
@end
|
248
|
+
END
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "dealloc support" do
|
4
|
+
|
5
|
+
it "should add missing release calls to dealloc" do
|
6
|
+
xdry :dealloc, <<-END
|
7
|
+
@interface Foo {
|
8
|
+
NSString *something;
|
9
|
+
}
|
10
|
+
@end
|
11
|
+
|
12
|
+
@implementation Foo
|
13
|
+
|
14
|
+
- (void)dealloc {
|
15
|
+
+ [something release], something = nil;
|
16
|
+
[super dealloc];
|
17
|
+
}
|
18
|
+
|
19
|
+
@end
|
20
|
+
END
|
21
|
+
end
|
22
|
+
|
23
|
+
it "shouldn't add release calls that already exist" do
|
24
|
+
xdry :dealloc, <<-END
|
25
|
+
@interface Foo {
|
26
|
+
NSString *something;
|
27
|
+
NSString *somethingElse;
|
28
|
+
}
|
29
|
+
@end
|
30
|
+
|
31
|
+
@implementation Foo
|
32
|
+
|
33
|
+
- (void)dealloc {
|
34
|
+
[something release];
|
35
|
+
+ [somethingElse release], somethingElse = nil;
|
36
|
+
[super dealloc];
|
37
|
+
}
|
38
|
+
|
39
|
+
@end
|
40
|
+
END
|
41
|
+
end
|
42
|
+
|
43
|
+
it "shouldn't add anything if all calls already exist" do
|
44
|
+
xdry :dealloc, <<-END
|
45
|
+
@interface Foo {
|
46
|
+
NSString *something;
|
47
|
+
NSString *somethingElse;
|
48
|
+
}
|
49
|
+
@end
|
50
|
+
|
51
|
+
@implementation Foo
|
52
|
+
|
53
|
+
- (void)dealloc {
|
54
|
+
[something release];
|
55
|
+
[somethingElse release], somethingElse = nil;
|
56
|
+
[super dealloc];
|
57
|
+
}
|
58
|
+
|
59
|
+
@end
|
60
|
+
END
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should detect self.foo = nil as a release call" do
|
64
|
+
xdry :dealloc, <<-END
|
65
|
+
@interface Foo {
|
66
|
+
NSString *something;
|
67
|
+
NSString *somethingElse;
|
68
|
+
}
|
69
|
+
@end
|
70
|
+
|
71
|
+
@implementation Foo
|
72
|
+
|
73
|
+
- (void)dealloc {
|
74
|
+
self.something = nil;
|
75
|
+
+ [somethingElse release], somethingElse = nil;
|
76
|
+
[super dealloc];
|
77
|
+
}
|
78
|
+
|
79
|
+
@end
|
80
|
+
END
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should add dealloc if it does not exist" do
|
84
|
+
xdry :dealloc, <<-END
|
85
|
+
@interface Foo {
|
86
|
+
NSString *something;
|
87
|
+
NSString *somethingElse;
|
88
|
+
}
|
89
|
+
@end
|
90
|
+
|
91
|
+
@implementation Foo
|
92
|
+
+
|
93
|
+
+ - (void)dealloc {
|
94
|
+
+ [something release], something = nil;
|
95
|
+
+ [somethingElse release], somethingElse = nil;
|
96
|
+
+ [super dealloc];
|
97
|
+
+ }
|
98
|
+
+
|
99
|
+
@end
|
100
|
+
END
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|