cocoapods-core 0.30.0 → 1.15.2

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.
Files changed (50) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +7 -10
  3. data/lib/cocoapods-core/build_type.rb +121 -0
  4. data/lib/cocoapods-core/cdn_source.rb +501 -0
  5. data/lib/cocoapods-core/core_ui.rb +4 -3
  6. data/lib/cocoapods-core/dependency.rb +100 -73
  7. data/lib/cocoapods-core/gem_version.rb +1 -2
  8. data/lib/cocoapods-core/github.rb +32 -5
  9. data/lib/cocoapods-core/http.rb +86 -0
  10. data/lib/cocoapods-core/lockfile.rb +161 -56
  11. data/lib/cocoapods-core/metrics.rb +47 -0
  12. data/lib/cocoapods-core/platform.rb +99 -11
  13. data/lib/cocoapods-core/podfile/dsl.rb +623 -124
  14. data/lib/cocoapods-core/podfile/target_definition.rb +662 -109
  15. data/lib/cocoapods-core/podfile.rb +138 -65
  16. data/lib/cocoapods-core/requirement.rb +37 -8
  17. data/lib/cocoapods-core/source/acceptor.rb +16 -13
  18. data/lib/cocoapods-core/source/aggregate.rb +79 -103
  19. data/lib/cocoapods-core/source/health_reporter.rb +9 -18
  20. data/lib/cocoapods-core/source/manager.rb +488 -0
  21. data/lib/cocoapods-core/source/metadata.rb +79 -0
  22. data/lib/cocoapods-core/source.rb +241 -70
  23. data/lib/cocoapods-core/specification/consumer.rb +187 -47
  24. data/lib/cocoapods-core/specification/dsl/attribute.rb +49 -85
  25. data/lib/cocoapods-core/specification/dsl/attribute_support.rb +6 -8
  26. data/lib/cocoapods-core/specification/dsl/deprecations.rb +9 -126
  27. data/lib/cocoapods-core/specification/dsl/platform_proxy.rb +30 -20
  28. data/lib/cocoapods-core/specification/dsl.rb +943 -296
  29. data/lib/cocoapods-core/specification/json.rb +64 -23
  30. data/lib/cocoapods-core/specification/linter/analyzer.rb +218 -0
  31. data/lib/cocoapods-core/specification/linter/result.rb +128 -0
  32. data/lib/cocoapods-core/specification/linter.rb +310 -309
  33. data/lib/cocoapods-core/specification/root_attribute_accessors.rb +90 -39
  34. data/lib/cocoapods-core/specification/set/presenter.rb +35 -71
  35. data/lib/cocoapods-core/specification/set.rb +42 -96
  36. data/lib/cocoapods-core/specification.rb +368 -130
  37. data/lib/cocoapods-core/standard_error.rb +45 -24
  38. data/lib/cocoapods-core/trunk_source.rb +14 -0
  39. data/lib/cocoapods-core/vendor/requirement.rb +133 -53
  40. data/lib/cocoapods-core/vendor/version.rb +197 -156
  41. data/lib/cocoapods-core/vendor.rb +1 -5
  42. data/lib/cocoapods-core/version.rb +137 -42
  43. data/lib/cocoapods-core/yaml_helper.rb +334 -0
  44. data/lib/cocoapods-core.rb +10 -4
  45. metadata +100 -27
  46. data/lib/cocoapods-core/source/abstract_data_provider.rb +0 -71
  47. data/lib/cocoapods-core/source/file_system_data_provider.rb +0 -150
  48. data/lib/cocoapods-core/source/github_data_provider.rb +0 -143
  49. data/lib/cocoapods-core/specification/set/statistics.rb +0 -266
  50. data/lib/cocoapods-core/yaml_converter.rb +0 -192
@@ -1,8 +1,7 @@
1
- require 'active_support/core_ext/string/strip.rb'
1
+ require 'cocoapods-core/specification/root_attribute_accessors'
2
2
 
3
3
  module Pod
4
4
  class Specification
5
-
6
5
  # Allows to conveniently access a Specification programmatically.
7
6
  #
8
7
  # It takes care of:
@@ -10,6 +9,7 @@ module Pod
10
9
  # - standardizing the attributes
11
10
  # - handling multi-platform values
12
11
  # - handle default values
12
+ # - handle automatic container wrapping of values
13
13
  # - handle inherited values
