modelmaker 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/src/bin/modelmake ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'modelmaker'
4
+
5
+ ModelMaker::DefaultRunner.new().run()
@@ -0,0 +1,386 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'erb'
4
+
5
+ module ModelMaker
6
+ class Project
7
+ attr_accessor :name, :copyright, :class_prefix, :entities
8
+
9
+ def initialize
10
+ @entities = []
11
+ end
12
+
13
+ def add_entity(entity)
14
+ entity.project = self
15
+ @entities << entity
16
+ end
17
+ end
18
+
19
+ class ProjectBuilder
20
+ def initialize(project)
21
+ @project = project
22
+ end
23
+
24
+ def project(name)
25
+ @project.name = name
26
+ end
27
+
28
+ def class_prefix(prefix)
29
+ @project.class_prefix = prefix
30
+ end
31
+
32
+ def copyright(copyright)
33
+ @project.copyright = copyright
34
+ end
35
+
36
+ def object(name, &configuration)
37
+ builder = EntityBuilder.new(name, &configuration)
38
+ @project.add_entity(builder.entity)
39
+ end
40
+ end
41
+
42
+ class EntityBuilder
43
+ attr_reader :entity
44
+
45
+ def initialize(entity_name, &configuration)
46
+ @entity = Entity.new(entity_name)
47
+ instance_eval(&configuration)
48
+ end
49
+
50
+ def inherits(superclass)
51
+ @entity.superclass = superclass
52
+ end
53
+
54
+ def conforms_to(protocol)
55
+ @entity.protocols << protocol
56
+ end
57
+
58
+ # There was a way to do that better... "define_all" or something
59
+ def string(propname)
60
+ add_property(StringProperty.new(propname))
61
+ end
62
+
63
+ def int(propname)
64
+ add_property(IntegerProperty.new(propname))
65
+ end
66
+
67
+ def set(propname)
68
+ add_property(SetProperty.new(propname))
69
+ end
70
+
71
+ def url(propname)
72
+ add_property(UrlProperty.new(propname))
73
+ end
74
+
75
+ def array(propname)
76
+ add_property(ArrayProperty.new(propname))
77
+ end
78
+
79
+ def date(propname)
80
+ add_property(DateProperty.new(propname))
81
+ end
82
+
83
+ def add_property(property)
84
+ @entity.add_property(property)
85
+ end
86
+ end
87
+
88
+ class Entity
89
+ attr_reader :name
90
+ attr_accessor :superclass, :protocols, :project
91
+
92
+ def initialize(name)
93
+ @name = name
94
+
95
+ @superclass = 'NSObject'
96
+ @properties = {}
97
+ @protocols = []
98
+ end
99
+
100
+ def short_name
101
+ @name
102
+ end
103
+
104
+ def class_name
105
+ if @project
106
+ "#{@project.class_prefix}#{@name}"
107
+ else
108
+ @name
109
+ end
110
+ end
111
+
112
+ alias :name :class_name
113
+
114
+ def instance_name
115
+ name = @name.clone
116
+ name[0] = name[0].downcase
117
+ name
118
+ end
119
+
120
+ def add_property(property)
121
+ @properties[property.name] = property
122
+ end
123
+
124
+ def properties
125
+ @properties.values
126
+ end
127
+
128
+ def needs_init?
129
+ for property in properties do
130
+ if property.needs_init?
131
+ return true
132
+ end
133
+ end
134
+
135
+ return false
136
+ end
137
+ end
138
+
139
+ class Property
140
+ attr_reader :name
141
+
142
+ def initialize(name)
143
+ @name = name
144
+ end
145
+
146
+ def internal_type
147
+ type
148
+ end
149
+
150
+ def exposed_type
151
+ type
152
+ end
153
+
154
+ def internal_name
155
+ "_#{@name}"
156
+ end
157
+
158
+ def exposed_name
159
+ @name
160
+ end
161
+
162
+ def type
163
+ raise "Implement me, or override internal_type and external_type"
164
+ end
165
+
166
+ def needs_init?
167
+ false
168
+ end
169
+
170
+ def init_line
171
+ nil
172
+ end
173
+
174
+ def setter_signature
175
+ name = exposed_name.to_s
176
+ name[0] = name[0].upcase
177
+ "- (void)set#{name}:(#{exposed_type})#{exposed_name}"
178
+ end
179
+
180
+ def assignation_value
181
+ exposed_name
182
+ end
183
+ end
184
+
185
+ class StringProperty < Property
186
+ def type
187
+ 'NSString *'
188
+ end
189
+ end
190
+
191
+ class IntegerProperty < Property
192
+ def type
193
+ 'NSInteger'
194
+ end
195
+ end
196
+
197
+ class UrlProperty < Property
198
+ def type
199
+ 'NSURL *'
200
+ end
201
+ end
202
+
203
+ class DateProperty < Property
204
+ def type
205
+ 'NSDate *'
206
+ end
207
+ end
208
+
209
+ class SetProperty < Property
210
+ def internal_type
211
+ 'NSMutableSet *'
212
+ end
213
+
214
+ def exposed_type
215
+ 'NSSet *'
216
+ end
217
+
218
+ def needs_init?
219
+ true
220
+ end
221
+
222
+ def init_line
223
+ "#{internal_name} = [[NSMutableSet alloc] init]"
224
+ end
225
+
226
+ def assignation_value
227
+ "[[NSMutableSet alloc] initWithSet:#{exposed_name}]"
228
+ end
229
+ end
230
+
231
+ class ArrayProperty < Property
232
+ def internal_type
233
+ 'NSMutableArray *'
234
+ end
235
+
236
+ def exposed_type
237
+ 'NSArray *'
238
+ end
239
+
240
+ def needs_init?
241
+ true
242
+ end
243
+
244
+ def init_line
245
+ "#{internal_name} = [[NSMutableArray alloc] init]";
246
+ end
247
+
248
+ def assignation_value
249
+ "[[NSMutableArray alloc] initWithArray:#{exposed_name}]"
250
+ end
251
+ end
252
+
253
+ class DefaultRunner
254
+ attr_accessor :pathname
255
+
256
+ def initialize
257
+ @pathname = 'Model' # Look for a file 'Model' in this directory
258
+ end
259
+
260
+ def run
261
+ if not File.exists?(@pathname)
262
+ raise 'No "Model" file found in the current directory'
263
+ end
264
+
265
+ project = Project.new()
266
+ source = File.new(@pathname).read()
267
+
268
+ builder = ProjectBuilder.new(project)
269
+ builder.instance_eval(source, @pathname, 1)
270
+
271
+ generator = Source::Generator.new(project)
272
+ generator.generate()
273
+ end
274
+ end
275
+
276
+ module Source
277
+ class Generator
278
+ def initialize(project)
279
+ @project = project
280
+ end
281
+
282
+ def generate(target_directory='.')
283
+ for cls in renderers do
284
+ renderer = cls.new()
285
+
286
+ for entity in @project.entities
287
+ vars = TemplateVars.new()
288
+ vars.project = @project
289
+ vars.entity = entity
290
+
291
+ filename = renderer.generated_file(vars)
292
+ fullpath = File.join(target_directory, filename)
293
+ fhandle = File.new(fullpath, 'w')
294
+ fhandle.write(renderer.result(vars))
295
+ end
296
+ end
297
+ end
298
+
299
+ def renderers
300
+ [
301
+ HeaderRenderer,
302
+ ImplementationRenderer,
303
+ BuilderHeaderRenderer,
304
+ BuilderImplementationRenderer
305
+ ]
306
+ end
307
+ end
308
+
309
+ class TemplateVars
310
+ attr_accessor :entity, :project, :file
311
+
312
+ def get_binding
313
+ binding
314
+ end
315
+ end
316
+
317
+ class BaseRenderer
318
+ def template_file
319
+ raise 'Implement me'
320
+ end
321
+
322
+ def generated_file(template_vars)
323
+ raise 'Implement me'
324
+ end
325
+
326
+ def result(template_vars)
327
+ renderer.result(template_vars.get_binding)
328
+ end
329
+
330
+ def renderer
331
+ if not @renderer
332
+ mydir = File.dirname(__FILE__)
333
+ template_path = File.join(mydir, '../templates', template_file)
334
+ template = File.new(template_path).read()
335
+ @renderer = ERB.new(template, 0, '>')
336
+ end
337
+
338
+ @renderer
339
+ end
340
+ end
341
+
342
+ class HeaderRenderer < BaseRenderer
343
+ def template_file
344
+ 'header.erb'
345
+ end
346
+
347
+ def generated_file(template_vars)
348
+ "#{template_vars.entity.name}.h"
349
+ end
350
+ end
351
+
352
+ class ImplementationRenderer < BaseRenderer
353
+ def template_file
354
+ 'implementation.erb'
355
+ end
356
+
357
+ def generated_file(template_vars)
358
+ "#{template_vars.entity.name}.m"
359
+ end
360
+ end
361
+
362
+ class BuilderHeaderRenderer < BaseRenderer
363
+ def template_file
364
+ 'builder_header.erb'
365
+ end
366
+
367
+ def generated_file(template_vars)
368
+ "#{template_vars.entity.name}Builder.h"
369
+ end
370
+ end
371
+
372
+ class BuilderImplementationRenderer < BaseRenderer
373
+ def template_file
374
+ 'builder_implementation.erb'
375
+ end
376
+
377
+ def generated_file(template_vars)
378
+ "#{template_vars.entity.name}Builder.m"
379
+ end
380
+ end
381
+
382
+ class FileInfo
383
+ attr_accessor :pathname
384
+ end
385
+ end
386
+ end
@@ -0,0 +1,27 @@
1
+ //
2
+ // <%= entity.name %>Builder.h
3
+ // <%= project.name %>
4
+
5
+ <% if project.copyright %>
6
+ //
7
+ // Copyright (c) <%= project.copyright %>. All rights reserved.
8
+ <% end %>
9
+ //
10
+ // Generated by ModelMaker
11
+ // See http://github.com/aspyct/ModelMaker
12
+ //
13
+
14
+ #import <Foundation/Foundation.h>
15
+ #import "<%= entity.name %>.h"
16
+
17
+ @interface <%= entity.name %>Builder : NSObject
18
+
19
+ @property (readonly) <%= entity.name %> *<%= entity.instance_name %>;
20
+
21
+ - (id)init;
22
+
23
+ <% for property in entity.properties %>
24
+ <%= property.setter_signature %>;
25
+ <% end %>
26
+
27
+ @end
@@ -0,0 +1,36 @@
1
+ //
2
+ // <%= entity.name %>Builder.m
3
+ // <%= project.name %>
4
+
5
+ <% if project.copyright %>
6
+ //
7
+ // Copyright (c) <%= project.copyright %>. All rights reserved.
8
+ <% end %>
9
+ //
10
+ // Generated by ModelMaker
11
+ // See http://github.com/aspyct/ModelMaker
12
+ //
13
+
14
+ #import "<%= entity.name %>Builder.h"
15
+
16
+ @implementation <%= entity.name %>Builder
17
+
18
+ @synthesize <%= entity.instance_name %> = _<%= entity.instance_name %>;
19
+
20
+ - (id)init {
21
+ self = [super init];
22
+
23
+ if (self) {
24
+ _<%= entity.instance_name %> = [[<%= entity.name %> alloc] init];
25
+ }
26
+
27
+ return self;
28
+ }
29
+
30
+ <% for property in entity.properties %>
31
+ <%= property.setter_signature %> {
32
+ _<%= entity.instance_name %>-><%= property.internal_name %> = <%= property.assignation_value %>;
33
+ }
34
+
35
+ <% end %>
36
+ @end
@@ -0,0 +1,27 @@
1
+ //
2
+ // <%= entity.name %>.h
3
+ // <%= project.name %>
4
+
5
+ <% if project.copyright %>
6
+ //
7
+ // Copyright (c) <%= project.copyright %>. All rights reserved.
8
+ <% end %>
9
+ //
10
+ // Generated by ModelMaker
11
+ // See http://github.com/aspyct/ModelMaker
12
+ //
13
+
14
+ #import <Foundation/Foundation.h>
15
+
16
+ @interface <%= @entity.name %> : <%= @entity.superclass %> <%= '<' + @entity.protocols.join(', ') + '> ' if not @entity.protocols.empty? %>{
17
+ @package
18
+ <% for @property in @entity.properties %>
19
+ <%= @property.internal_type %> <%= @property.internal_name %>;
20
+ <% end %>
21
+ }
22
+
23
+ <% for @property in @entity.properties %>
24
+ @property (readonly) <%= @property.exposed_type %> <%= @property.exposed_name %>;
25
+ <% end %>
26
+
27
+ @end
@@ -0,0 +1,38 @@
1
+ //
2
+ // <%= entity.name %>.m
3
+ // <%= project.name %>
4
+
5
+ <% if project.copyright %>
6
+ //
7
+ // Copyright (c) <%= project.copyright %>. All rights reserved.
8
+ <% end %>
9
+ //
10
+ // Generated by ModelMaker
11
+ // See http://github.com/aspyct/ModelMaker
12
+ //
13
+
14
+ #import "<%= @entity.name %>.h"
15
+
16
+ @implementation <%= @entity.name %>
17
+
18
+
19
+ <% for @property in @entity.properties %>
20
+ @synthesize <%= @property.exposed_name %> = <%= @property.internal_name %>;
21
+ <% end %>
22
+
23
+ <% if @entity.needs_init? %>
24
+ - (id)init
25
+ {
26
+ self = [super init];
27
+
28
+ if (self) {
29
+ <% for @property in @entity.properties %><% if @property.needs_init? %>
30
+ <%= @property.init_line %>;
31
+ <% end %><% end %>
32
+ }
33
+
34
+ return self;
35
+ }
36
+
37
+ <% end %>
38
+ @end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: modelmaker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Antoine d'Otreppe
9
+ autorequire:
10
+ bindir: src/bin
11
+ cert_chain: []
12
+ date: 2012-10-16 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ! 'ModelMaker generates your model classes based on a simple ruby definition. '
15
+ email: a.dotreppe@aspyct.org
16
+ executables:
17
+ - modelmake
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - src/templates/builder_header.erb
22
+ - src/templates/builder_implementation.erb
23
+ - src/templates/header.erb
24
+ - src/templates/implementation.erb
25
+ - src/bin/modelmake
26
+ - src/lib/modelmaker.rb
27
+ homepage: https://github.com/aspyct/ModelMaker
28
+ licenses:
29
+ - MIT
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - src/lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 1.8.24
49
+ signing_key:
50
+ specification_version: 3
51
+ summary: Objective-C model class generator
52
+ test_files: []
53
+ has_rdoc: