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