14
14
  #
15
15
  # This class allows to store the values of the attributes in the
@@ -18,7 +18,6 @@ module Pod
18
18
  # serializing a specification back exactly as defined in a file.
19
19
  #
20
20
  class Consumer
21
-
22
21
  # @return [Specification] The specification to consume.
23
22
  #
24
23
  attr_reader :spec
@@ -55,11 +54,21 @@ module Pod
55
54
  end
56
55
  end
57
56
 
57
+ DSL::RootAttributesAccessors.instance_methods.each do |root_accessor|
58
+ define_method(root_accessor) do
59
+ spec.root.send(root_accessor)
60
+ end
61
+ end
62
+
58
63
  #-----------------------------------------------------------------------#
59
64
 
60
65
  # @!group Regular attributes
61
66
 
62
- # @return [Bool] Whether the source files of the specification require to
67
+ # @return [String] The name of the specification.
68
+ #
69
+ spec_attr_accessor :name
70
+
71
+ # @return [Boolean] Whether the source files of the specification require to
63
72
  # be compiled with ARC.
64
73
  #
65
74
  spec_attr_accessor :requires_arc
@@ -86,9 +95,24 @@ module Pod
86
95
  spec_attr_accessor :compiler_flags
87
96
 
88
97
  # @return [Hash{String => String}] the xcconfig flags for the current
89
- # specification.
98
+ # specification for the pod target.
99
+ #
100
+ def pod_target_xcconfig
101
+ attr = Specification::DSL.attributes[:pod_target_xcconfig]
102
+ merge_values(attr, value_for_attribute(:xcconfig), value_for_attribute(:pod_target_xcconfig))
103
+ end
104
+
105
+ # @return [Hash{String => String}] the xcconfig flags for the current
106
+ # specification for the user target.
107
+ #
108
+ def user_target_xcconfig
109
+ attr = Specification::DSL.attributes[:user_target_xcconfig]
110
+ merge_values(attr, value_for_attribute(:xcconfig), value_for_attribute(:user_target_xcconfig))
111
+ end
112
+
113
+ # @return [Hash{String => String}] the Info.plist values for the current specification
90
114
  #
91
- spec_attr_accessor :xcconfig
115
+ spec_attr_accessor :info_plist
92
116
 
93
117
  # @return [String] The contents of the prefix header.
94
118
  #
@@ -98,6 +122,14 @@ module Pod
98
122
  #
99
123
  spec_attr_accessor :prefix_header_file
100
124
 
125
+ # @return [String] the module name.
126
+ #
127
+ spec_attr_accessor :module_name
128
+
129
+ # @return [String] the path of the module map file.
130
+ #
131
+ spec_attr_accessor :module_map
132
+
101
133
  # @return [String] the headers directory.
102
134
  #
103
135
  spec_attr_accessor :header_dir
@@ -109,6 +141,23 @@ module Pod
109
141
 
110
142
  #-----------------------------------------------------------------------#
111
143
 
144
+ # @!group Test Support
145
+
146
+ # @return [Boolean] Whether this test specification requires an app host.
147
+ #
148
+ spec_attr_accessor :requires_app_host
149
+ alias_method :requires_app_host?, :requires_app_host
150
+
151
+ # @return [String] Name of the app host this spec requires
152
+ #
153
+ spec_attr_accessor :app_host_name
154
+
155
+ # @return [Symbol] the test type supported by this specification.
156
+ #
157
+ spec_attr_accessor :test_type
158
+
159
+ #-----------------------------------------------------------------------#
160
+
112
161
  # @!group File patterns
113
162
 
114
163
  # @return [Array<String>] the source files of the Pod.
@@ -119,6 +168,10 @@ module Pod
119
168
  #
120
169
  spec_attr_accessor :public_header_files
121
170
 
171
+ # @return [Array<String>] the project headers of the Pod.
172
+ #
173
+ spec_attr_accessor :project_header_files
174
+
122
175
  # @return [Array<String>] the private headers of the Pod.
123
176
  #
124
177
  spec_attr_accessor :private_header_files
@@ -133,12 +186,27 @@ module Pod
133
186
  #
134
187
  spec_attr_accessor :vendored_libraries
135
188
 
