Class: Objc2swiftAssistant::ObjC2SwiftFileConverter

Inherits:
FailableProcessingElement show all
Defined in:
lib/objc2swift_assistant/objc_2_swift.rb

Instance Attribute Summary collapse

Attributes inherited from FailableProcessingElement

#error_messages

Instance Method Summary collapse

Methods inherited from FailableProcessingElement

#add_error, #add_warning, #has_errors, #initiailize

Constructor Details

#initialize(objc_file_node, configuration) ⇒ ObjC2SwiftFileConverter

Returns a new instance of ObjC2SwiftFileConverter.



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 57

def initialize( objc_file_node, configuration )
  @objc_file_node = objc_file_node
  @configuration = configuration
  @enums = {}
  @classes_by_name = {}
  @categories_by_class_and_name = {}
  @protocols = []

  @access_control_state = nil
  @protocol_optional_state = false
end

Instance Attribute Details

#access_control_stateObject

Returns the value of attribute access_control_state.



54
55
56
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 54

def access_control_state
  @access_control_state
end

#categories_by_class_and_nameObject

Returns the value of attribute categories_by_class_and_name.



49
50
51
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 49

def categories_by_class_and_name
  @categories_by_class_and_name
end

#classes_by_nameObject

Returns the value of attribute classes_by_name.



48
49
50
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 48

def classes_by_name
  @classes_by_name
end

#configurationObject

Returns the value of attribute configuration.



52
53
54
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 52

def configuration
  @configuration
end

#enumsObject

Returns the value of attribute enums.



47
48
49
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 47

def enums
  @enums
end

#objc_file_nodeObject

Returns the value of attribute objc_file_node.



46
47
48
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 46

def objc_file_node
  @objc_file_node
end

#protocol_optional_stateObject

Returns the value of attribute protocol_optional_state.



55
56
57
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 55

def protocol_optional_state
  @protocol_optional_state
end

#protocolsObject

Returns the value of attribute protocols.



50
51
52
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 50

def protocols
  @protocols
end

#swift_file_nodeObject

Returns the value of attribute swift_file_node.



51
52
53
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 51

def swift_file_node
  @swift_file_node
end

Instance Method Details

#cannonical_source_file_pathObject



223
224
225
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 223

def cannonical_source_file_path
  objc_file_node.cannonical_source_file_path
end

#category_for_class_and_name(class_name, category_name) ⇒ Object



208
209
210
211
212
213
214
215
216
217
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 208

def category_for_class_and_name( class_name, category_name )
  the_key = [class_name, category_name]
  category_converter = @categories_by_class_and_name[ the_key ]
  if category_converter.nil?
    category_converter = ObjC2SwiftCategoryConverter.new( self, class_name, category_name, @configuration )
    @categories_by_class_and_name[ [class_name, category_name] ] = category_converter
  end

  category_converter
end

#class_for_name(class_name) ⇒ Object

Utility



198
199
200
201
202
203
204
205
206
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 198

def class_for_name( class_name )
  class_converter = @classes_by_name[ class_name ]
  if class_converter.nil?
    class_converter = ObjC2SwiftClassConverter.new( self, class_name, @configuration )
    @classes_by_name[ class_name ] = class_converter
  end

  class_converter
end

#dump(indent, tab, errors_only) ⇒ Object



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 227

def dump( indent, tab, errors_only )
    puts( "#{indent}Generating Swift file #{@swift_file_node.relative_path} at #{@swift_file_node.full_path}" )

    #objc_file_node
    #enums
    puts( "\n#{indent}Generated Classes:" ) unless @classes_by_name.length == 0
    @classes_by_name.each do  | _, class_converter |
      puts( "#{indent+tab}#{class_converter.class_name}" )
    end

    puts( "\n#{indent}Generated Categories:" ) unless @categories_by_class_and_name.length == 0
    @categories_by_class_and_name.each do | _, category_converter |
      category_str = category_converter.category_name.nil? ? "" : " /*#{category_converter.category_name}*/"
      puts( "#{indent+tab}#{category_converter.class_name}#{category_str}" )
    end

    puts( "\n#{indent}Generated Prototcols:" ) unless @protocols.length == 0
    @protocols.each do  | protocol |
      puts( "#{indent+tab}#{protocol.class_name}" )
    end

  #protocols
    #configuration
end

#generate(generator_defs, configuration, dry_run) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 176

def generate( generator_defs, configuration, dry_run )
  @configuration.log_verbose( "Generating #{@swift_file_node.relative_path} at #{@swift_file_node.full_path}" )

  @enums.each do |enum_converter|

  end

  @classes_by_name.each do |key, class_converter|
    class_converter.generate( generator_defs, @swift_file_node.relative_path, configuration, dry_run )
  end

  @categories_by_class_and_name.each do |_, category_converter|
    category_converter.generate( generator_defs, @swift_file_node.relative_path, configuration, dry_run )
  end

  @protocols.each do | protcol_converter|
    protcol_converter.generate( generator_defs, @swift_file_node.relative_path, configuration, dry_run )
  end
