Class: Fastlane::SwiftFunction

Inherits:
Object
  • Object
show all
Defined in:
fastlane/lib/fastlane/swift_fastlane_function.rb

Direct Known Subclasses

ToolSwiftFunction

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(action_name: nil, keys: nil, key_descriptions: nil, key_default_values: nil, key_optionality_values: nil, key_type_overrides: nil, return_type: nil) ⇒ SwiftFunction

Returns a new instance of SwiftFunction.


13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 13

def initialize(action_name: nil, keys: nil, key_descriptions: nil, key_default_values: nil, key_optionality_values: nil, key_type_overrides: nil, return_type: nil)
  @function_name = action_name
  @param_names = keys
  @param_descriptions = key_descriptions
  @param_default_values = key_default_values
  @param_optionality_values = key_optionality_values
  @return_type = return_type
  @param_type_overrides = key_type_overrides

  # rubocop:disable LineLength
  # class instance?
  @reserved_words = %w[associativity break case catch class continue convenience default deinit didSet do else enum extension fallthrough false final for func get guard if in infix init inout internal lazy let mutating nil operator override postfix precedence prefix private public repeat required return self set static struct subscript super switch throws true try var weak where while willSet].to_set
  # rubocop:enable LineLength
end

Instance Attribute Details

#default_values_to_ignoreObject

Returns the value of attribute default_values_to_ignore


11
12
13
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 11

def default_values_to_ignore
  @default_values_to_ignore
end

#function_nameObject

Returns the value of attribute function_name


3
4
5
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 3

def function_name
  @function_name
end

#param_default_valuesObject

Returns the value of attribute param_default_values


7
8
9
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 7

def param_default_values
  @param_default_values
end

#param_descriptionsObject

Returns the value of attribute param_descriptions


6
7
8
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 6

def param_descriptions
  @param_descriptions
end

#param_namesObject

Returns the value of attribute param_names


5
6
7
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 5

def param_names
  @param_names
end

#param_optionality_valuesObject

Returns the value of attribute param_optionality_values


8
9
10
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 8

def param_optionality_values
  @param_optionality_values
end

#param_type_overridesObject

Returns the value of attribute param_type_overrides


9
10
11
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 9

def param_type_overrides
  @param_type_overrides
end

#reserved_wordsObject

Returns the value of attribute reserved_words


10
11
12
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 10

def reserved_words
  @reserved_words
end

#return_typeObject

Returns the value of attribute return_type


4
5
6
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 4

def return_type
  @return_type
end

Instance Method Details

#build_argument_listObject


180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 180

def build_argument_list
  unless @param_names
    return "[]" # return empty list for argument
  end

  argument_object_strings = @param_names.zip(param_type_overrides).map do |name, type_override|
    sanitized_name = camel_case_lower(string: name)
    sanitized_name = sanitize_reserved_word(word: sanitized_name)
    type_string = type_override == :string_callback ? ", type: .stringClosure" : nil

    "RubyCommand.Argument(name: \"#{name}\", value: #{sanitized_name}#{type_string})"
  end
  return argument_object_strings
end

#camel_case_lower(string: nil) ⇒ Object


67
68
69
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 67