136
- # @return [Hash{String=>String}]] hash where the keys are the names of
189
+ # @return [Hash{String => Array<String>}] hash where the keys are the tags of
190
+ # the on demand resources and the values are their relative file
191
+ # patterns.
192
+ #
193
+ spec_attr_accessor :on_demand_resources
194
+
195
+ # @return [Hash{String=>String}]] hash where the keys are the names of
137
196
  # the resource bundles and the values are their relative file
138
197
  # patterns.
139
198
  #
140
199
  spec_attr_accessor :resource_bundles
141
200
 
201
+ # @return [Array<Hash{Symbol=>String}>] An array of hashes where each hash
202
+ # represents a script phase.
203
+ #
204
+ spec_attr_accessor :script_phases
205
+
206
+ # @return [Hash] A hash that contains the scheme configuration.
207
+ #
208
+ spec_attr_accessor :scheme
209
+
142
210
  # @return [Array<String>] A hash where the key represents the
143
211
  # paths of the resources to copy and the values the paths of
144
212
  # the resources that should be copied.
@@ -157,8 +225,6 @@ module Pod
157
225
 
158
226
  #-----------------------------------------------------------------------#
159
227
 
160
- # @!group Dependencies
161
-
162
228
  # @return [Array<Dependency>] the dependencies on other Pods.
163
229
  #
164
230
  def dependencies
@@ -168,10 +234,10 @@ module Pod
168
234
  end
169
235
  end
170
236
 
237
+ # Raw values need to be prepared as soon as they are read so they can be
238
+ # safely merged to support multi platform attributes and inheritance
171
239
  #-----------------------------------------------------------------------#
172
240
 
173
- private
174
-
175
241
  # Returns the value for the attribute with the given name for the
176
242
  # specification. It takes into account inheritance, multi-platform
177
243
  # attributes and default values.
@@ -184,8 +250,8 @@ module Pod
184
250
  def value_for_attribute(attr_name)
185
251
  attr = Specification::DSL.attributes[attr_name]
186
252
  value = value_with_inheritance(spec, attr)
187
- value ||= attr.default(platform_name)
188
- value ||= attr.container.new if attr.container
253
+ value = attr.default(platform_name) if value.nil?
254
+ value = attr.container.new if value.nil? && attr.container
189
255
  value
190
256
  end
191
257
 
@@ -261,12 +327,7 @@ module Pod
261
327
  r.compact
262
328
  elsif attr.container == Hash
263
329
  existing_value.merge(new_value) do |_, old, new|
264
- if new.is_a?(Array) || old.is_a?(Array)
265
- r = [*old] + [*new]
266
- r.compact
267
- else
268
- old + ' ' + new
269
- end
330
+ merge_hash_value(attr, old, new)
270
331
  end
271
332
  else
272
333
  new_value
@@ -285,49 +346,53 @@ module Pod
285
346
  # prepare hook was defined.
286
347
  #
287
348
  def prepare_value(attr, value)
288
- if attr.container == Array
289
- value = [*value].compact
349
+ if attr.container == Array
350
+ value = if value.is_a?(Hash)
351
+ [value]
352
+ else
353
+ [*value].compact
354
+ end
290
355
  end
291
356
 
292
357
  hook_name = prepare_hook_name(attr)
293
358
  if self.respond_to?(hook_name, true)
294
- value = send(hook_name, value)
359
+ send(hook_name, value)
295
360
  else
296
361
  value
297
362
  end
298
363
  end
299
364
 
300
- #-----------------------------------------------------------------------#
301
-
302
365
  private
303
366
 
304
- # Converts the keys of the given hash to a string.
367
+ # Merges two values in a hash together based on the needs of the attribute
305
368
  #
306
- # @todo Removed if not used by `resources_bundle`
369
+ # @param [Specification::DSL::Attribute] attr
370
+ # the attribute for which that value is needed.
307
371
  #
308
- # @param [Object] value
309
- # the value that needs to be stripped from the Symbols.
372
+ # @param [Object] old the value from the original hash
310
373
  #
311
- # @return [Hash] the hash with the strings instead of the keys.
374
+ # @param [Object] new the value from the new hash
312
375
  #
