class SwiftGenerator::SwiftClass
A Swift Class to be generated.
Attributes
access_control_modifier[RW]
Convenience
auto_test_class[RW]
Associated classes
do_generate[RW]
parent_class[RW]
post_super_initializations[RW]
Initializations
supporting_elements_created[RW]
test_object_method[RW]
Public Class Methods
new(definition_set, specified_type_name, inheritance_list=[], file_name: nil, characteristics:$default_swift_class_characteristics, is_test_element: false, is_user_editable: false)
click to toggle source
@param [SwiftDefinitionSet] definition_set @param [String] type_name @param [Array] inherited_from @param [Object] file_name @param [Object] characteristics @param [Object] is_test_class
Calls superclass method
SwiftGenerator::SwiftNonPrimitive::new
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 372 def initialize (definition_set, specified_type_name, inheritance_list=[], file_name: nil, characteristics:$default_swift_class_characteristics, is_test_element: false, is_user_editable: false) # Generate the type name from the specified type name. Non-editable classes are prepended with "_" prefix = characteristics.include?(:create_user_class) ? '_' : '' type_name = prefix + specified_type_name super( definition_set, specified_type_name, inheritance_list=inheritance_list, type_name:type_name, file_name:file_name, characteristics:characteristics, is_user_editable:is_user_editable, is_test_element: is_test_element ) @parent_class = nil #change for known & legal combinations of characteristics abort( "illegal class characteristics" ) if ! definition_set.characteristics_are_legal(@class_characteristics ) # prefix = @class_characteristics.include?(:create_user_class) ? '_' : '' # @type_name = prefix + @specified_type_name @do_generate = true @supporting_elements_created = false end
Public Instance Methods
add_simple_class_property( name, type, value:nil, mutability: :var, override:false)
click to toggle source
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 397 def add_simple_class_property( name, type, value:nil, mutability: :var, override:false) # class variables not supported. Use class property instead. p = SwiftProperty.new(self, name, type, mutability ) p.property_qualifiers = 'class' p.property_qualifiers = "override #{p.property_qualifiers}" if override p.getter_body = "return #{value}" end
create_copy_methods()
click to toggle source
Copy methods
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 626 def create_copy_methods() copy_to_method_name = "copyTo#{@type_name}" # The copy method - calls copyTo so that we can avoid duplicating copy code copy_m = SwiftMethod.new(self, 'copy', '', 'AnyObject', override: true) copy_m << "let theCopy = #{@type_name}()" copy_m << "#{copy_to_method_name}( theCopy )" copy_m << "return theCopy" copy_to_m = SwiftMethod.new(self, copy_to_method_name, "other: #{@type_name}", nil, override:false) if !@parent_class.nil? copy_to_m << "super.copyTo#{@parent_class.type_name}( other )" end self.persistent_properties.each do |prop| copy_to_m << "\tother.#{prop.property_name} = #{prop.property_name}" end end
create_description_methods()
click to toggle source
Description methods
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 646 def create_description_methods() # description dm = SwiftMethod.new(self, 'description', 'indent:String=" ", diagnostic:Bool=false', "NSString", override:!@parent_class.nil? ) dm << "let d = NSMutableString()" if @parent_class.nil? else dm << "d.appendString( super.description(indent:indent, diagnostic:diagnostic) )" end dm << "if( diagnostic ) {" dm.ii "d.appendString( \" properties of class #{@type_name} :\\n\")" dm.ii "d.appendString( \"\\(indent)- none -\\n\")" if @properties.empty? dm << "}" self.persistent_properties.each do |prop| if( prop.is_optional ) prop_value = prop.property_name if prop.property_type.swift_kind == :enum dm << "d.appendString( \"\\(indent)#{prop.property_name} = \\(prettyFormatEnum( #{prop_value} ))\\n\" )" else dm << "d.appendString( \"\\(indent)#{prop.property_name} = \\(prettyFormat( #{prop_value} ))\\n\" )" end else dm << "d.appendString( \"\\(indent)#{prop.property_name} = \\(#{prop_value})\\n\" )" end end dm << "return d" # className type_name_m = SwiftMethod.new(self, 'className', nil, 'String', override:!@parent_class.nil? ) type_name_m .func_qualifiers = 'class' type_name_m << "return \"#{@type_name}\"" end
create_equality_methods()
click to toggle source
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 501 def create_equality_methods() comparable_super = super_has_characteristics(:comparable) #func isEqual(_ anObject: AnyObject!) -> Bool is_equals_method = SwiftMethod.new(self, 'isEqual', 'other:AnyObject!', 'Bool', override: true) is_equals_method << "if( other == nil ) { return false }" other_typed_var = "other#{@type_name}" if comparable_super is_equals_method << "if( !super.isEqual( other )) { return false }" end is_equals_method << "" is_equals_method << "if let #{other_typed_var} = other as? #{@type_name} {" comparable_properties.each do |property| other_name = "#{other_typed_var}.#{property.property_name}" if property.property_type.nil? puts( property.property_name ) end if property.collection_type == :array is_equals_method.ii "if( !optionalArraysEqual( #{property.property_name}, #{other_name} )) { return false }" else custom_test = property.property_type.custom_equality_test if custom_test.nil? is_equals_method.ii "if( self.#{property.property_name} != #{other_name} ) { return false }" else is_equals_method.ii "if( !#{custom_test.call(property.property_name, other_name)} ) { return false }" end end end is_equals_method << "" << "\treturn true" is_equals_method << "} else {" is_equals_method << "\treturn false" is_equals_method << "}" #- (NSUInteger)hash hash_method = SwiftMethod.new(self, 'hashValue', '', 'Int', override: comparable_super) hash_method << "var hasher = Hasher() // Hasher must be mutable" << "" if comparable_super hash_method << 'hasher.hashIn( super.hashValue() )' end comparable_properties.each do |property| hash_element = lambda{ |var_name, is_optional| "hasher.hashIn( #{property.property_type.hashable_value(var_name, is_optional )} )"} if( property.collection_type.nil?) hash_method << hash_element.call(property.property_name, property.mutability_type.must_be_unwrapped) elsif( property.collection_type == :array ) arrayName = "#{property.property_name}Array" hash_method << "if let #{arrayName} = #{property.property_name} {" hash_method._i "for element in #{arrayName} {" hash_method.ii hash_element.call("element", false) hash_method._o "}" hash_method << "}" else hash_method << "ERROR: hashing of #{property.collection_type.to_s} collections not supported." end end hash_method << "" << "return hasher.hash" end
create_init_methods()
click to toggle source
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 488 def create_init_methods() # Only no-argument init methods & optional properties are currently supported return if @post_super_initializations.empty? init_m = SwiftInitializer.new(self, 'init', nil, override: true) init_m << "super.init()" keys = @post_super_initializations.keys.sort! keys.each do |prop_name| init_m << "#{prop_name} = #{@post_super_initializations[prop_name]}" end end
create_test_classes()
click to toggle source
Test class generation
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 691 def create_test_classes() tc = @auto_test_class = SwiftUnitTestClass.new(@definition_set, self, 'AutoGenerated') end
create_user_classes()
click to toggle source
User class generation
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 685 def create_user_classes user_class_characteristics = @class_characteristics - [:make_test_class, :create_user_class] @user_editable_class = SwiftClass.new(@definition_set, @specified_type_name, [@type_name], characteristics:user_class_characteristics, is_user_editable:true ) end
ensure_test_object_method()
click to toggle source
Test Support ( Here for embedded objects )
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 721 def ensure_test_object_method #NOTE: this method is in the global test support class return if !@test_object_method.nil? comment = "/// Create a test #{@type_name} object with varying values" # e.g. func makeTestUser() -> User obj_name = "test#{@type_name}" m = SwiftMethod.new(@definition_set.test_support_class, "makeTest#{@type_name}", '_ index:Int = 0', "#{@type_name}", comment: comment) m.func_qualifiers = 'class' m << "let #{obj_name} = #{@type_name}()" << "" prop_index = 1 set_test_values( m, obj_name, 1 ) m << "" << "return #{obj_name}" @test_object_method = m end
insert_marshal_expression( m, unwrapped_var, destination )
click to toggle source
JSON marshaling support
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 432 def insert_marshal_expression( m, unwrapped_var, destination ) #Probably only works for String enums m << "let objectDictionary = NSMutableDictionary()" m << "#{unwrapped_var}.marshalToJSON( objectDictionary )" m << "#{destination} = objectDictionary" end
insert_unmarshal_expression( m, unwrapped_value, destination )
click to toggle source
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 439 def insert_unmarshal_expression( m, unwrapped_value, destination ) #Probably only works for String enums m << "let temp = #{self.type_name}()" m << "temp.unmarshalFromJSON( #{unwrapped_value} )" # TODO: validate? m << "#{destination} = temp" end
make_property_type()
click to toggle source
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 405 def make_property_type() # Make a type for this class so that references to this class can be resolved type_symbol = @type_name.to_sym test_value_lambda = lambda{|num| ensure_test_object_method test_object_method_call(num) } property_type = SwiftObjectPropertyType.new( self, :NSDictionary, test_value:test_value_lambda ) property_type.hashable_value_lambda = lambda{|var_name, is_optional| if is_optional return "#{var_name}?.hashValue()" else return "#{var_name}.hashValue()" end } #TODO Fix this Horror property_type.custom_unmarshaling = lambda{|var_name, unwrapped_var| [ "#{var_name} = #{unmarshal_expression(unwrapped_var)}" ]} return self.swift_type_symbol, property_type end
post_super_init( values_for_properties )
click to toggle source
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 393 def post_super_init( values_for_properties ) @post_super_initializations.merge!( values_for_properties ) end
prepare_for_generation()
click to toggle source
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 479 def prepare_for_generation() create_init_methods create_equality_methods if @class_characteristics.include?(:comparable) prepare_marshaling_code if @class_characteristics.include?(:json_serializable) create_description_methods if @class_characteristics.include?(:auto_describing) create_copy_methods if @class_characteristics.include?(:json_serializable) end
prepare_marshaling_code()
click to toggle source
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 565 def prepare_marshaling_code() super_does_json = super_has_characteristics(:json_serializable) # Reader & Writer reader = SwiftMethod.new(self, 'unmarshalFromJSON', 'jsonObject:NSDictionary', nil, override: super_does_json ) writer = SwiftMethod.new(self, 'marshalToJSON', 'jsonObject:NSMutableDictionary', nil, override: super_does_json ) if super_does_json reader << "super.unmarshalFromJSON( jsonObject )" writer << "super.marshalToJSON( jsonObject )" end writer << "" << "jsonObject[\"objectType\"] = \"#{@type_name}\"" persistent_properties.each do |prop| prop.unmarshal_code(reader) prop.marshal_code(writer) end # Object Reader object_reader = SwiftMethod.new(self, "objectFromJSON", 'newObjData:NSDictionary', @specified_type_name, override: super_does_json ) object_reader.func_qualifiers = 'class' object_reader << "let newObj = #{@specified_type_name}()" object_reader << "newObj.unmarshalFromJSON( newObjData )" object_reader << 'return newObj' # Array Reader & Writer # Array Reader array_reader = SwiftMethod.new(self, "arrayFromJSON", 'json:NSArray', '[USIBaseModel]', override: super_does_json ) array_reader.func_qualifiers = 'class' array_reader << "var newObjects = [#{@specified_type_name}]()" array_reader << "for objEntry in json {" array_reader << "\tlet newObj = #{@specified_type_name}()" array_reader << "\tif let newObjData = objEntry as? NSDictionary {" array_reader << "\t\tnewObj.unmarshalFromJSON( newObjData )" array_reader << "\t\tnewObjects.append( newObj )" array_reader << "\t}" array_reader << '}' array_reader << 'return newObjects' # Array Writer array_writer = SwiftMethod.new(self, "arrayToJSON", "array:[USIBaseModel]", 'NSMutableArray', override: super_does_json ) array_writer.func_qualifiers = 'class' array_writer << 'var dataArray = NSMutableArray()' array_writer << "for obj in array {" array_writer << "\tlet objData = NSMutableDictionary()" array_writer << "\tobj.marshalToJSON( objData )" array_writer << "\tdataArray.addObject( objData )" array_writer << "}" array_writer << "return dataArray" end
prepare_supporting_elements()
click to toggle source
Called before all other generation-time methods. Construct other related or required elements May be called more than once
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 463 def prepare_supporting_elements() return if @supporting_elements_created create_user_classes if @class_characteristics.include?(:create_user_class) create_test_classes if ! @is_test_element && @class_characteristics.include?(:make_test_class) @supporting_elements_created = true end
resolve_inheritance()
click to toggle source
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 473 def resolve_inheritance() return if @inheritance_list.empty? @parent_class = @definition_set.elements_by_name[ @inheritance_list[0] ] end
set_test_values( set_method, variable_name, indexing_number )
click to toggle source
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 707 def set_test_values( set_method, variable_name, indexing_number ) if ! @parent_class.nil? indexing_number = @parent_class.set_test_values( set_method, variable_name, indexing_number ) end comparable_properties.each do |prop| set_method << "#{variable_name}.#{prop.property_name} = #{prop.make_test_value(indexing_number)}" indexing_number += 1 end return indexing_number end
super_has_characteristics( *characteristics )
click to toggle source
Utility
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 696 def super_has_characteristics( *characteristics ) remaining_characteristics = characteristics ancestor = @parent_class until ancestor.nil? || remaining_characteristics.empty? remaining_characteristics = (remaining_characteristics - ancestor.class_characteristics) ancestor = ancestor.parent_class end return remaining_characteristics.empty? end
test_object_method_call(index=0)
click to toggle source
# File lib/swift_generator/code_generation/swift_class_generation.rb, line 740 def test_object_method_call(index=0) argStr = index == 0 ? '' : "#{index}" "#{@definition_set.test_support_class.type_name}.makeTest#{@type_name}(#{argStr})" end