def camel_case_lower(string: nil)
  string.split('_').inject([]) { |buffer, e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
end

#determine_type_from_override(type_override: nil, default_type: nil) ⇒ Object


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 71

def determine_type_from_override(type_override: nil, default_type: nil)
  if type_override == Array
    return "[String]"
  elsif type_override == Hash
    return "[String : Any]"
  elsif type_override == Integer
    return "Int"
  elsif type_override == Boolean
    return "Bool"
  elsif type_override == :string_callback
    return "((String) -> Void)"
  else
    return default_type
  end
end

#get_type(param: nil, default_value: nil, optional: nil, param_type_override: nil) ⇒ Object


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 94

def get_type(param: nil, default_value: nil, optional: nil, param_type_override: nil)
  unless param_type_override.nil?
    type = determine_type_from_override(type_override: param_type_override)
  end
  type ||= "String"

  optional_specifier = ""
  # if we are optional and don't have a default value, we'll need to use ?
  optional_specifier = "?" if (optional && default_value.nil?) && type != "((String) -> Void)"

  # If we have a default value of true or false, we can infer it is a Bool
  if default_value.class == FalseClass
    type = "Bool"
  elsif default_value.class == TrueClass
    type = "Bool"
  elsif default_value.kind_of?(Array)
    type = "[String]"
  elsif default_value.kind_of?(Hash)
    type = "[String : Any]"
  elsif default_value.kind_of?(Integer)
    type = "Int"
  end
  return "#{type}#{optional_specifier}"
end

#implementationObject


219
220
221
222
223
224
225
226
227
228
229
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 219

def implementation
  args = build_argument_list

  implm = "  let command = RubyCommand(commandID: \"\", methodName: \"#{@function_name}\", className: nil, args: ["
  # Get the indent of the first argument in the list to give each
  # subsequent argument it's own line with proper indenting
  indent = ' ' * implm.length
  implm += args.join(",\n#{indent}")
  implm += "])\n"
  return implm + "  #{return_statement}"
end

#override_default_value_if_not_correct_type(param_name: nil, param_type: nil, default_value: nil) ⇒ Object


87
88
89
90
91
92
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 87

def override_default_value_if_not_correct_type(param_name: nil, param_type: nil, default_value: nil)
  return "[]" if param_type == "[String]" && default_value == ""
  return "{_ in }" if param_type == "((String) -> Void)"

  return default_value
end

#parametersObject


119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 119

def parameters
  unless @param_names
    return ""
  end

  param_names_and_types = @param_names.zip(param_default_values, param_optionality_values, param_type_overrides).map do |param, default_value, optional, param_type_override|
    type = get_type(param: param, default_value: default_value, optional: optional, param_type_override: param_type_override)

    unless default_value.nil?
      if type == "[String : Any]"
        # we can't handle default values for Hashes, yet
        default_value = "[:]"
      elsif type != "Bool" && type != "[String]" && type != "Int" && type != "((String) -> Void)"
        default_value = "\"#{default_value}\""
      end
    end

    # if we don't have a default value, but the param is optional, set a default value in Swift to be nil
    if optional && default_value.nil?
      default_value = "nil"
    end

    # sometimes we get to the point where we have a default value but its type is wrong
    # so we need to correct that because [String] = "" is not valid swift
    default_value = override_default_value_if_not_correct_type(param_type: type, param_name: param, default_value: default_value)

    param = camel_case_lower(string: param)
    param = sanitize_reserved_word(word: param)

    if default_value.nil?
      "#{param}: #{type}"
    else
      "#{param}: #{type} = #{default_value}"
    end
  end

  return param_names_and_types
end

#return_declarationObject


35
36
37
38
39
40
41
42
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 35

def return_declaration
  expected_type = swift_type_for_return_type
  unless expected_type.to_s.length > 0
    return ""
  end

  return " -> #{expected_type}"
end

#return_statementObject


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 195

def return_statement
  returned_object = "runner.executeCommand(command)"
  case @return_type
  when :array_of_strings
    returned_object = "parseArray(fromString: #{returned_object})"
  when :hash_of_strings
    returned_object = "parseDictionary(fromString: #{returned_object})"
  when :hash
    returned_object = "parseDictionary(fromString: #{returned_object})"
  when :bool
    returned_object = "parseBool(fromString: #{returned_object})"
  when :int
    returned_object = "parseInt(fromString: #{returned_object})"
  end

  expected_type = swift_type_for_return_type

  return_string = "_ = "
  if expected_type.length > 0
    return_string = "return "
  end
  return "#{return_string}#{returned_object}"
end

#sanitize_reserved_word(word: nil) ⇒ Object


28
29
30
31
32
33
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 28

def sanitize_reserved_word(word: nil)
  unless @reserved_words.include?(word)
    return word
  end
  return "`#{word}`"
end

#swift_codeObject

rubocop:enable Metrics/PerceivedComplexity


159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 159

def swift_code
  function_name = camel_case_lower(string: self.function_name)
  function_return_declaration = self.return_declaration
  discardable_result = function_return_declaration.length > 0 ? "@discardableResult " : ''

  # Calculate the necessary indent to line up parameter names on new lines
  # with the first parameter after the opening paren following the function name.
  # i.e.: @discardableResult func someFunctionName(firstParameter: T
  #                                                secondParameter: T)
  # This just creates a string with as many spaces are necessary given whether or not
  # the function has a 'discardableResult' annotation, the 'func' keyword, function name
  # and the opening paren.
  function_keyword_definition = 'func '
  open_paren = '('
  closed_paren = ')'
  indent = ' ' * (discardable_result.length + function_name.length + function_keyword_definition.length + open_paren.length)
  params = self.parameters.join(",\n#{indent}")

  return "#{discardable_result}#{function_keyword_definition}#{function_name}#{open_paren}#{params}#{closed_paren}#{function_return_declaration} {\n#{self.implementation}\n}"
end

#swift_type_for_return_typeObject


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'fastlane/lib/fastlane/swift_fastlane_function.rb', line 44

def swift_type_for_return_type
  unless @return_type
    return ""
  end

  case @return_type
  when :string
    return "String"
  when :array_of_strings
    return "[String]"
  when :hash_of_strings
    return "[String : String]"
  when :hash
    return "[String : Any]"
  when :bool
    return "Bool"
  when :int
    return "Int"
  else
    return ""
  end
end