313
- # def convert_keys_to_symbol(value)
314
- # return unless value
315
- # result = {}
316
- # value.each do |key, subvalue|
317
- # subvalue = convert_keys_to_symbol(subvalue) if subvalue.is_a?(Hash)
318
- # result[key.to_sym] = subvalue
319
- # end
320
- # result
321
- # end
322
-
323
- #-----------------------------------------------------------------------#
324
-
325
- private
376
+ # @return [Object] the merged value
377
+ #
378
+ def merge_hash_value(attr, old, new)
379
+ case attr.name
380
+ when :info_plist
381
+ new
382
+ when ->(name) { spec.non_library_specification? && [:pod_target_xcconfig, :user_target_xcconfig, :xcconfig].include?(name) }
383
+ new
384
+ else
385
+ if new.is_a?(Array) || old.is_a?(Array)
386
+ r = Array(old) + Array(new)
387
+ r.compact
388
+ else
389
+ old + ' ' + new
390
+ end
391
+ end
392
+ end
326
393
 
327
394
  # @!group Preparing Values
328
- #
329
- # Raw values need to be prepared as soon as they are read so they can be
330
- # safely merged to support multi platform attributes and inheritance
395
+ #-----------------------------------------------------------------------#
331
396
 
332
397
  # @return [String] the name of the prepare hook for this attribute.
333
398
  #
@@ -347,7 +412,83 @@ module Pod
347
412
  # @return [String] the prefix header.
348
413
  #
349
414
  def _prepare_prefix_header_contents(value)
350
- value.is_a?(Array) ? value * "\n" : value
415
+ if value
416
+ value = value.join("\n") if value.is_a?(Array)
417
+ value.strip_heredoc.chomp
418
+ end
419
+ end
420
+
421
+ # Converts the test type value from a string to a symbol.
422
+ #
423
+ # @param [String, Symbol] value.
424
+ # The value of the test type attributed as specified by the user.
425
+ #
426
+ # @return [Symbol] the test type as a symbol.
427
+ #
428
+ def _prepare_test_type(value)
429
+ if value
430
+ value.to_sym
431
+ end
432
+ end
433
+
434
+ # Converts the array of hashes (script phases) where keys are strings into symbols.
435
+ #
436
+ # @param [Array<Hash{String=>String}>] value.
437
+ # The value of the attribute as specified by the user.
438
+ #
439
+ # @return [Array<Hash{Symbol=>String}>] the script phases array with symbols for each hash instead of strings.
440
+ #
441
+ def _prepare_script_phases(value)
442
+ if value
443
+ value.map do |script_phase|
444
+ if script_phase.is_a?(Hash)
445
+ phase = Specification.convert_keys_to_symbol(script_phase)
446
+ phase[:execution_position] = if phase.key?(:execution_position)
447
+ phase[:execution_position].to_sym
448
+ else
449
+ :any
450
+ end
451
+ phase
452
+ end
453
+ end.compact
454
+ end
455
+ end
456
+
457
+ # Converts the a scheme where keys are strings into symbols.
458
+ #
459
+ # @param [Hash] value.
460
+ # The value of the attribute as specified by the user.
461
+ #
462
+ # @return [Hash] the scheme with symbols as keys instead of strings or `nil` if the value is not a hash.
463
+ #
464
+ def _prepare_scheme(value)
465
+ Specification.convert_keys_to_symbol(value, :recursive => false) if value && value.is_a?(Hash)
466
+ end
467
+
468
+ # Ensures that the file patterns of the on demand resources are contained in
469
+ # an array.
470
+ #
471
+ # @param [String, Array, Hash] value.
472
+ # The value of the attribute as specified by the user.
473
+ #
474
+ # @return [Hash] the on demand resources.
475
+ #
476
+ def _prepare_on_demand_resources(value)
477
+ result = {}
478
+ if value
479
+ value.each do |key, patterns|
480
+ case patterns
481
+ when String, Array
482
+ result[key] = { :paths => [*patterns].compact, :category => :download_on_demand }
483
+ when Hash
484
+ patterns = Specification.convert_keys_to_symbol(patterns, :recursive => false)
485
+ result[key] = { :paths => [*patterns[:paths]].compact, :category => patterns.fetch(:category, :download_on_demand).to_sym }
486
+ else
487
+ raise StandardError, "Unknown on demand resource value type `#{patterns}`."
488
+ end
489
+ end
490
+ end
491
+ result
351
492
  end
352
493
 
353
494
  # Ensures that the file patterns of the resource bundles are contained in
@@ -369,7 +510,6 @@ module Pod
369
510
  end
370
511
 
