swift_generator 0.1.2 → 0.3.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/README.md CHANGED
@@ -1,8 +1,6 @@
1
- # SwiftGenerator
1
+ # swift\_generator
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/swift_generator`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ This gem vends an API to generate swift code programatically. Any number of code elements can be created simultaneously and iteratively.
6
4
 
7
5
  ## Installation
8
6
 
@@ -21,8 +19,58 @@ Or install it yourself as:
21
19
  $ gem install swift_generator
22
20
 
23
21
  ## Usage
22
+ ### Ruby API
23
+
24
+ ```ruby
25
+
26
+ # Coming Soon
27
+
28
+ ```
29
+
30
+ ### Command Line Tool
31
+ Work on a simple command-line interface has been started to generate Swift code from non-ruby systems.
32
+
33
+ To invoke the tool:
34
+
35
+ genswift generate SPECFILE [options]
36
+
37
+ or just
38
+
39
+ genswift SPECFILE [options]
40
+
41
+ Some help is availible:
42
+
43
+ genswift help
44
+ genswift help generate
45
+
46
+ ###### Specfile Format
47
+
48
+ ```json
49
+
50
+ # Coming Soon
51
+
52
+ ```
53
+
54
+ ##Project Status
55
+ The initial use of this gem is by the [objective\_c\_2\_swift\_assistant](https://www.something.com "Github project") gem to generate Swift files.
56
+
57
+ The current release is functional, but rough. Testing, input validation, and other important quality aspects are missing.
58
+
59
+ ##Design and History
60
+ This gem started out as a way to generate Swift code for a production application. It was started a few weeks after WWDC 2014.
61
+
62
+ The design was experiment in a sense. We want to see if it was possible to create a code generator that could have some intelligence about the code it was generating.
63
+
64
+ ###Goals
65
+ * Preservation of intermediate state information for debugging and extensibility
66
+ * High-level constructs for things that matter to developers: Types, Classes, Methods, Properties, ...
67
+ * The ability to generate unit tests for the methods it generates. This feature is not yet well documented at this time
68
+ * Ability to generate meaningful pure Swift classes (classes not descending from NSObject)
69
+ * JSON serialization support for generated Swift classes
24
70
 
25
- TODO: Write usage instructions here
71
+ ###Non-Goals
72
+ * Code generation speed
73
+ * Minimal Memory Footprint
26
74
 
27
75
  ## Development
28
76
 
data/bin/genswift CHANGED
@@ -11,7 +11,7 @@ program :version, '1.0.0'
11
11
  program :description, 'Basic CLI interface to the swift_generator gem'
12
12
 
13
13
  command :generate do |c|
14
- c.syntax = 'genswift specfile'
14
+ c.syntax = 'genswift SPECFILE [options]'
15
15
  c.description = 'Generate Swift files based upon a JSON specification file.'
16
16
  c.option '--out STRING', String, 'The root of the generated Swift source. Overrides the setting in the spec file.'
17
17
  c.action do |args, options|
@@ -0,0 +1,216 @@
1
+ require 'rubygems'
2
+ require 'json'
3
+ require_relative 'POSOMetaclasses'
4
+ require_relative 'POSOTypes'
5
+ require_relative 'usi_metaclasses'
6
+
7
+ def make_definition_set
8
+ # File Paths
9
+ useful_root = '../Useful'
10
+ model_user_source = File.join(useful_root, 'Shared', 'Models')
11
+ model_generated_source = File.join(model_user_source, 'Generated')
12
+
13
+ test_root = '../UsefulTests'
14
+ model_test = File.join(test_root, 'Shared', 'Models')
15
+ model_generated_test = File.join(model_test, 'Generated')
16
+
17
+ # Standard USI Model settings
18
+ uis_model_characteristics = [:json_serializable, :comparable, :make_test_class, :create_user_class]
19
+
20
+ # USI Model (Wire Data) settings
21
+ defs = SwiftDefinitionSet.new( generated_root:model_generated_source,
22
+ generated_user_root:model_user_source,
23
+ generated_test_root:model_generated_test)
24
+
25
+ base = SwiftClass.new(defs, 'USIBaseModel', ['NSObject'], characteristics: uis_model_characteristics )
26
+ base.add_simple_class_property( "restEndpoint", :AnvilEndpoint, value:".None", override:false )
27
+
28
+ SwiftPersistentProperty.new( base, '__v', :String, :optional, rest_omit: :omit_if_null)
29
+ SwiftPersistentProperty.new( base, '_id', :String, :optional, rest_omit: :omit_if_null )
30
+ SwiftPersistentProperty.new( base, 'organizationID', :String, :optional, json_key:'organizationId', rest_omit: :omit )
31
+ SwiftPersistentProperty.new( base, 'updatedAt', :NSDate, :optional, rest_omit: :omit )
32
+
33
+ address = USIWireDataClass.new(defs, 'Address', endpoint:".Addresses" )
34
+ SwiftPersistentProperty.new( address, 'buildingName', :String, :optional )
35
+ SwiftPersistentProperty.new( address, 'city', :String, :optional )
36
+ SwiftPersistentProperty.new( address, 'country', :String, :optional )
37
+ SwiftPersistentProperty.new( address, 'governingDistrict', :String, :optional )
38
+ SwiftPersistentProperty.new( address, 'latitude', :Double, :optional )
39
+ SwiftPersistentProperty.new( address, 'localMunicipality', :String, :optional )
40
+ SwiftPersistentProperty.new( address, 'longitude', :Double, :optional )
41
+ SwiftPersistentProperty.new( address, 'postalArea', :String, :optional )
42
+ SwiftPersistentProperty.new( address, 'streetDirection', :String, :optional )
43
+ SwiftPersistentProperty.new( address, 'streetName', :String, :optional )
44
+ SwiftPersistentProperty.new( address, 'streetNumber', :Int, :optional )
45
+ SwiftPersistentProperty.new( address, 'streetNumberSuffix', :String, :optional )
46
+ SwiftPersistentProperty.new( address, 'streetType', :String, :optional )
47
+ SwiftPersistentProperty.new( address, 'title', :String, :optional )
48
+ SwiftPersistentProperty.new( address, 'type', :String, :optional )
49
+ SwiftPersistentProperty.new( address, 'typeIdentifier', :String, :optional )
50
+
51
+ affOrg = USIWireDataClass.new( defs, 'AffiliateOrganization', endpoint:".AffiliateOrganizations" )
52
+ SwiftPersistentProperty.new( affOrg, 'activeCustomer', :Bool, :optional )
53
+ SwiftPersistentProperty.new( affOrg, 'activePartner', :Bool, :optional )
54
+ SwiftPersistentProperty.new( affOrg, 'customer', :Bool, :optional )
55
+ SwiftPersistentProperty.new( affOrg, 'otherOrganization', :USIObjectID, :optional )
56
+ SwiftPersistentProperty.new( affOrg, 'partner', :Bool, :optional )
57
+
58
+ contact = USIWireDataClass.new( defs, 'Contact', endpoint:".Contacts" )
59
+ SwiftPersistentProperty.new( contact, 'email', :String, :optional )
60
+ SwiftPersistentProperty.new( contact, 'firstName', :String, :optional )
61
+ SwiftPersistentProperty.new( contact, 'lastName', :String, :optional )
62
+ SwiftPersistentProperty.new( contact, 'phoneNumber', :PhoneNumber, :optional )
63
+
64
+ customer = USIWireDataClass.new( defs, 'Customer', endpoint:".Customers" )
65
+ SwiftPersistentProperty.new( customer, 'name', :String, :optional )
66
+ SwiftPersistentProperty.new( customer, 'email', :String, :optional )
67
+ SwiftPersistentProperty.new( customer, 'types', :String, :optional, collection_type: :array )
68
+ SwiftPersistentProperty.new( customer, 'account', :String, :optional )
69
+ SwiftPersistentProperty.new( customer, 'addresses', :Address, :optional, collection_type: :array )
70
+ SwiftPersistentProperty.new( customer, 'contacts', :Contact, :optional, collection_type: :array )
71
+ SwiftPersistentProperty.new( customer, 'phoneNumbers', :PhoneNumber, :optional, collection_type: :array )
72
+
73
+ customerSummary = USIWireDataClass.new( defs, 'CustomerSummary' )
74
+ SwiftPersistentProperty.new( customerSummary, 'name', :String, :optional )
75
+ SwiftPersistentProperty.new( customerSummary, 'email', :String, :optional )
76
+ SwiftPersistentProperty.new( customerSummary, 'types', :String, :optional, collection_type: :array )
77
+ SwiftPersistentProperty.new( customerSummary, 'account', :String, :optional )
78
+
79
+ detail = USIWireDataClass.new( defs, 'Detail', endpoint:".Details" )
80
+ SwiftPersistentProperty.new( detail, 'detailText', :String, :optional )
81
+ SwiftPersistentProperty.new( detail, 'userId', :String, :optional )
82
+ SwiftPersistentProperty.new( detail, 'workFormID', :String, :optional, json_key:'workFormid' )
83
+ SwiftPersistentProperty.new( detail, 'title', :String, :optional )
84
+
85
+ materialType = USIWireDataClass.new( defs, 'MaterialType', endpoint:".MaterialTypes" )
86
+ SwiftPersistentProperty.new( materialType, 'materialDescription', :String, :optional, json_key:'description' )
87
+ SwiftPersistentProperty.new( materialType, 'defaultBillablePrice', :Int, :optional )
88
+ SwiftPersistentProperty.new( materialType, 'defaultCost', :Int, :optional )
89
+ SwiftPersistentProperty.new( materialType, 'name', :String, :optional )
90
+ SwiftPersistentProperty.new( materialType, 'partNumber', :String, :optional )
91
+ SwiftPersistentProperty.new( materialType, 'unit', :String, :optional )
92
+
93
+ material = USIWireDataClass.new(defs, 'Material', endpoint:".Materials")
94
+ SwiftPersistentProperty.new( material, 'workFormID', :String, :optional )
95
+ SwiftPersistentProperty.new( material, 'materialTypeID', :String, :optional )
96
+ SwiftPersistentProperty.new( material, 'materialDescription', :String, :optional, json_key:'description' )
97
+ SwiftPersistentProperty.new( material, 'billablePrice', :Int, :optional )
98
+ SwiftPersistentProperty.new( material, 'cost', :Int, :optional )
99
+ SwiftPersistentProperty.new( material, 'name', :String, :optional )
100
+ SwiftPersistentProperty.new( material, 'partNumber', :String, :optional )
101
+ SwiftPersistentProperty.new( material, 'unit', :String, :optional )
102
+
103
+ org = USIWireDataClass.new( defs, 'Organization', endpoint:".Organizations" )
104
+ SwiftPersistentProperty.new( org, 'addresses', :Address, :optional, collection_type: :array )
105
+ SwiftPersistentProperty.new( org, 'affiliateOrganizations', :Organization, :optional, collection_type: :array )
106
+ SwiftPersistentProperty.new( org, 'contacts', :Contact, :optional, collection_type: :array )
107
+ SwiftPersistentProperty.new( org, 'defaultTaxRate', :Int, :optional )
108
+ SwiftPersistentProperty.new( org, 'email', :String, :optional )
109
+ SwiftPersistentProperty.new( org, 'logoURIs', :String, :optional, collection_type: :array )
110
+ SwiftPersistentProperty.new( org, 'materialTypes', :MaterialType, :optional, collection_type: :array )
111
+ SwiftPersistentProperty.new( org, 'name', :String, :optional )
112
+ SwiftPersistentProperty.new( org, 'phoneNumbers', :PhoneNumber, :optional, collection_type: :array )
113
+ SwiftPersistentProperty.new( org, 'serviceTypes', :ServiceType, :optional, collection_type: :array )
114
+ # 'subscription (ref to Subscription)
115
+ SwiftPersistentProperty.new( org, 'timezone', :String, :optional )
116
+ SwiftPersistentProperty.new( org, 'website', :String, :optional )
117
+ SwiftPersistentProperty.new( org, 'users', :User, :optional, collection_type: :array )
118
+
119
+ payRate = USIWireDataClass.new(defs, 'PayRate', endpoint:".PayRates" )
120
+ SwiftPersistentProperty.new( payRate, 'rate', :Int, :optional )
121
+ SwiftPersistentProperty.new( payRate, 'taxType', :TaxType, :optional )
122
+
123
+ permission = SwiftEnum.new(defs, 'Permission', ['String'] )
124
+ SwiftEnumCase.new( permission, 'Admin', 'ADMIN' )
125
+
126
+ phoneNumber = USIWireDataClass.new(defs, 'PhoneNumber', endpoint:".PhoneNumbers" )
127
+ SwiftPersistentProperty.new( phoneNumber, 'areaCode', :Int, :optional )
128
+ SwiftPersistentProperty.new( phoneNumber, 'countryCode', :Int, :optional )
129
+ SwiftPersistentProperty.new( phoneNumber, 'exchange', :Int, :optional )
130
+ SwiftPersistentProperty.new( phoneNumber, 'line', :Int, :optional )
131
+ SwiftPersistentProperty.new( phoneNumber, 'type', :String, :optional )
132
+
133
+ role = USIWireDataClass.new( defs, 'Role', endpoint:".Roles" )
134
+ SwiftPersistentProperty.new( role, 'permissions', :Permission, :optional, collection_type: :array )
135
+
136
+ serviceType = USIWireDataClass.new( defs, 'ServiceType', endpoint:".ServiceTypes" )
137
+ SwiftPersistentProperty.new( serviceType, 'defaultBillableRate', :Int, :optional )
138
+ SwiftPersistentProperty.new( serviceType, 'serviceDescription', :String, :optional, json_key:'description')
139
+ SwiftPersistentProperty.new( serviceType, 'isHourlyRate', :Bool, :optional )
140
+ SwiftPersistentProperty.new( serviceType, 'name', :String, :optional )
141
+
142
+ service = USIWireDataClass.new( defs, 'Service', endpoint: ".Services" )
143
+ SwiftPersistentProperty.new( service, 'billableRate', :Int, :optional )
144
+ SwiftPersistentProperty.new( service, 'serviceDescription', :String, :optional, json_key:'description')
145
+ SwiftPersistentProperty.new( service, 'isHourlyRate', :Bool, :optional )
146
+ SwiftPersistentProperty.new( service, 'name', :String, :optional )
147
+ SwiftPersistentProperty.new( service, 'serviceTypeId', :String, :optional )
148
+ SwiftPersistentProperty.new( service, 'workFormId', :String, :optional )
149
+
150
+ tax_type = SwiftEnum.new(defs, 'TaxType', ['String'] )
151
+ SwiftEnumCase.new( tax_type, 'HourlyEmployee', 'HOURLY_EMPLOYEE' )
152
+ SwiftEnumCase.new( tax_type, 'None', 'NONE' )
153
+ SwiftEnumCase.new( tax_type, 'SalariedContractor', 'SALARIED_CONTRACTOR' )
154
+ SwiftEnumCase.new( tax_type, 'SalariedEmployee', 'SALARIED_EMPLOYEE' )
155
+
156
+ user = USIWireDataClass.new(defs, 'User', endpoint:".Users")
157
+ SwiftPersistentProperty.new( user, 'addresses', :Address, :optional, collection_type: :array )
158
+ SwiftPersistentProperty.new( user, 'disabled', :Bool, :optional )
159
+ SwiftPersistentProperty.new( user, 'emergencyContacts', :Contact, :optional, collection_type: :array )
160
+ SwiftPersistentProperty.new( user, 'email', :String, :optional )
161
+ SwiftPersistentProperty.new( user, 'firstName', :String, :optional )
162
+ SwiftPersistentProperty.new( user, 'lastName', :String, :optional )
163
+ SwiftPersistentProperty.new( user, 'latitude', :Double, :optional )
164
+ SwiftPersistentProperty.new( user, 'longitude', :Double, :optional )
165
+ SwiftPersistentProperty.new( user, 'passwordHash', :String, :optional )
166
+ SwiftPersistentProperty.new( user, 'payRate', :PayRate, :optional )
167
+ SwiftPersistentProperty.new( user, 'phoneNumbers', :PhoneNumber, :optional, collection_type: :array )
168
+ SwiftPersistentProperty.new( user, 'photoURIs', :String, :optional, collection_type: :array )
169
+ SwiftPersistentProperty.new( user, 'role', :Role, :optional )
170
+
171
+ userSummary = USIWireDataClass.new( defs, 'UserSummary' )
172
+ SwiftPersistentProperty.new( userSummary, 'isDisabled', :Bool, :optional )
173
+ SwiftPersistentProperty.new( userSummary, 'email', :String, :optional )
174
+ SwiftPersistentProperty.new( userSummary, 'firstName', :String, :optional )
175
+ SwiftPersistentProperty.new( userSummary, 'lastName', :String, :optional )
176
+ SwiftPersistentProperty.new( userSummary, 'nickname', :String, :optional )
177
+
178
+ workForm = USIWireDataClass.new( defs, 'WorkForm', endpoint:".WorkForms" )
179
+ SwiftPersistentProperty.new( workForm, 'customer', :CustomerSummary, :optional )
180
+ SwiftPersistentProperty.new( workForm, 'formDescription', :String, :optional, json_key:'description' )
181
+ SwiftPersistentProperty.new( workForm, 'assignedToUser', :UserSummary, :optional )
182
+ SwiftPersistentProperty.new( workForm, 'createdByUser', :UserSummary, :optional )
183
+ SwiftPersistentProperty.new( workForm, 'details', :Detail, :optional, collection_type: :array )
184
+ SwiftPersistentProperty.new( workForm, 'materials', :Material, :optional, collection_type: :array )
185
+ SwiftPersistentProperty.new( workForm, 'services', :Service, :optional, collection_type: :array )
186
+ SwiftPersistentProperty.new( workForm, 'crew', :UserSummary, :optional, collection_type: :array )
187
+ SwiftPersistentProperty.new( workForm, 'formId', :String, :optional )
188
+ SwiftPersistentProperty.new( workForm, 'formType', :WorkFormType, :optional )
189
+ SwiftPersistentProperty.new( workForm, 'workFlowId', :String, :optional )
190
+ SwiftPersistentProperty.new( workForm, 'previousFormId', :String, :optional )
191
+ SwiftPersistentProperty.new( workForm, 'status', :WorkStatusType, :optional )
192
+ SwiftPersistentProperty.new( workForm, 'startDate', :NSDate, :optional )
193
+ SwiftPersistentProperty.new( workForm, 'endDate', :NSDate, :optional )
194
+ SwiftPersistentProperty.new( workForm, 'marqueeImageURL', :String, :optional )
195
+ SwiftPersistentProperty.new( workForm, 'totalValue', :Int, :optional )
196
+
197
+ work_form_type = SwiftEnum.new(defs, 'WorkFormType', ['String'] )
198
+ SwiftEnumCase.new( work_form_type, 'Request', 'REQUEST' )
199
+ SwiftEnumCase.new( work_form_type, 'Inspection', 'INSPECTION' )
200
+ SwiftEnumCase.new( work_form_type, 'Estimate', 'ESTIMATE' )
201
+ SwiftEnumCase.new( work_form_type, 'WorkOrder', 'WORKORDER' )
202
+ SwiftEnumCase.new( work_form_type, 'Invoice', 'INVOICE' )
203
+
204
+ work_status_type = SwiftEnum.new(defs, 'WorkStatusType', ['String'] )
205
+ SwiftEnumCase.new( work_status_type, 'Draft', 'DRAFT' )
206
+ # SwiftEnumCase.new( work_status_type, 'Unscheduled', 'UNSCHEDULED' )
207
+ SwiftEnumCase.new( work_status_type, 'Assigned', 'ASSIGNED' )
208
+ SwiftEnumCase.new( work_status_type, 'Scheduled', 'SCHEDULED' )
209
+ SwiftEnumCase.new( work_status_type, 'Dispatched', 'DISPATCHED' )
210
+ SwiftEnumCase.new( work_status_type, 'InProgress', 'IN-PROGRESS' )
211
+ SwiftEnumCase.new( work_status_type, 'Completed', 'COMPLETED' )
212
+ SwiftEnumCase.new( work_status_type, 'Rejected', 'REJECTED' )
213
+ SwiftEnumCase.new( work_status_type, 'Submitted', 'SUBMITTED' )
214
+
215
+ return defs
216
+ end
@@ -20,10 +20,14 @@ module_function :write_files_for_definition_set
20
20
 
21
21
  # Templated Output Methods
22
22
  def write_element( element )
23
- if( element.kind_of? SwiftClass )
24
- SwiftGenerator::write_class( element )
23
+ if( element.kind_of? SwiftCategory )
24
+ SwiftGenerator::write_category( element )
25
+ elsif( element.kind_of? SwiftProtocol )
26
+ SwiftGenerator::write_protocol( element )
25
27
  elsif( element.kind_of? SwiftEnum )
26
28
  SwiftGenerator::write_enum( element )
29
+ elsif( element.kind_of? SwiftClass ) # Must be last as it is the superclass
30
+ SwiftGenerator::write_class( element )
27
31
  end
28
32
  end
29
33
 
@@ -32,10 +36,12 @@ module_function :write_element
32
36
  def writeGeneratedFile( f )
33
37
  return if ( f.is_user_file && File.exist?( f.file_path ))
34
38
 
39
+ Pathname.new( f.file_path ).parent().mkpath()
40
+
35
41
  ./!output( f.file_path )
36
42
 
37
43
  .//
38
- .// @{f.file_name}
44
+ .// @{ Pathname.new( f.file_name ).basename }
39
45
  .// @{f.company_name}
40
46
  if $definition_file
41
47
  .//
@@ -91,7 +97,6 @@ def write_enum( e )
91
97
  SwiftGenerator::write_methods( e.methods )
92
98
  . }
93
99
  end
94
-
95
100
  module_function :write_enum
96
101
 
97
102
 
@@ -104,21 +109,58 @@ def write_class( c )
104
109
  end
105
110
  . /+ {
106
111
 
107
- SwiftGenerator::write_property_declarations( c.transient_properties, "Transient" )
108
- SwiftGenerator::write_property_declarations( c.persistent_properties, "Persistent" )
112
+ SwiftGenerator::write_class_body( c )
113
+ .}
114
+ end
115
+ module_function :write_class
116
+
109
117
 
110
- SwiftGenerator::write_methods( c.initializers )
111
- SwiftGenerator::write_methods( c.methods )
118
+ def write_category( c )
119
+ .
120
+ .
121
+ .&{c.access_control_modifier}extension @{c.categorized_class_name} /*@{c.type_name || ' '}*/ {
122
+ SwiftGenerator::write_class_body( c )
112
123
  .}
124
+ end
125
+ module_function :write_category
126
+
127
+ def write_class_body( c )
128
+ c.top_inner_comment_block().each do |line|
129
+ . &{line}
130
+ end
131
+
132
+ # SwiftGenerator::write_property_declarations( c.transient_properties, "Transient" )
133
+ # SwiftGenerator::write_property_declarations( c.persistent_properties, "Persistent" )
134
+ SwiftGenerator::write_property_declarations( c.transient_properties )
135
+ SwiftGenerator::write_property_declarations( c.persistent_properties )
113
136
 
137
+ SwiftGenerator::write_methods( c.initializers )
138
+ SwiftGenerator::write_methods( c.methods )
114
139
  end
140
+ module_function :write_class_body
115
141
 
116
- module_function :write_class
142
+ def write_protocol( p )
143
+ .
144
+ .
145
+ .&{p.access_control_modifier}protocol @{p.type_name}
146
+ if p.inheritance_list.count > 0
147
+ . /+ : @{p.inheritance_list.join( ", " )}
148
+ end
149
+ . /+ {
150
+ # SwiftGenerator::write_property_declarations( c.transient_properties, "Transient" )
151
+ # SwiftGenerator::write_property_declarations( c.persistent_properties, "Persistent" )
152
+ SwiftGenerator::write_property_declarations( p.transient_properties )
153
+ SwiftGenerator::write_property_declarations( p.persistent_properties )
117
154
 
155
+ SwiftGenerator::write_methods( p.initializers, for_protocol=true )
156
+ SwiftGenerator::write_methods( p.methods, for_protocol=true )
157
+ .}
158
+ end
159
+ module_function :write_protocol
118
160
 
119
- def write_property_declarations( properties, property_type_label )
161
+ def write_property_declarations( properties, property_type_label=nil )
120
162
  properties.each_with_index do |prop, i|
121
- if i == 0
163
+ if i == 0 && ! property_type_label.nil?
122
164
  .
123
165
  . // MARK: @{property_type_label} Properties
124
166
  end
@@ -126,13 +168,12 @@ def write_property_declarations( properties, property_type_label )
126
168
  . &{declLine}
127
169
  end
128
170
  end
129
-
130
171
  end
131
172
 
132
173
  module_function :write_property_declarations
133
174
 
134
175
 
135
- def write_methods( methods )
176
+ def write_methods( methods, for_protocol=false )
136
177
  methods.each_with_index do |m, i|
137
178
  overrideString = m.override ? 'override ' : ''
138
179
  .
@@ -140,15 +181,18 @@ def write_methods( methods )
140
181
  . &{m.comment}
141
182
  end
142
183
  args = m.argStr.nil? || m.argStr.empty? ? m.argStr : ' ' + m.argStr + ' '
143
- . &{overrideString}&{m.access_control_modifier}&{m.func_fragment} @{m.name}(&{args})
184
+ access_control_modifier_str = m.access_control_modifiers.length > 0 ? m.access_control_modifiers.join( ", " ) + " " : ""
185
+ . &{overrideString}&{access_control_modifier_str}&{m.func_fragment + " " unless m.func_fragment.length == 0}@{m.name}(&{args})
144
186
  if ! (m.returns.nil? || m.returns.length == 0 )
145
187
  . /+ -> @{m.returns}
146
188
  end
189
+ unless for_protocol
147
190
  . /+ {
148
- m.bodyLines.each do |line|
149
- . &{line}
150
- end
191
+ m.bodyLines.each do |line|
192
+ . &{line}
193
+ end
151
194
  . }
195
+ end
152
196
  end
153
197
  end
154
198
 
@@ -22,7 +22,7 @@ class SwiftFile
22
22
  @file_name = name
23
23
  @file_path = File.join(root_path, @file_name)
24
24
 
25
- puts( "--- SwiftFile name = #{name} root_path = #{root_path} file_path = #{@file_path}" )
25
+ #puts( "--- SwiftFile name = #{name} root_path = #{root_path} file_path = #{@file_path}" )
26
26
 
27
27
  @is_user_file = is_user_file
28
28
  @elements = []
@@ -43,7 +43,7 @@ class SwiftFile
43
43
  end
44
44
  end
45
45
 
46
- def prepare_for_generation()
46
+ def prepare_for_generation
47
47
  @elements.each do |element|
48
48
  element.prepare_for_generation
49
49
  end
@@ -62,12 +62,14 @@ class SwiftNonPrimitive
62
62
  attr_accessor :definition_set
63
63
  attr_accessor :type_name
64
64
  attr_accessor :specified_type_name
65
- attr_accessor :access_control_modifier
65
+ attr_accessor :access_control_modifiers
66
66
  attr_accessor :inheritance_list # Raw parent list
67
67
 
68
68
  attr_accessor :file_name
69
69
  attr_accessor :source_file
70
70
 
71
+ attr_accessor :top_inner_comment_block # Useful for converted Objective-C classes
72
+
71
73
  attr_accessor :properties
72
74
  attr_accessor :initializers
73
75
  attr_accessor :methods
@@ -85,7 +87,7 @@ class SwiftNonPrimitive
85
87
  @type_name = type_name.nil? ? specified_type_name : type_name
86
88
  @file_name = file_name
87
89
  #@access_control_modifier = 'public '
88
- @access_control_modifier = ''
90
+ @access_control_modifiers = []
89
91
 
90
92
  @class_characteristics = [* characteristics]
91
93
  @is_user_editable = is_user_editable
@@ -96,6 +98,8 @@ class SwiftNonPrimitive
96
98
  @properties = []
97
99
  @post_super_initializations = {}
98
100
 
101
+ @top_inner_comment_block = []
102
+
99
103
  # This class will now be added to the definition set and its source file
100
104
  # The source file will be created if needed.
101
105
  @definition_set.add_element(self)
@@ -739,6 +743,28 @@ class SwiftClass < SwiftNonPrimitive
739
743
  end
740
744
  end
741
745
 
746
+ class SwiftCategory < SwiftClass
747
+ attr_accessor :categorized_class_name
748
+
749
+ def initialize( definition_set, specified_type_name, categorized_class_name, file_name: nil, characteristics:$default_swift_class_characteristics,
750
+ is_test_element: false, is_user_editable: false )
751
+ super( definition_set, specified_type_name, inheritance_list=[], file_name:file_name,
752
+ characteristics:characteristics, is_test_element:is_test_element, is_user_editable:is_user_editable )
753
+ @categorized_class_name = categorized_class_name || nil
754
+ end
755
+
756
+ end
757
+
758
+ class SwiftProtocol < SwiftClass
759
+ attr_accessor :categorized_class_name
760
+
761
+ def initialize( definition_set, specified_type_name, inheritance_list, file_name: nil, characteristics:$default_swift_class_characteristics )
762
+ super( definition_set, specified_type_name, inheritance_list=[], file_name:file_name,
763
+ characteristics:characteristics, is_test_element:false, is_user_editable:false )
764
+ @categorized_class_name = categorized_class_name || nil
765
+ end
766
+
767
+ end
742
768
 
743
769
  class SwiftUnitTestClass < SwiftClass
744
770
  attr_accessor :tested_class
@@ -754,7 +780,6 @@ class SwiftUnitTestClass < SwiftClass
754
780
  @source_file.add_import('XCTest')
755
781
  end
756
782
 
757
-
758
783
  def prepare_for_generation()
759
784
  super()
760
785
 
@@ -867,6 +892,9 @@ class SwiftProperty
867
892
  attr_accessor :getter_body
868
893
  attr_accessor :setter_body
869
894
  attr_accessor :rest_omit
895
+ attr_accessor :access_control_modifiers
896
+
897
+ attr_accessor :protocol_get_set_spec # for declarations in protocols
870
898
 
871
899
 
872
900
  def initialize(swift_class, property_name, property_type_symbol, mutability= :let, initialization_value:nil, collection_type: nil, required: true, rest_omit:nil )
@@ -881,7 +909,7 @@ class SwiftProperty
881
909
  @required = required
882
910
 
883
911
  #@access_control_modifier = 'public '
884
- @access_control_modifier = ''
912
+ @access_control_modifiers = nil
885
913
  @property_qualifiers = nil
886
914
 
887
915
  @initialization_value = initialization_value
@@ -889,13 +917,16 @@ class SwiftProperty
889
917
  @setter_body = nil
890
918
  @rest_omit = rest_omit
891
919
 
920
+ @protocol_get_set_spec = nil
921
+
892
922
  swift_class.properties << self
893
923
  end
894
924
 
895
925
  def declaration_lines
896
926
 
897
927
  qualifiers = []
898
- qualifiers += [*@property_qualifiers] if !@property_qualifiers.nil?
928
+ qualifiers += [*@access_control_modifiers] unless @access_control_modifiers.nil?
929
+ qualifiers += [*@property_qualifiers] unless @property_qualifiers.nil?
899
930
  qualifiers << @mutability_type.mutability
900
931
 
901
932
  declaration = "#{qualifiers.join(' ')} #{@property_name} : #{full_type_specifier()}"
@@ -912,9 +943,9 @@ class SwiftProperty
912
943
  end
913
944
  end
914
945
 
915
- if (!initial_value.nil?)
916
- declaration += " = #{initial_value}"
917
- end
946
+ declaration += " = #{initial_value}" unless initial_value.nil?
947
+
948
+ declaration += " #{@protocol_get_set_spec}" unless @protocol_get_set_spec.nil? # Must be set if part of a protocol definition
918
949
 
919
950
  # Computed Properties
920
951
  if !( @getter_body.nil? && @setter_body.nil? )
@@ -979,6 +1010,30 @@ class SwiftProperty
979
1010
  end
980
1011
 
981
1012
 
1013
+ class SwiftBlockProperty < SwiftProperty
1014
+
1015
+ attr_accessor :declaration_string
1016
+
1017
+ def initialize( swift_class, property_name, declaration_string, mutability= :let, initialization_value:nil, required: false )
1018
+
1019
+ super(swift_class, property_name, property_type_symbol, mutability= :let, initialization_value:nil, collection_type: nil, required: required, rest_omit:true )
1020
+ @declaration_string = declaration_string
1021
+ end
1022
+
1023
+ def resolve_type()
1024
+ @property_type = @declaration_string
1025
+ end
1026
+
1027
+ def full_type_specifier
1028
+ return @declaration_string
1029
+ end
1030
+
1031
+ def property_declared_type
1032
+ @declaration_string + @mutability_type.declaration_wrapping
1033
+ end
1034
+
1035
+ end
1036
+
982
1037
  class SwiftPersistentProperty < SwiftProperty
983
1038
  attr_accessor :json_key
984
1039
 
@@ -1294,7 +1349,7 @@ class SwiftMethodBase
1294
1349
  attr_accessor :returns
1295
1350
  attr_accessor :comment
1296
1351
 
1297
- attr_accessor :access_control_modifier
1352
+ attr_accessor :access_control_modifiers
1298
1353
  attr_accessor :func_qualifiers
1299
1354
 
1300
1355
  attr_accessor :indent
@@ -1311,7 +1366,7 @@ class SwiftMethodBase
1311
1366
  @indent = 0
1312
1367
  @bodyLines = []
1313
1368
 
1314
- @access_control_modifier = ''
1369
+ @access_control_modifiers = []
1315
1370
  end
1316
1371
 
1317
1372