end

#prepareObject



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 69

def prepare( )
  @objc_file_node.root_matches.each do |region|

    if region.region_type == CLASS_INTERFACE_KEY
      class_converter = class_for_name( region.class_name )
      class_converter.interface_region = region
      process_interface_sub_regions( region, class_converter )
    elsif region.region_type == CLASS_IMPLEMENTATION_KEY
      class_converter = class_for_name( region.class_name )
      class_converter.implementation_region = region
      process_impl_sub_regions( region, class_converter )
    elsif region.region_type == EXTENSION_DECLARARATION_KEY
      class_converter = class_for_name( region.class_name )
      extension_converter = ObjC2SwiftCategoryConverter.new( self, region.class_name, nil, @configuration   )
      extension_converter.interface_region = region
      class_converter.extension_converter = extension_converter
    elsif region.region_type == CATEGORY_DECLARARATION_KEY
      category_converter = category_for_class_and_name( region.class_name, region.category_name  )
      category_converter.interface_region = region
      process_interface_sub_regions( region, category_converter )
    elsif region.region_type == CATEGORY_IMPLEMENTATION_KEY
      category_converter = category_for_class_and_name( region.class_name, region.category_name  )
      category_converter.implementation_region = region
      process_impl_sub_regions( region, category_converter )
    elsif region.region_type == PROTOCOL_DECLARATION_KEY
      protocol_converter = ObjC2SwiftProtocolConverter.new( self, region.protocol_name, @configuration )
      protocol_converter.interface_region = region
      @protocols << protocol_converter
      process_interface_sub_regions( region, protocol_converter )

      # category_converter.implementation_region = region
      # process_impl_sub_regions( region, category_converter )
      @configuration.log_warning( "protocols NYI")
    elsif region.region_type == ENUM_DECLARATION_KEY
      @configuration.log_warning( "Not Yet Implemented Region Type: #{region.region_type.to_s}")
    elsif region.region_type == PRAGMA_MARK_KEY
      @configuration.log_warning( "Not Yet Implemented Region Type: #{region.region_type.to_s}")
    else
      @configuration.log_warning( "Unexpected Root Region Type: #{region.region_type.to_s}")
    end
  end # Iterating over root matches

  @classes_by_name.each_value do |class_converter|
    class_converter.prepare
  end

  @categories_by_class_and_name.each do |_, category_converter|
    category_converter.prepare
  end

  @protocols.each do | protcol_converter|
    protcol_converter.prepare
  end
end

#process_at_directive_region(region) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 162

def process_at_directive_region( region )
  directive = region.directive_symbol

  if( directive == :required )
    @protocol_optional_state = directive
  elsif ( directive == :optional )
    @protocol_optional_state = directive
  elsif ( [:public, :private, :protected].include? directive )
    @access_control_state = directive
  else
    add_error( "unknown '@' directive: #{directive}")
  end
end

#process_impl_sub_regions(impl_region, class_converter) ⇒ Object

common logic for class-like entities (classes, categories)



151
152
153
154
155
156
157
158
159
160
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 151

def process_impl_sub_regions( impl_region, class_converter )
  impl_region.sub_regions.each do |sub_region|
    if sub_region.region_type == METHOD_IMPLEMENTATION_KEY
      method = class_converter.method_for_signature( sub_region.objc_signature )
      method.implementation_region = sub_region
    else
      unexpected_sub_region( sub_region, impl_region )
    end
  end
end

#process_interface_sub_regions(interface_region, class_converter) ⇒ Object

common logic for class-like entities (classes, categories, extensions)



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 125

def process_interface_sub_regions( interface_region, class_converter )

  @configuration.log_verbose( "\nprocess_interface_sub_regions") unless interface_region.sub_regions.length == 0

  interface_region.sub_regions.each do |sub_region|
    @configuration.log_verbose( "#{sub_region.region_type} #{sub_region.starting_line_number} #{sub_region.detection_line}" )

    if sub_region.region_type == PROPERTY_DECLARATION_KEY
      property = class_converter.property_for_name( sub_region.name )
      property.declaration_region = sub_region
      property.access_control_state = @access_control_state
      property.protocol_optional_state = @protocol_optional_state
    elsif sub_region.region_type == METHOD_DECLARATION_KEY
      method = class_converter.method_for_signature( sub_region.objc_signature )
      method.declaration_region = sub_region
      method.access_control_state = @access_control_state
      method.protocol_optional_state = @protocol_optional_state
    elsif sub_region.region_type == AT_DIRECTIVE_KEY
      process_at_directive_region( sub_region )
    else
      unexpected_sub_region( sub_region, interface_region )
    end
  end
end

#unexpected_sub_region(sub_region, region) ⇒ Object



219
220
221
# File 'lib/objc2swift_assistant/objc_2_swift.rb', line 219

def unexpected_sub_region( sub_region, region )
  @configuration.log_warning( "Unexpected Sub Region Type: #{sub_region.region_type.to_s} of #{region.region_type.to_s}")
end