371
512
  #-----------------------------------------------------------------------#
372
-
373
513
  end
374
514
  end
375
515
  end
@@ -1,14 +1,16 @@
1
1
  module Pod
2
2
  class Specification
3
3
  module DSL
4
-
5
4
  # A Specification attribute stores the information of an attribute. It
6
5
  # also provides logic to implement any required logic.
7
6
  #
8
7
  class Attribute
9
-
10
8
  require 'active_support/inflector/inflections'
11
9
 
10
+ # Spec types currently supported.
11
+ #
12
+ SUPPORTED_SPEC_TYPES = [:library, :app, :test].freeze
13
+
12
14
  # @return [Symbol] the name of the attribute.
13
15
  #
14
16
  attr_reader :name
@@ -31,22 +33,26 @@ module Pod
31
33
  def initialize(name, options)
32
34
  @name = name
33
35
 
34
- @multi_platform = options.delete(:multi_platform) { true }
35
- @inherited = options.delete(:inherited) { false }
36
- @root_only = options.delete(:root_only) { false }
37
- @required = options.delete(:required) { false }
38
- @singularize = options.delete(:singularize) { false }
39
- @file_patterns = options.delete(:file_patterns) { false }
40
- @container = options.delete(:container) { nil }
41
- @keys = options.delete(:keys) { nil }
42
- @default_value = options.delete(:default_value) { nil }
43
- @ios_default = options.delete(:ios_default) { nil }
44
- @osx_default = options.delete(:osx_default) { nil }
45
- @types = options.delete(:types) { [String] }
36
+ @multi_platform = options.delete(:multi_platform) { true }
37
+ @root_only = options.delete(:root_only) { false }
38
+ @spec_types = options.delete(:spec_types) { SUPPORTED_SPEC_TYPES }
39
+ @inherited = options.delete(:inherited) { @root_only }
40
+ @required = options.delete(:required) { false }
41
+ @singularize = options.delete(:singularize) { false }
42
+ @file_patterns = options.delete(:file_patterns) { false }
43
+ @container = options.delete(:container) { nil }
44
+ @keys = options.delete(:keys) { nil }
45
+ @default_value = options.delete(:default_value) { nil }
46
+ @ios_default = options.delete(:ios_default) { nil }
47
+ @osx_default = options.delete(:osx_default) { nil }
48
+ @types = options.delete(:types) { [String] }
46
49
 
47
50
  unless options.empty?
48
51
  raise StandardError, "Unrecognized options: #{options} for #{self}"
49
52
  end
53
+ unless (@spec_types - SUPPORTED_SPEC_TYPES).empty?
54
+ raise StandardError, "Unrecognized spec type option: #{@spec_types} for #{self}"
55
+ end
50
56
  end
51
57
 
52
58
  # @return [String] A string representation suitable for UI.
@@ -109,39 +115,56 @@ module Pod
109
115
  #
110
116
  attr_reader :osx_default
111
117
 
112
- # @return [Bool] whether the specification should be considered invalid
118
+ # @return [Boolean] whether the specification should be considered invalid
113
119
  # if a value for the attribute is not specified.
114
120
  #
115
- def required?; @required; end
121
+ def required?
122
+ @required
123
+ end
116
124
 
117
- # @return [Bool] whether the attribute should be specified only on the
125
+ # @return [Boolean] whether the attribute should be specified only on the
118
126
  # root specification.
119
127
  #
120
- def root_only?; @root_only; end
128
+ def root_only?
129
+ @root_only
130
+ end
131
+
132
+ # @return [Boolean] whether the attribute should be specified only on
133
+ # test specifications.
134
+ #
135
+ def test_only?
136
+ @spec_types == [:test]
137
+ end
121
138
 
122
- # @return [Bool] whether the attribute is multi-platform and should
139
+ # @return [Boolean] whether the attribute is multi-platform and should
123
140
  # work in conjunction with #{PlatformProxy}.
124
141
  #
125
- def multi_platform?; @multi_platform; end
142
+ def multi_platform?
143
+ @multi_platform
144
+ end
126
145
 
127
- # @return [Bool] whether there should be a singular alias for the
146
+ # @return [Boolean] whether there should be a singular alias for the
128
147
  # attribute writer.
129
148
  #
130
- def singularize?; @singularize; end
149
+ def singularize?
150
+ @singularize
151
+ end
131
152
 
