swift_generator 0.1.2

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 (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.idea/.name +1 -0
  4. data/.idea/.rakeTasks +7 -0
  5. data/.idea/compiler.xml +22 -0
  6. data/.idea/copyright/profiles_settings.xml +3 -0
  7. data/.idea/dictionaries/ckornher.xml +7 -0
  8. data/.idea/encodings.xml +4 -0
  9. data/.idea/misc.xml +4 -0
  10. data/.idea/modules.xml +8 -0
  11. data/.idea/runConfigurations/Install_the_Gem.xml +26 -0
  12. data/.idea/runConfigurations/Ribosome.xml +26 -0
  13. data/.idea/runConfigurations/genswift_help.xml +26 -0
  14. data/.idea/runConfigurations/test1.xml +30 -0
  15. data/.idea/scopes/scope_settings.xml +5 -0
  16. data/.idea/swift_generator.iml +126 -0
  17. data/.idea/uiDesigner.xml +124 -0
  18. data/.idea/vcs.xml +6 -0
  19. data/.idea/workspace.xml +1356 -0
  20. data/.rspec +2 -0
  21. data/.travis.yml +3 -0
  22. data/CODE_OF_CONDUCT.md +13 -0
  23. data/Gemfile +7 -0
  24. data/LICENSE.txt +21 -0
  25. data/README.md +39 -0
  26. data/Rakefile +1 -0
  27. data/Tools/compile_templates.bash +3 -0
  28. data/Tools/help.rna +340 -0
  29. data/Tools/ribosome.rb +589 -0
  30. data/bin/console +14 -0
  31. data/bin/genswift +34 -0
  32. data/bin/setup +7 -0
  33. data/lib/swift_generator.rb +23 -0
  34. data/lib/swift_generator/code_generation/POSOTest.rb +8 -0
  35. data/lib/swift_generator/code_generation/SwiftFileTemplate.dna +157 -0
  36. data/lib/swift_generator/code_generation/ToRemove/generate.bash +41 -0
  37. data/lib/swift_generator/code_generation/code_generation_common.rb +6 -0
  38. data/lib/swift_generator/code_generation/swift_class_generation.rb +1589 -0
  39. data/lib/swift_generator/code_generation/swift_file_template.rb +499 -0
  40. data/lib/swift_generator/code_generation/swift_types.rb +106 -0
  41. data/lib/swift_generator/code_generation/usi_metaclasses.rb +23 -0
  42. data/lib/swift_generator/specfile_parser.rb +116 -0
  43. data/lib/swift_generator/version.rb +3 -0
  44. data/swift_generator.gemspec +31 -0
  45. metadata +118 -0
@@ -0,0 +1,499 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #
4
+ # The initial part of this file belongs to the ribosome project.
5
+ #
6
+ # Copyright (c) 2014 Martin Sustrik All rights reserved.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files (the "Software"),
10
+ # to deal in the Software without restriction, including without limitation
11
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
+ # and/or sell copies of the Software, and to permit persons to whom
13
+ # the Software is furnished to do so, subject to the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be included
16
+ # in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
+ # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24
+ # IN THE SOFTWARE.
25
+ #
26
+
27
+ module Ribosome
28
+
29
+ # Class Block represents a rectangular area of text.
30
+ class Block
31
+
32
+ attr_accessor :text, :width
33
+
34
+ def initialize(s)
35
+ @text = []
36
+ @width = 0
37
+ return if s == nil
38
+
39
+ # Split the string into individual lines.
40
+ start = 0
41
+ loop do
42
+ i = s.index("\n", start) || s.size
43
+ @text << (i == start ? "" : s[start..i - 1])
44
+ @width = [@width, @text.last.size].max
45
+ start = i + 1
46
+ break if start > s.size
47
+ end
48
+ end
49
+
50
+ # Weld the supplied block to the right side of this block.
51
+ def add_right(block)
52
+
53
+ # Merge the blocks while taking care to add whitespace
54
+ # where they do not align properly.
55
+ i = 0
56
+ for l in block.text
57
+ if(@text[i])
58
+ @text[i] += (" " * (@width - @text[i].size)) + l
59
+ else
60
+ @text << (" " * @width) + l
61
+ end
62
+ i += 1
63
+ end
64
+
65
+ # Adjust the overall width of the block.
66
+ @width += block.width
67
+
68
+ end
69
+
70
+ # Weld the supplied block to the bottom side of this block.
71
+ def add_bottom(block)
72
+ @text += block.text
73
+ @width = [@width, block.width].max
74
+ end
75
+
76
+ # Trim the whitespace from the block.
77
+ def trim()
78
+
79
+ # Find the boundaries of the text.
80
+ top = -1
81
+ bottom = -1
82
+ left = -1
83
+ right = -1
84
+
85
+ i = 0
86
+ for l in @text
87
+ if(!l.lstrip().empty?)
88
+ top = i if top == -1
89
+ bottom = i;
90
+ if (left == -1)
91
+ left = l.size() - l.lstrip().size()
92
+ else
93
+ left = [left, l.size() - l.lstrip().size()].min
94
+ end
95
+ if (right == -1)
96
+ right = l.rstrip().size()
97
+ else
98
+ right = [right, l.rstrip().size()].max
99
+ end
100
+ end
101
+ i += 1
102
+ end
103
+
104
+ # The case of block with no text whatsoever.
105
+ if bottom == -1
106
+ @text = []
107
+ @width = 0
108
+ return
109
+ end
110
+
111
+ # Strip off the top and bottom whitespace.
112
+ @text = @text[top..bottom]
113
+
114
+ # Strip off the whitespace on the left and on the right.
115
+ for i in 0..@text.size() - 1
116
+ @text[i] = @text[i].rstrip()[left..right]
117
+ @text[i] = "" if @text[i] == nil
118
+ end
119
+
120
+ # Adjust the overall width of the block.
121
+ @width = (@text.max {|x,y| x.size <=> y.size} || "").size
122
+
123
+ end
124
+
125
+ def write(out, tabsize)
126
+ for l in @text
127
+
128
+ # If required, replace the initial whitespace by tabs.
129
+ if(tabsize > 0)
130
+ ws = l.size - l.lstrip.size
131
+ l = "\t" * (ws / tabsize) +
132
+ " " * (ws % tabsize) + l.lstrip
133
+ end
134
+
135
+ # Write an individual line to the output file.
136
+ out.write(l)
137
+ out.write("\n")
138
+ end
139
+ end
140
+
141
+ # Returns offset of the last line in the block.
142
+ def last_offset()
143
+ return 0 if @text.empty?
144
+ return @text.last.size - @text.last.lstrip.size
145
+ end
146
+
147
+ end
148
+
149
+ # Size of a tab. If set to zero, tabs are not generated.
150
+ @tabsize = 0
151
+
152
+ # The output file, or, alternativly, stdout.
153
+ @outisafile = false
154
+ @out = $stdout
155
+
156
+ # This is the ribosome call stack. At each level there is a list of
157
+ # text blocks generated up to that point.
158
+ @stack = [[]]
159
+
160
+ # Redirects output to the specified file.
161
+ def Ribosome.output(filename)
162
+ close()
163
+ @outisafile = true
164
+ @out = File.open(filename, "w")
165
+ end
166
+
167
+ # Redirects output to the specified file.
168
+ # New stuff is added to the existing content of the file.
169
+ def Ribosome.append(filename)
170
+ close()
171
+ @outisafile = true
172
+ @out = File.open(filename, "a")
173
+ end
174
+
175
+ # Redirects output to the stdout.
176
+ def Ribosome.stdout()
177
+ close()
178
+ @outisafile = false
179
+ @out = $stdout
180
+ end
181
+
182
+ # Sets the size of the tab.
183
+ def Ribosome.tabsize(size)
184
+ @tabsize = size
185
+ end
186
+
187
+ # Flush the data to the currently open file and close it.
188
+ def Ribosome.close()
189
+ for b in @stack.last
190
+ b.write(@out, @tabsize)
191
+ end
192
+ @stack = [[]]
193
+ @out.close() if @outisafile
194
+ end
195
+
196
+ # Adds one . line from the DNA file.
197
+ def Ribosome.add(line, bind)
198
+
199
+ # If there is no previous line, add one.
200
+ if(@stack.last.empty?)
201
+ @stack.last << Block.new("")
202
+ end
203
+
204
+ # In this block we will accumulate the expanded line.
205
+ block = @stack.last.last
206
+
207
+ # Traverse the line and convert it into a block.
208
+ i = 0
209
+ while true
210
+ j = line.index(/[@&][1-9]?\{/, i)
211
+ j = line.size if j == nil
212
+
213
+ # Process constant block of text.
214
+ if (i != j)
215
+ block.add_right(Block.new(line[i..j - 1]))
216
+ end
217
+
218
+ break if line.size == j
219
+
220
+ # Process an embedded expression.
221
+ i = j
222
+ j += 1
223
+ level = 0
224
+ if (line[j] >= ?1 && line[j] <= ?9)
225
+ level = line[j].to_i
226
+ j += 1
227
+ end
228
+
229
+ # Find corresponding }.
230
+ par = 0;
231
+ while true
232
+ if(line[j] == ?{)
233
+ par += 1
234
+ elsif(line[j] == ?})
235
+ par -= 1
236
+ end
237
+ break if par == 0
238
+ j += 1
239
+ if j >= line.size
240
+ raise SyntaxError.new("Unmatched {")
241
+ end
242
+ end
243
+
244
+ # Expression of higher indirection levels are simply brought
245
+ # down by one level.
246
+ if(level > 0)
247
+ if line [i + 1] == ?1
248
+ block.add_right(Block.new("@" + line[i + 2..j]))
249
+ else
250
+ line[i + 1] = (line [i + 1].to_i - 1).chr
251
+ block.add_right(Block.new(line[i..j]))
252
+ end
253
+ i = j + 1
254
+ next
255
+ end
256
+
257
+ # We are at the lowest level of embeddedness so we have to
258
+ # evaluate the embedded expression straight away.
259
+ expr = line[(level == 0 ? i + 2 : i + 3)..j - 1]
260
+ @stack.push([])
261
+ val = eval(expr, bind)
262
+ top = @stack.pop()
263
+ if(top.empty?)
264
+ val = Block.new(val.to_s)
265
+ else
266
+ val = Block.new("")
267
+ for b in top
268
+ val.add_bottom(b)
269
+ end
270
+ end
271
+ val.trim if line[i] == ?@
272
+ block.add_right(val)
273
+ i = j + 1
274
+ end
275
+ end
276
+
277
+ # Adds newline followed by one . line from the DNA file.
278
+ def Ribosome.dot(line, bind)
279
+ @stack.last << Block.new("")
280
+ add(line, bind)
281
+ end
282
+
283
+ # Adds newline followed by leading whitespace copied from the previous line
284
+ # and one line from the DNA file.
285
+ def Ribosome.align(line, bind)
286
+ if @stack.last.empty?
287
+ n = 0
288
+ else
289
+ n = @stack.last.last.last_offset
290
+ end
291
+ @stack.last << Block.new("")
292
+ add(" " * n, nil)
293
+ add(line, bind)
294
+ end
295
+
296
+ # Report an error that happened when executing RNA file.
297
+ def Ribosome.rethrow(e, rnafile, linemap)
298
+ i = 0
299
+ for i in 0..e.backtrace.size - 1
300
+ l = e.backtrace[i]
301
+ if l.start_with?(rnafile + ":")
302
+ stop = l.index(":", rnafile.size + 1) || l.size
303
+ num = l[rnafile.size + 1..stop - 1].to_i
304
+ for j in 0..linemap.size - 1
305
+ break if linemap[j][0] == nil || linemap[j][0] > num
306
+ end
307
+ j -= 1
308
+ num = num - linemap[j][0] + linemap[j][2]
309
+ l = "#{linemap[j][1]}:#{num}#{l[stop..-1]}"
310
+ e.backtrace[i] = l
311
+ end
312
+ end
313
+ raise e
314
+ end
315
+
316
+ end
317
+
318
+ # Escape function for @
319
+ def at()
320
+ return "@"
321
+ end
322
+
323
+ # Escape function for &
324
+ def amp()
325
+ return "&"
326
+ end
327
+
328
+ # Escape function for /
329
+ def slash()
330
+ return "/"
331
+ end
332
+
333
+ ################################################################################
334
+ # The code that belongs to the ribosome project ends at this point of the #
335
+ # RNA file and so does the associated license. What follows is the code #
336
+ # generated from the DNA file. #
337
+ ################################################################################
338
+
339
+ $definition_file = nil
340
+
341
+ require 'fileutils'
342
+ require "swift_generator/version"
343
+ require "swift_generator/code_generation/swift_class_generation"
344
+
345
+
346
+ module SwiftGenerator
347
+
348
+ def write_files_for_definition_set( definition_set )
349
+ for _, f in definition_set.output_files
350
+ path = Pathname.new( f.file_path )
351
+ path.parent.mkpath
352
+ SwiftGenerator::writeGeneratedFile( f )
353
+ end
354
+ end
355
+
356
+
357
+ module_function :write_files_for_definition_set
358
+
359
+ # files = YAML::load(File.open(ARGV[0]))
360
+
361
+ # Templated Output Methods
362
+ def write_element( element )
363
+ if( element.kind_of? SwiftClass )
364
+ SwiftGenerator::write_class( element )
365
+ elsif( element.kind_of? SwiftEnum )
366
+ SwiftGenerator::write_enum( element )
367
+ end
368
+ end
369
+
370
+ module_function :write_element
371
+
372
+ def writeGeneratedFile( f )
373
+ return if ( f.is_user_file && File.exist?( f.file_path ))
374
+
375
+ Ribosome.output( f.file_path )
376
+
377
+ Ribosome.dot("//", binding)
378
+ Ribosome.dot("// @{f.file_name}", binding)
379
+ Ribosome.dot("// @{f.company_name}", binding)
380
+ if $definition_file
381
+ Ribosome.dot("//", binding)
382
+ Ribosome.dot("// Generated from @{$definition_file} on @{Time.now.strftime(\"%d/%m/%Y %H:%M\")}", binding)
383
+ end
384
+ if f.include_editing_warnings
385
+ if !f.is_user_file
386
+ Ribosome.dot("//", binding)
387
+ Ribosome.dot("// WARNING: This entire file is generated. DO NOT EDIT.", binding)
388
+ else
389
+ Ribosome.dot("//", binding)
390
+ Ribosome.dot("// This is a user-editable generated file. Delete or rename this file to have a new empty file generated", binding)
391
+ end
392
+ end
393
+ Ribosome.dot("//", binding)
394
+ Ribosome.dot("// Copyright (c) @{Time.now.strftime(\"\")} @{f.company_name}, Inc. All rights reserved.", binding)
395
+ Ribosome.dot("//", binding)
396
+
397
+ for import_statement in f.import_statements.sort
398
+ Ribosome.dot("&{import_statement}", binding)
399
+ end
400
+
401
+ for element in f.elements
402
+ SwiftGenerator::write_element(element)
403
+ end
404
+ end
405
+
406
+ module_function :writeGeneratedFile
407
+
408
+
409
+ def write_enum( e )
410
+ Ribosome.dot("", binding)
411
+ Ribosome.dot("", binding)
412
+ Ribosome.dot("&{e.access_control_modifier}enum @{e.type_name}", binding)
413
+ if e.inheritance_list.count > 0
414
+ Ribosome.add(" : @{e.inheritance_list.join( \", \" )}", binding)
415
+ end
416
+ Ribosome.add(" {", binding)
417
+
418
+ e.enum_cases.each_with_index do |enum_case, _|
419
+ enum_case.declaration_lines().each do |declLine|
420
+ Ribosome.dot(" &{declLine}", binding)
421
+ end
422
+ end
423
+
424
+ e.properties.each_with_index do |prop, i|
425
+ Ribosome.dot("", binding)
426
+ prop.declaration_lines().each do |declLine|
427
+ Ribosome.dot(" &{declLine}", binding)
428
+ end
429
+ end
430
+
431
+ SwiftGenerator::write_methods( e.methods )
432
+ Ribosome.dot(" }", binding)
433
+ end
434
+
435
+ module_function :write_enum
436
+
437
+
438
+ def write_class( c )
439
+ Ribosome.dot("", binding)
440
+ Ribosome.dot("", binding)
441
+ Ribosome.dot("&{c.access_control_modifier}class @{c.type_name}", binding)
442
+ if c.inheritance_list.count > 0
443
+ Ribosome.add(" : @{c.inheritance_list.join( \", \" )}", binding)
444
+ end
445
+ Ribosome.add(" {", binding)
446
+
447
+ SwiftGenerator::write_property_declarations( c.transient_properties, "Transient" )
448
+ SwiftGenerator::write_property_declarations( c.persistent_properties, "Persistent" )
449
+
450
+ SwiftGenerator::write_methods( c.initializers )
451
+ SwiftGenerator::write_methods( c.methods )
452
+ Ribosome.dot("}", binding)
453
+
454
+ end
455
+
456
+ module_function :write_class
457
+
458
+
459
+ def write_property_declarations( properties, property_type_label )
460
+ properties.each_with_index do |prop, i|
461
+ if i == 0
462
+ Ribosome.dot("", binding)
463
+ Ribosome.dot(" // MARK: @{property_type_label} Properties", binding)
464
+ end
465
+ prop.declaration_lines().each do |declLine|
466
+ Ribosome.dot(" &{declLine}", binding)
467
+ end
468
+ end
469
+
470
+ end
471
+
472
+ module_function :write_property_declarations
473
+
474
+
475
+ def write_methods( methods )
476
+ methods.each_with_index do |m, i|
477
+ overrideString = m.override ? 'override ' : ''
478
+ Ribosome.dot("", binding)
479
+ if ! m.comment.nil?
480
+ Ribosome.dot(" &{m.comment}", binding)
481
+ end
482
+ args = m.argStr.nil? || m.argStr.empty? ? m.argStr : ' ' + m.argStr + ' '
483
+ Ribosome.dot(" &{overrideString}&{m.access_control_modifier}&{m.func_fragment} @{m.name}(&{args})", binding)
484
+ if ! (m.returns.nil? || m.returns.length == 0 )
485
+ Ribosome.add(" -> @{m.returns}", binding)
486
+ end
487
+ Ribosome.add(" {", binding)
488
+ m.bodyLines.each do |line|
489
+ Ribosome.dot(" &{line}", binding)
490
+ end
491
+ Ribosome.dot(" }", binding)
492
+ end
493
+ end
494
+
495
+ module_function :write_methods
496
+
497
+ end
498
+ Ribosome.close()
499
+