guff 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt ADDED
File without changes
data/Manifest.txt ADDED
@@ -0,0 +1,21 @@
1
+ Rakefile
2
+ README.txt
3
+ CHANGELOG.txt
4
+ Manifest.txt
5
+ setup.rb
6
+ lib/guff/version.rb
7
+ lib/guff/java_source.rb
8
+ lib/guff.rb
9
+ test/test_helper.rb
10
+ test/java_source/files/ClassWithAnnotatedFields.java
11
+ test/java_source/files/ClassWithAnnotatedMethods.java
12
+ test/java_source/files/ClassWithFields.java
13
+ test/java_source/files/ClassWithMethods.java
14
+ test/java_source/files/EmptyClass.java
15
+ test/java_source/files/GenericClass.java
16
+ test/java_source/annotation_declaration_test.rb
17
+ test/java_source/class_declaration_test.rb
18
+ test/java_source/field_declaration_test.rb
19
+ test/java_source/method_declaration_test.rb
20
+ test/java_source/test_helper.rb
21
+ test/test_helper.rb
data/README.txt ADDED
@@ -0,0 +1,3 @@
1
+ README for guff
2
+ ===============
3
+
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ include FileUtils
12
+ require File.join(File.dirname(__FILE__), 'lib', 'guff', 'version')
13
+
14
+ AUTHOR = "Mike Hogan" # can also be an array of Authors
15
+ EMAIL = "me@mikehogan.net"
16
+ DESCRIPTION = "An API to describe and generate Java source code. The idea is to avoid writing all the 'guff' that is typical in java projects by generating it from more succinct ruby models."
17
+ GEM_NAME = "guff" # what ppl will type to install your gem
18
+ RUBYFORGE_PROJECT = "guff" # The unix name for your project
19
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
20
+
21
+
22
+ NAME = "guff"
23
+ REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
24
+ VERS = ENV['VERSION'] || (Guff::VERSION::STRING + (REV ? ".#{REV}" : ""))
25
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
26
+ RDOC_OPTS = ['--quiet', '--title', "guff documentation",
27
+ "--opname", "index.html",
28
+ "--line-numbers",
29
+ "--main", "README",
30
+ "--inline-source"]
31
+
32
+ class Hoe
33
+ def extra_deps
34
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
35
+ end
36
+ end
37
+
38
+ # Generate all the Rake tasks
39
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
40
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
41
+ p.author = AUTHOR
42
+ p.description = DESCRIPTION
43
+ p.email = EMAIL
44
+ p.summary = DESCRIPTION
45
+ p.url = HOMEPATH
46
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
47
+ p.test_globs = ["test/**/*_test.rb"]
48
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
49
+
50
+ # == Optional
51
+ #p.changes - A description of the release's latest changes.
52
+ #p.extra_deps - An array of rubygem dependencies.
53
+ #p.spec_extras - A hash of extra values to set in the gemspec.
54
+ end
@@ -0,0 +1,576 @@
1
+ require 'fileutils'
2
+
3
+ module ArgumentsHelper
4
+ def ensure_array(a)
5
+ if (a.respond_to? :[])
6
+ return a
7
+ end
8
+ [a]
9
+ end
10
+ end
11
+
12
+ class String
13
+ def ends_with?(s)
14
+ reverse.index(s) == 0
15
+ end
16
+ end
17
+
18
+ class Array
19
+ def each_joined(joiner)
20
+ last = size - 1
21
+ for i in 0..last
22
+ joiner.call if i > 0
23
+ yield self[i]
24
+ end
25
+ end
26
+ end
27
+
28
+ module Guff
29
+ module JavaSource
30
+
31
+ module ClientSyntaxSupport
32
+ def annotation(type)
33
+ a = Annotation.new(type)
34
+ yield a if block_given?
35
+ a
36
+ end
37
+ end
38
+
39
+ module AnnotationSupport
40
+ def add_annotation(type,value=nil)
41
+ annotation = Annotation.new(type,value)
42
+ @annotations << annotation
43
+ yield annotation if block_given?
44
+ self
45
+ end
46
+
47
+ def write_annotations_to(writer)
48
+ @annotations.each {|a|
49
+ a.write_to(writer)
50
+ writer.new_line
51
+ }
52
+ end
53
+ end
54
+
55
+ module ParameterSupport
56
+ def takes(name, type)
57
+ @parameters << Parameter.new(name, type)
58
+ self
59
+ end
60
+ end
61
+
62
+ module ScopeSupport
63
+ def package_local
64
+ @scope = ''
65
+ self
66
+ end
67
+
68
+ def protected
69
+ @scope = 'protected'
70
+ self
71
+ end
72
+
73
+ def public
74
+ @scope = 'public'
75
+ self
76
+ end
77
+
78
+ def private
79
+ @scope = 'private'
80
+ self
81
+ end
82
+ end
83
+
84
+ module ModifierSupport
85
+ def static
86
+ @modifiers << 'static'
87
+ self
88
+ end
89
+
90
+ def final
91
+ @modifiers << 'final'
92
+ self
93
+ end
94
+
95
+ def abstract
96
+ @modifiers << 'abstract'
97
+ self
98
+ end
99
+ end
100
+
101
+ class UnnamedProperty
102
+ def initialize(value)
103
+ @value = value
104
+ end
105
+
106
+ def write_to(writer)
107
+ write_value(writer)
108
+ end
109
+
110
+ def write_value(writer)
111
+ @value.write_to(writer) if @value.respond_to? :write_to
112
+ writer.append(@value) unless @value.respond_to? :write_to
113
+ self
114
+ end
115
+ end
116
+
117
+ class Property < UnnamedProperty
118
+ def initialize(name, value)
119
+ super(value)
120
+ @name = name
121
+ end
122
+
123
+ def write_to(writer)
124
+ writer.append(@name).append("=")
125
+ write_value(writer)
126
+ end
127
+ end
128
+
129
+ class Annotation
130
+ def initialize(type,value=nil)
131
+ @type = type
132
+ @properties = []
133
+ @properties << UnnamedProperty.new(value) unless value.nil?
134
+ end
135
+
136
+ def write_to(writer)
137
+ writer.append("@#{@type}")
138
+ write_properties_to(writer) unless @properties.empty?
139
+ end
140
+
141
+ def write_properties_to(writer)
142
+ writer.append("(").indent.new_line
143
+ joiner = proc {
144
+ writer.append(",").new_line
145
+ }
146
+ writer.append_all(@properties, joiner)
147
+ writer.outdent.new_line.append(")")
148
+ end
149
+
150
+ def add_property(name, value)
151
+ @properties << Property.new(name, value)
152
+ self
153
+ end
154
+ end
155
+
156
+ class Parameter
157
+ def initialize(n, t)
158
+ @name=n
159
+ @guff_type=t
160
+ end
161
+
162
+ def as_source
163
+ "#{guff_type} #{@name}"
164
+ end
165
+
166
+ def name
167
+ @name
168
+ end
169
+
170
+ def guff_type
171
+ @guff_type
172
+ end
173
+ end
174
+
175
+ class Constructor
176
+ include ArgumentsHelper, ParameterSupport, AnnotationSupport
177
+
178
+ def initialize(name)
179
+ @name = name
180
+ @parameters = []
181
+ @body = Body.default_body
182
+ @annotations = []
183
+ end
184
+
185
+ def body
186
+ @body = Body.new
187
+ yield @body
188
+ self
189
+ end
190
+
191
+ def parameters
192
+ result = []
193
+ @parameters.each {|p|
194
+ result << p.as_source
195
+ }
196
+ result.join(',')
197
+ end
198
+
199
+ def write_to(writer)
200
+ writer.ensure_member_separation_line
201
+ write_annotations_to(writer)
202
+ write_declaration(writer)
203
+ @body.write_to(writer) unless @body.nil?
204
+ end
205
+
206
+ def write_declaration(writer)
207
+ writer.append("public #{@name}(" ).append(parameters).append(")")
208
+ end
209
+ end
210
+
211
+ module BodyBits
212
+ class Line
213
+ def initialize(l)
214
+ @line = l
215
+ end
216
+
217
+ def write_to(writer)
218
+ writer.line(@line)
219
+ end
220
+ end
221
+
222
+ class Text
223
+ def initialize(t)
224
+ @text = t
225
+ end
226
+
227
+ def write_to(writer)
228
+ writer.append(@text)
229
+ end
230
+ end
231
+
232
+ class NestedBody
233
+ def initialize(body)
234
+ @body = body
235
+ end
236
+
237
+ def write_to(writer)
238
+ @body.write_to(writer)
239
+ end
240
+ end
241
+ end
242
+
243
+ class Body
244
+ def self.default_body
245
+ EmptyBody.new
246
+ end
247
+
248
+ def initialize
249
+ @bits = []
250
+ end
251
+
252
+ def line(l)
253
+ @bits << BodyBits::Line.new(l)
254
+ self
255
+ end
256
+
257
+ def append(t)
258
+ @bits << BodyBits::Text.new(t)
259
+ self
260
+ end
261
+
262
+ def body
263
+ nested = Body.new
264
+ @bits << BodyBits::NestedBody.new(nested)
265
+ yield nested
266
+ self
267
+ end
268
+
269
+ def write_to(writer)
270
+ writer.open_brace
271
+ @bits.each {|bit|
272
+ bit.write_to(writer)
273
+ }
274
+ writer.close_brace
275
+ end
276
+ end
277
+
278
+ class EmptyBody < Body
279
+ def write_to(writer)
280
+ writer.semi_colon.new_line
281
+ end
282
+ end
283
+
284
+ class Method < Constructor
285
+ include ScopeSupport, ModifierSupport, AnnotationSupport
286
+
287
+ def initialize(name)
288
+ super(name)
289
+ @return_type = 'void'
290
+ @modifiers = []
291
+ @scope = 'public'
292
+ end
293
+
294
+ def returns(t)
295
+ @return_type = t
296
+ self
297
+ end
298
+
299
+ def returns_list_of(t)
300
+ @return_type= "List<#{t}>"
301
+ self
302
+ end
303
+
304
+ def return_type
305
+ @return_type
306
+ end
307
+
308
+ def write_declaration(writer)
309
+ writer.word(@scope).words(@modifiers).word(@return_type).word("#{@name}(").append(parameters).append(")")
310
+ end
311
+ end
312
+
313
+ class Field
314
+ include ScopeSupport, ModifierSupport, AnnotationSupport
315
+ def initialize(name, type)
316
+ @name = name
317
+ @type = type
318
+ @scope = 'private'
319
+ @modifiers = []
320
+ @initializer = ''
321
+ @annotations = []
322
+ end
323
+
324
+ def write_to(writer)
325
+ write_annotations_to(writer)
326
+ writer.word(@scope).words(@modifiers).word(@type).word(@name).word(@initializer).semi_colon.new_line
327
+ end
328
+
329
+ def initial(i)
330
+ @initializer = "= #{i}"
331
+ self
332
+ end
333
+ end
334
+
335
+ class Class
336
+ include ScopeSupport, ModifierSupport, AnnotationSupport
337
+
338
+ def initialize(name, package, source_file)
339
+ @name = name;
340
+ @package = package
341
+ @modifiers = ['public']
342
+ @extends = nil
343
+ @instance_methods = []
344
+ @fields = []
345
+ @constructors = []
346
+ @source_file=source_file
347
+ @genericized_using = ''
348
+ @interfaces = nil
349
+ @annotations = []
350
+ @implements = nil
351
+ end
352
+
353
+ def add_field(name, type)
354
+ f = Field.new(name, type)
355
+ @fields << f
356
+ f
357
+ end
358
+
359
+ def genericized_using(g)
360
+ @genericized_using = g
361
+ self
362
+ end
363
+
364
+ def name
365
+ @name
366
+ end
367
+
368
+ def fully_qualified_name
369
+ "#{@package}.#{@name}"
370
+ end
371
+
372
+ def extends(d)
373
+ @extends = d
374
+ self
375
+ end
376
+
377
+ def implements(*interfaces)
378
+ @implements = interfaces
379
+ self
380
+ end
381
+
382
+ def add_method(name)
383
+ result = Method.new(name)
384
+ @instance_methods << result
385
+ result
386
+ end
387
+
388
+ def add_constructor
389
+ result = Constructor.new(@name)
390
+ @constructors << result
391
+ result
392
+ end
393
+
394
+ def write_to(writer)
395
+ write_annotations_to(writer)
396
+ writer.words(@modifiers).word("class").word(@name).append(@genericized_using).word_with_prefix('extends', @extends).list_with_prefix('implements', @implements).open_brace
397
+
398
+ @fields.each {|f|
399
+ f.write_to(writer)
400
+ }
401
+ @constructors.each {|c|
402
+ c.write_to(writer)
403
+ }
404
+ @instance_methods.each {|m|
405
+ m.write_to(writer)
406
+ }
407
+ writer.close_brace
408
+ end
409
+ end
410
+
411
+ class SourceFile
412
+ def initialize
413
+ @package = 'set the package'
414
+ @classes = []
415
+ end
416
+
417
+ def save_in(root)
418
+ writer = Printer.new
419
+ write_to(writer)
420
+ directory = root << "/" + package_as_directory
421
+ if (!FileTest.exist?(directory))
422
+ FileUtils.mkdir_p(directory)
423
+ end
424
+ filename = directory << "/" << @name << ".java"
425
+ file = File.new(filename, "w")
426
+ file.write(writer.contents)
427
+ file.close
428
+ filename
429
+ end
430
+
431
+ def package_as_directory
432
+ @package.split('.').join('/')
433
+ end
434
+
435
+ def package(p)
436
+ @package=p
437
+ self
438
+ end
439
+
440
+ def begin_class(name)
441
+ @name = name
442
+ result = Class.new(name, @package, self)
443
+ @classes << result
444
+ yield result if block_given?
445
+ self
446
+ end
447
+
448
+ def write_to(writer)
449
+ writer.line(package_def).line
450
+ @classes.each {|c|
451
+ c.write_to(writer)
452
+ }
453
+ writer
454
+ end
455
+
456
+ def package_def
457
+ "package #{@package};"
458
+ end
459
+ end
460
+
461
+ class Printer
462
+ def initialize
463
+ @text=""
464
+ @indent=0
465
+ @current_line = nil
466
+ end
467
+
468
+ def line(s="")
469
+ append(s)
470
+ new_line
471
+ end
472
+
473
+ def append(s)
474
+ if (@current_line.nil?)
475
+ @current_line = indent_text
476
+ end
477
+ @current_line << s.to_s
478
+ self
479
+ end
480
+
481
+ def append_all(writers, joiner)
482
+ writers.each_joined(joiner) {|w|
483
+ w.write_to(self)
484
+ }
485
+ end
486
+
487
+ def word_with_prefix(prefix, w)
488
+ if (w.to_s.size>0)
489
+ word(prefix).word(w)
490
+ end
491
+ self
492
+ end
493
+
494
+ def words_with_prefix(prefix, ww)
495
+ if (ww.nil? == false && ww.size > 0)
496
+ word(prefix).words(ww)
497
+ end
498
+ self
499
+ end
500
+
501
+ def list_with_prefix(prefix, list, joiner=',')
502
+ if (list.nil? == false && list.size > 0)
503
+ word(prefix).word(list.join(joiner))
504
+ end
505
+ self
506
+ end
507
+
508
+ def ensure_member_separation_line
509
+ if (!@text.ends_with?("\n\n"))
510
+ new_line
511
+ end
512
+ end
513
+
514
+ def word(w)
515
+ if (w.to_s.size > 0)
516
+ if (!@current_line.nil? && !@text.ends_with?(' '))
517
+ w = " #{w}"
518
+ end
519
+ append(w)
520
+ end
521
+ self
522
+ end
523
+
524
+ def words(ww)
525
+ ww.each {|w|
526
+ word(w)
527
+ }
528
+ self
529
+ end
530
+
531
+ def semi_colon
532
+ append(';')
533
+ end
534
+
535
+ def indent_text
536
+ result = ""
537
+ @indent.times {
538
+ result << " "
539
+ }
540
+ result
541
+ end
542
+
543
+
544
+ def new_line
545
+ @text << @current_line unless @current_line.nil?
546
+ @text << "\n"
547
+ @current_line=nil
548
+ self
549
+ end
550
+
551
+ def indent
552
+ @indent += 1
553
+ self
554
+ end
555
+
556
+ def outdent
557
+ @indent -= 1
558
+ self
559
+ end
560
+
561
+ def open_brace
562
+ line("{")
563
+ indent
564
+ end
565
+
566
+ def close_brace
567
+ outdent
568
+ line("}")
569
+ end
570
+
571
+ def contents
572
+ @text
573
+ end
574
+ end
575
+ end
576
+ end
@@ -0,0 +1,9 @@
1
+ module Guff #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 2
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
data/lib/guff.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'fileutils'
2
+ require 'guff/java_source'