132
- # @return [Bool] whether the attribute describes file patterns.
153
+ # @return [Boolean] whether the attribute describes file patterns.
133
154
  #
134
155
  # @note This is mostly used by the linter.
135
156
  #
136
- def file_patterns?; @file_patterns; end
157
+ def file_patterns?
158
+ @file_patterns
159
+ end
137
160
 
138
- # @return [Bool] defines whether the attribute reader should join the
161
+ # @return [Boolean] defines whether the attribute reader should join the
139
162
  # values with the parent.
140
163
  #
141
164
  # @note Attributes stored in wrappers are always inherited.
142
165
  #
143
166
  def inherited?
144
- !root_only? && @inherited
167
+ @inherited
145
168
  end
146
169
 
147
170
  #---------------------------------------------------------------------#
@@ -177,66 +200,7 @@ module Pod
177
200
  def writer_singular_form
178
201
  "#{name.to_s.singularize}=" if singularize?
179
202
  end
180
-
181
- #---------------------------------------------------------------------#
182
-
183
- # @!group Values validation
184
-
185
- # Validates the value for an attribute. This validation should be
186
- # performed before the value is prepared or wrapped.
187
- #
188
- # @note The this is called before preparing the value.
189
- #
190
- # @raise If the type is not in the allowed list.
191
- #
192
- # @return [void]
193
- #
194
- def validate_type(value)
195
- return if value.nil?
196
- unless supported_types.any? { |klass| value.class == klass }
197
- raise StandardError, "Non acceptable type `#{value.class}` for "\
198
- "#{self}. Allowed values: `#{types.inspect}`"
199
- end
200
- end
201
-
202
- # Validates a value before storing.
203
- #
204
- # @raise If a root only attribute is set in a subspec.
205
- #
206
- # @raise If a unknown key is added to a hash.
207
- #
208
- # @return [void]
209
- #
210
- def validate_for_writing(spec, value)
211
- if root_only? && !spec.root?
212
- raise StandardError, "Can't set `#{name}` attribute for " \
213
- "subspecs (in `#{spec.name}`)."
214
- end
215
-
216
- if keys
217
- value.keys.each do |key|
218
- unless allowed_keys.include?(key)
219
- raise StandardError, "Unknown key `#{key}` for "\
220
- "#{self}. Allowed keys: `#{allowed_keys.inspect}`"
221
- end
222
- end
223
- end
224
-
225
- # @return [Array] the flattened list of the allowed keys for the
226
- # hash of a given specification.
227
- #
228
- def allowed_keys
229
- if keys.is_a?(Hash)
230
- keys.keys.concat(keys.values.flatten.compact)
231
- else
232
- keys
233
- end
234
- end
235
- end
236
203
  end
237
-
238
- #-----------------------------------------------------------------------#
239
-
240
204
  end
241
205
  end
242
206
  end
@@ -1,25 +1,23 @@
1
1
  module Pod
2
2
  class Specification
3
3
  module DSL
4
-
5
4
  # @return [Array<Attribute>] The attributes of the class.
6
5
  #
7
- def self.attributes
8
- @attributes
6
+ class << self
7
+ attr_reader :attributes
9
8
  end
10
9
 
11
10
  # This module provides support for storing the runtime information of the
12
11
  # {Specification} DSL.
13
12
  #
14
13
  module AttributeSupport
15
-
16
14
  # Defines a root attribute for the extended class.
17
15
  #
18
16
  # Root attributes make sense only in root specification, they never are
19
- # multiplatform, they don't have inheritance, and they never have a
17
+ # multi-platform, they don't have inheritance, and they never have a
20
18
  # default value.
21
19
  #
22
- # @param [String] name
20
+ # @param [Symbol, String] name
23
21
  # The name of the attribute.
24
22
  #
25
23
  # @param [Hash] options
@@ -35,10 +33,10 @@ module Pod
35
33
 
36
34
  # Defines an attribute for the extended class.
37
35
  #
38
- # Regular attributes in general support inheritance and multi platform
36
+ # Regular attributes in general support inheritance and multi-platform
39
37
  # values, so resolving them for a given specification is not trivial.
40
38
  #
41
- # @param [String] name
39
+ # @param [Symbol, String] name
42
40
  # The name of the attribute.
43
41
  #
44
42
  # @param [Hash] options