xcodeproj 0.18.0 → 0.19.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/xcodeproj +5 -5
- data/lib/xcodeproj.rb +0 -2
- data/lib/xcodeproj/command.rb +26 -17
- data/lib/xcodeproj/command/project_diff.rb +8 -11
- data/lib/xcodeproj/command/show.rb +8 -10
- data/lib/xcodeproj/command/sort.rb +4 -7
- data/lib/xcodeproj/command/target_diff.rb +4 -5
- data/lib/xcodeproj/config.rb +64 -57
- data/lib/xcodeproj/config/other_linker_flags_parser.rb +62 -0
- data/lib/xcodeproj/constants.rb +31 -30
- data/lib/xcodeproj/differ.rb +5 -9
- data/lib/xcodeproj/gem_version.rb +1 -2
- data/lib/xcodeproj/helper.rb +5 -4
- data/lib/xcodeproj/plist_helper.rb +46 -11
- data/lib/xcodeproj/project.rb +16 -20
- data/lib/xcodeproj/project/case_converter.rb +59 -0
- data/lib/xcodeproj/project/object.rb +40 -30
- data/lib/xcodeproj/project/object/build_configuration.rb +1 -5
- data/lib/xcodeproj/project/object/build_file.rb +1 -4
- data/lib/xcodeproj/project/object/build_phase.rb +2 -13
- data/lib/xcodeproj/project/object/build_rule.rb +0 -3
- data/lib/xcodeproj/project/object/configuration_list.rb +0 -4
- data/lib/xcodeproj/project/object/container_item_proxy.rb +2 -4
- data/lib/xcodeproj/project/object/file_reference.rb +3 -6
- data/lib/xcodeproj/project/object/group.rb +6 -14
- data/lib/xcodeproj/project/object/helpers/file_references_factory.rb +64 -13
- data/lib/xcodeproj/project/object/helpers/groupable_helper.rb +4 -6
- data/lib/xcodeproj/project/object/native_target.rb +18 -29
- data/lib/xcodeproj/project/object/reference_proxy.rb +0 -4
- data/lib/xcodeproj/project/object/root_object.rb +4 -8
- data/lib/xcodeproj/project/object/target_dependency.rb +1 -4
- data/lib/xcodeproj/project/object_attributes.rb +76 -33
- data/lib/xcodeproj/project/object_dictionary.rb +76 -63
- data/lib/xcodeproj/project/object_list.rb +5 -9
- data/lib/xcodeproj/project/project_helper.rb +2 -7
- data/lib/xcodeproj/project/xcproj_helper.rb +0 -2
- data/lib/xcodeproj/scheme.rb +12 -15
- data/lib/xcodeproj/user_interface.rb +0 -4
- data/lib/xcodeproj/workspace.rb +36 -23
- data/lib/xcodeproj/workspace/file_reference.rb +3 -3
- data/lib/xcodeproj/xcodebuild_helper.rb +0 -6
- metadata +20 -18
@@ -1,14 +1,12 @@
|
|
1
1
|
module Xcodeproj
|
2
2
|
class Project
|
3
3
|
module Object
|
4
|
-
|
5
4
|
# Apparently a proxy for a reference object which might belong another
|
6
5
|
# project contained in the same workspace of the project document.
|
7
6
|
#
|
8
7
|
# This class is used for referencing the products of another project.
|
9
8
|
#
|
10
9
|
class PBXReferenceProxy < AbstractObject
|
11
|
-
|
12
10
|
# @!group Attributes
|
13
11
|
|
14
12
|
# @return [String] the path of the referenced filed.
|
@@ -46,9 +44,7 @@ module Xcodeproj
|
|
46
44
|
end
|
47
45
|
|
48
46
|
#---------------------------------------------------------------------#
|
49
|
-
|
50
47
|
end
|
51
48
|
end
|
52
49
|
end
|
53
50
|
end
|
54
|
-
|
@@ -1,11 +1,9 @@
|
|
1
1
|
module Xcodeproj
|
2
2
|
class Project
|
3
3
|
module Object
|
4
|
-
|
5
4
|
# This class represents the root object of a project document.
|
6
5
|
#
|
7
6
|
class PBXProject < AbstractObject
|
8
|
-
|
9
7
|
# @!group Attributes
|
10
8
|
|
11
9
|
# @return [ObjectList<PBXNativeTarget>] a list of all the targets in
|
@@ -22,7 +20,7 @@ module Xcodeproj
|
|
22
20
|
# - `LastUpgradeCheck`
|
23
21
|
# - `ORGANIZATIONNAME`
|
24
22
|
#
|
25
|
-
attribute :attributes, Hash,
|
23
|
+
attribute :attributes, Hash, 'LastUpgradeCheck' => Constants::LAST_UPGRADE_CHECK
|
26
24
|
|
27
25
|
# @return [XCConfigurationList] the configuration list of the project.
|
28
26
|
#
|
@@ -64,11 +62,9 @@ module Xcodeproj
|
|
64
62
|
|
65
63
|
# @return [Array<ObjectDictionary>] any reference to other projects.
|
66
64
|
#
|
67
|
-
has_many_references_by_keys :project_references,
|
68
|
-
|
69
|
-
|
70
|
-
}
|
71
|
-
|
65
|
+
has_many_references_by_keys :project_references,
|
66
|
+
:project_ref => PBXFileReference,
|
67
|
+
:product_group => PBXGroup
|
72
68
|
end
|
73
69
|
end
|
74
70
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
module Xcodeproj
|
2
2
|
class Project
|
3
3
|
module Object
|
4
|
-
|
5
4
|
# Represents a dependency of a target on another one.
|
6
5
|
#
|
7
6
|
class PBXTargetDependency < AbstractObject
|
8
|
-
|
9
7
|
# @!group Attributes
|
10
8
|
|
11
9
|
# @return [PBXNativeTarget] the target that needs to be built to
|
@@ -28,7 +26,6 @@ module Xcodeproj
|
|
28
26
|
#
|
29
27
|
attribute :name, String
|
30
28
|
|
31
|
-
|
32
29
|
public
|
33
30
|
|
34
31
|
# @!group AbstractObject Hooks
|
@@ -47,7 +44,7 @@ module Xcodeproj
|
|
47
44
|
#
|
48
45
|
# @see AbstractObject#sort_recursively
|
49
46
|
#
|
50
|
-
def sort_recursively(
|
47
|
+
def sort_recursively(_options = nil)
|
51
48
|
end
|
52
49
|
end
|
53
50
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Xcodeproj
|
2
2
|
class Project
|
3
3
|
module Object
|
4
|
-
|
5
4
|
# This class represents an attribute of {AbstractObject} subclasses.
|
6
5
|
# Attributes are created by the {AbstractObject} DSL methods and allow to
|
7
6
|
# mirror the underlying attributes of the xcodeproj document model.
|
@@ -13,7 +12,6 @@ module Xcodeproj
|
|
13
12
|
# validated before serialization ?
|
14
13
|
#
|
15
14
|
class AbstractObjectAttribute
|
16
|
-
|
17
15
|
require 'active_support/inflector'
|
18
16
|
|
19
17
|
# @return [Symbol] the type of the attribute. It can be `:simple`,
|
@@ -49,27 +47,14 @@ module Xcodeproj
|
|
49
47
|
@owner = owner
|
50
48
|
end
|
51
49
|
|
52
|
-
# @return[String] The name of the attribute in camel case.
|
50
|
+
# @return [String] The name of the attribute in camel case.
|
53
51
|
#
|
54
52
|
# @example
|
55
53
|
# attribute.new(:simple, :project_root)
|
56
54
|
# attribute.plist_name #=> projectRoot
|
57
55
|
#
|
58
56
|
def plist_name
|
59
|
-
|
60
|
-
when :remote_global_id_string
|
61
|
-
# `_id_` would become `Id`
|
62
|
-
'remoteGlobalIDString'
|
63
|
-
else
|
64
|
-
self.class.plist_name_store[name] ||= name.to_s.camelize(:lower)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# @return [Hash] a shared store which caches the plist name of the
|
69
|
-
# attributes.
|
70
|
-
#
|
71
|
-
def self.plist_name_store
|
72
|
-
@plist_name_store ||= {}
|
57
|
+
CaseConverter.convert_to_plist(name, :lower)
|
73
58
|
end
|
74
59
|
|
75
60
|
# @return [Array<Class>] the list of the classes accepted by the
|
@@ -77,6 +62,11 @@ module Xcodeproj
|
|
77
62
|
#
|
78
63
|
attr_accessor :classes
|
79
64
|
|
65
|
+
# @return [{Symbol, Array<Class>}] the list of the classes accepted by
|
66
|
+
# each key for attributes which store a dictionary.
|
67
|
+
#
|
68
|
+
attr_accessor :classes_by_key
|
69
|
+
|
80
70
|
# @return [String, Array, Hash] the default value, if any, for simple
|
81
71
|
# attributes.
|
82
72
|
#
|
@@ -110,7 +100,9 @@ module Xcodeproj
|
|
110
100
|
# @return [void]
|
111
101
|
#
|
112
102
|
def set_value(object, new_value)
|
113
|
-
|
103
|
+
if type == :to_many
|
104
|
+
raise '[Xcodeproj] Set value called for a to-many attribute'
|
105
|
+
end
|
114
106
|
object.send("#{name}=", new_value)
|
115
107
|
end
|
116
108
|
|
@@ -127,7 +119,9 @@ module Xcodeproj
|
|
127
119
|
# @return [void]
|
128
120
|
#
|
129
121
|
def set_default(object)
|
130
|
-
|
122
|
+
unless type == :simple
|
123
|
+
raise "[Xcodeproj] Set value called for a #{type} attribute"
|
124
|
+
end
|
131
125
|
set_value(object, default_value.dup) if default_value
|
132
126
|
end
|
133
127
|
|
@@ -144,23 +138,57 @@ module Xcodeproj
|
|
144
138
|
return unless object
|
145
139
|
acceptable = classes.find { |klass| object.class == klass || object.class < klass }
|
146
140
|
if type == :simple
|
147
|
-
raise "[Xcodeproj] Type checking error: got `#{object.class}`
|
141
|
+
raise "[Xcodeproj] Type checking error: got `#{object.class}` " \
|
142
|
+
"for attribute: #{inspect}" unless acceptable
|
148
143
|
else
|
149
|
-
raise "[Xcodeproj] Type checking error: got `#{object.isa}` for
|
144
|
+
raise "[Xcodeproj] Type checking error: got `#{object.isa}` for " \
|
145
|
+
"attribute: #{inspect}" unless acceptable
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Checks that a given value is compatible with a key for attributes
|
150
|
+
# which store references by key.
|
151
|
+
#
|
152
|
+
# This method is used by the #{ObjectDictionary} class.
|
153
|
+
#
|
154
|
+
# @raise If the class of the value is not compatible with the given
|
155
|
+
# key.
|
156
|
+
#
|
157
|
+
def validate_value_for_key(object, key)
|
158
|
+
unless type == :references_by_keys
|
159
|
+
raise '[Xcodeproj] This method should be called only for ' \
|
160
|
+
'attributes of type `references_by_keys`'
|
161
|
+
end
|
162
|
+
|
163
|
+
unless classes_by_key.keys.include?(key)
|
164
|
+
raise "[Xcodeproj] unsupported key `#{key}` " \
|
165
|
+
"(accepted `#{classes_by_key.keys}`) for attribute `#{inspect}`"
|
166
|
+
end
|
167
|
+
|
168
|
+
return unless object
|
169
|
+
classes = Array(classes_by_key[key])
|
170
|
+
acceptable = classes.find { |klass| object.class == klass || object.class < klass }
|
171
|
+
unless acceptable
|
172
|
+
raise "[Xcodeproj] Type checking error: got `#{object.isa}` " \
|
173
|
+
"for key `#{key}` (which accepts `#{classes}`) of " \
|
174
|
+
"attribute: `#{inspect}`"
|
150
175
|
end
|
151
176
|
end
|
152
177
|
|
178
|
+
# @return [String] A string suitable for debugging the object.
|
179
|
+
#
|
153
180
|
def inspect
|
154
181
|
if type == :simple
|
155
|
-
"Attribute `#{plist_name}` (type: `#{type}`, classes:
|
182
|
+
"Attribute `#{plist_name}` (type: `#{type}`, classes: " \
|
183
|
+
"`#{classes}`, owner class: `#{owner.isa}`)"
|
156
184
|
else
|
157
|
-
"Attribute `#{plist_name}` (type: `#{type}`, classes:
|
185
|
+
"Attribute `#{plist_name}` (type: `#{type}`, classes: " \
|
186
|
+
"`#{classes.map(&:isa)}`, owner class: `#{owner.isa}`)"
|
158
187
|
end
|
159
188
|
end
|
160
189
|
end
|
161
190
|
|
162
191
|
class AbstractObject
|
163
|
-
|
164
192
|
# The {AbstractObject} DSL methods allow to specify with fidelity the
|
165
193
|
# underlying model of the xcodeproj document format. {AbstractObject}
|
166
194
|
# subclasses should specify their attributes through the following
|
@@ -177,7 +205,6 @@ module Xcodeproj
|
|
177
205
|
# @note Attributes are typed and are validated at runtime.
|
178
206
|
#
|
179
207
|
class << self
|
180
|
-
|
181
208
|
# @return [Array<AbstractObjectAttribute>] the attributes associated
|
182
209
|
# with the class.
|
183
210
|
#
|
@@ -191,9 +218,14 @@ module Xcodeproj
|
|
191
218
|
def attributes
|
192
219
|
unless @full_attributes
|
193
220
|
attributes = @attributes || []
|
194
|
-
|
221
|
+
if superclass.respond_to?(:attributes)
|
222
|
+
super_attributes = superclass.attributes
|
223
|
+
else
|
224
|
+
super_attributes = []
|
225
|
+
end
|
195
226
|
# The uniqueness of the attributes is very important because the
|
196
|
-
# initialization from plist deletes the values from the
|
227
|
+
# initialization from plist deletes the values from the
|
228
|
+
# dictionary.
|
197
229
|
@full_attributes = attributes.concat(super_attributes).uniq
|
198
230
|
end
|
199
231
|
@full_attributes
|
@@ -288,6 +320,8 @@ module Xcodeproj
|
|
288
320
|
end
|
289
321
|
end
|
290
322
|
|
323
|
+
# rubocop:disable Style/PredicateName
|
324
|
+
|
291
325
|
# Defines a new relationship to a single and synthesises the
|
292
326
|
# corresponding methods.
|
293
327
|
#
|
@@ -373,16 +407,17 @@ module Xcodeproj
|
|
373
407
|
# @param [String] plural_name
|
374
408
|
# the name of the relationship.
|
375
409
|
#
|
376
|
-
# @param [
|
410
|
+
# @param [{Symbol, Array<Class>}] classes_by_key
|
377
411
|
# the list of the classes corresponding to the accepted isas for
|
378
412
|
# this relationship.
|
379
413
|
#
|
380
414
|
# @macro [attach] has_many
|
381
415
|
# @!attribute [r] $1
|
382
416
|
#
|
383
|
-
def has_many_references_by_keys(plural_name,
|
417
|
+
def has_many_references_by_keys(plural_name, classes_by_key)
|
384
418
|
attrb = AbstractObjectAttribute.new(:references_by_keys, plural_name, self)
|
385
|
-
attrb.classes =
|
419
|
+
attrb.classes = classes_by_key.values
|
420
|
+
attrb.classes_by_key = classes_by_key
|
386
421
|
add_attribute(attrb)
|
387
422
|
|
388
423
|
define_method(attrb.name) do
|
@@ -396,6 +431,8 @@ module Xcodeproj
|
|
396
431
|
end
|
397
432
|
end
|
398
433
|
|
434
|
+
# rubocop:enable Style/PredicateName
|
435
|
+
|
399
436
|
protected
|
400
437
|
|
401
438
|
# Adds an attribute to the list of attributes of the class.
|
@@ -406,8 +443,14 @@ module Xcodeproj
|
|
406
443
|
# @return [void]
|
407
444
|
#
|
408
445
|
def add_attribute(attribute)
|
409
|
-
|
410
|
-
|
446
|
+
unless attribute.classes
|
447
|
+
raise "[Xcodeproj] BUG - missing classes for #{attribute.inspect}"
|
448
|
+
end
|
449
|
+
|
450
|
+
unless attribute.classes.all? { |klass| klass.is_a?(Class) }
|
451
|
+
raise "[Xcodeproj] BUG - classes:#{attribute.classes} for #{attribute.inspect}"
|
452
|
+
end
|
453
|
+
|
411
454
|
@attributes ||= []
|
412
455
|
@attributes << attribute
|
413
456
|
end
|
@@ -462,7 +505,7 @@ module Xcodeproj
|
|
462
505
|
def references_by_keys_attributes
|
463
506
|
self.class.references_by_keys_attributes
|
464
507
|
end
|
465
|
-
end
|
508
|
+
end
|
466
509
|
end
|
467
510
|
end
|
468
511
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Xcodeproj
|
2
2
|
class Project
|
3
|
-
|
4
3
|
# This class represents relationships to other objects stored in a
|
5
4
|
# Dictionary.
|
6
5
|
#
|
@@ -8,10 +7,7 @@ module Xcodeproj
|
|
8
7
|
# the project is not serialized with unreachable objects by updating the
|
9
8
|
# with reference count on modifications.
|
10
9
|
#
|
11
|
-
# @note
|
12
|
-
# {PBXProject#project_references}. It doesn't perform type cheeking
|
13
|
-
# and the keys of the dictionary are in camel-case. To provide full
|
14
|
-
# support as the other classes the dictionary should be able to
|
10
|
+
# @note To provide full support as the other classes the dictionary should:
|
15
11
|
#
|
16
12
|
# Give the following attribute:
|
17
13
|
#
|
@@ -28,7 +24,7 @@ module Xcodeproj
|
|
28
24
|
# #=> This should raise:
|
29
25
|
# root_object.project_references.product_group = file
|
30
26
|
#
|
31
|
-
# generate setters and getters from the specification hash.
|
27
|
+
# I.e. generate setters and getters from the specification hash.
|
32
28
|
#
|
33
29
|
# Also the interface is a dirty hybrid between the
|
34
30
|
# {AbstractObjectAttribute} and the {ObjectList}.
|
@@ -37,110 +33,119 @@ module Xcodeproj
|
|
37
33
|
# which are overridden to inform objects reference count. Ideally all
|
38
34
|
# the hash methods should be covered, but this is not done yet.
|
39
35
|
# Moreover it is a moving target because the methods of array
|
40
|
-
# usually are implemented in C
|
36
|
+
# usually are implemented in C.
|
41
37
|
#
|
42
|
-
# @todo
|
38
|
+
# @todo This class should use a {Hash} as a backing store instead of
|
39
|
+
# inheriting from it. This would prevent the usage of methods which
|
40
|
+
# don't notify the objects.
|
43
41
|
#
|
44
42
|
class ObjectDictionary < Hash
|
45
|
-
|
46
|
-
#
|
47
|
-
# {ObjectDictionary}, it is always initialized empty and automatically by
|
48
|
-
# the synthesized methods generated by {AbstractObject.has_many}.
|
43
|
+
# @param [Object::AbstractObjectAttribute] attribute @see #attribute
|
44
|
+
# @param [Object] owner @see #owner
|
49
45
|
#
|
50
46
|
def initialize(attribute, owner)
|
51
47
|
@attribute = attribute
|
52
48
|
@owner = owner
|
53
49
|
end
|
54
50
|
|
55
|
-
# @return [
|
51
|
+
# @return [Object::AbstractObjectAttribute] The attribute that generated
|
52
|
+
# the list.
|
56
53
|
#
|
57
54
|
attr_reader :attribute
|
58
55
|
|
59
|
-
# @return [
|
56
|
+
# @return [Object] The object that owns the list.
|
60
57
|
#
|
61
58
|
attr_reader :owner
|
62
59
|
|
63
|
-
|
60
|
+
# @return [Array<Symbol>] The list of the allowed keys.
|
61
|
+
#
|
62
|
+
def allowed_keys
|
63
|
+
attribute.classes_by_key.keys
|
64
|
+
end
|
64
65
|
|
65
|
-
#
|
66
|
+
# @return [String] A string suitable for debugging.
|
67
|
+
#
|
68
|
+
def inspect
|
69
|
+
"<ObjectDictionary attribute:`#{@attribute.name}` " \
|
70
|
+
"owner:`#{@owner.display_name}` values:#{super.inspect}>"
|
71
|
+
end
|
66
72
|
|
67
|
-
#
|
73
|
+
# @!group Notification enabled methods
|
74
|
+
#------------------------------------------------------------------------#
|
68
75
|
|
69
76
|
# Associates an object to the given key and updates its references count.
|
70
77
|
#
|
71
|
-
# @param
|
72
|
-
#
|
78
|
+
# @param [String] key
|
79
|
+
# The key.
|
73
80
|
#
|
74
|
-
# @param
|
75
|
-
#
|
81
|
+
# @param [AbstractObject] object
|
82
|
+
# The object to add to the dictionary.
|
76
83
|
#
|
77
|
-
# @return [
|
84
|
+
# @return [AbstractObject] The given object.
|
78
85
|
#
|
79
86
|
def []=(key, object)
|
87
|
+
key = normalize_key(key)
|
80
88
|
if object
|
81
|
-
perform_additions_operations(object)
|
89
|
+
perform_additions_operations(object, key)
|
82
90
|
else
|
83
91
|
perform_deletion_operations(self[key])
|
84
92
|
end
|
85
|
-
super
|
93
|
+
super(key, object)
|
86
94
|
end
|
87
95
|
|
88
96
|
# Removes the given key from the dictionary and informs the object that
|
89
97
|
# is not longer referenced by the owner.
|
90
98
|
#
|
91
|
-
# @param
|
92
|
-
#
|
93
|
-
#
|
94
|
-
# @return [void]
|
99
|
+
# @param [String] key
|
100
|
+
# The key.
|
95
101
|
#
|
96
102
|
def delete(key)
|
103
|
+
key = normalize_key(key)
|
97
104
|
object = self[key]
|
98
105
|
perform_deletion_operations(object)
|
99
106
|
super
|
100
107
|
end
|
101
108
|
|
102
|
-
|
103
|
-
|
104
|
-
# @!group AbstractObject
|
109
|
+
# @!group AbstractObject Methods
|
110
|
+
#-----------------------------------------------------------------------#
|
105
111
|
|
106
|
-
# The plist representation of the
|
107
|
-
# replaced by their UUIDs.
|
108
|
-
#
|
109
|
-
# @return [Hash<String => String>]
|
112
|
+
# @return [Hash<String => String>] The plist representation of the
|
113
|
+
# dictionary where the objects are replaced by their UUIDs.
|
110
114
|
#
|
111
115
|
def to_hash
|
112
116
|
result = {}
|
113
|
-
each
|
117
|
+
each do |key, obj|
|
118
|
+
if obj
|
119
|
+
plist_key = Object::CaseConverter.convert_to_plist(key, nil)
|
120
|
+
result[plist_key] = obj.uuid
|
121
|
+
end
|
122
|
+
end
|
114
123
|
result
|
115
124
|
end
|
116
125
|
|
117
|
-
# Returns a cascade representation of
|
118
|
-
#
|
119
|
-
# @return [Hash<String => String>]
|
126
|
+
# @return [Hash<String => String>] Returns a cascade representation of
|
127
|
+
# the object without UUIDs.
|
120
128
|
#
|
121
129
|
def to_tree_hash
|
122
130
|
result = {}
|
123
|
-
each
|
131
|
+
each do |key, obj|
|
132
|
+
if obj
|
133
|
+
plist_key = Object::CaseConverter.convert_to_plist(key, nil)
|
134
|
+
result[plist_key] = obj.to_tree_hash
|
135
|
+
end
|
136
|
+
end
|
124
137
|
result
|
125
138
|
end
|
126
139
|
|
127
140
|
# Removes all the references to a given object.
|
128
141
|
#
|
129
|
-
# @return [void]
|
130
|
-
#
|
131
142
|
def remove_reference(object)
|
132
143
|
each { |key, obj| self[key] = nil if obj == object }
|
133
144
|
end
|
134
145
|
|
135
|
-
#------------------------------------------------------------------------#
|
136
|
-
|
137
|
-
# @!group ObjectList
|
138
|
-
|
139
146
|
# Informs the objects contained in the dictionary that another object is
|
140
147
|
# referencing them.
|
141
148
|
#
|
142
|
-
# @return [void]
|
143
|
-
#
|
144
149
|
def add_referrer(referrer)
|
145
150
|
values.each { |obj| obj.add_referrer(referrer) }
|
146
151
|
end
|
@@ -148,17 +153,32 @@ module Xcodeproj
|
|
148
153
|
# Informs the objects contained in the dictionary that another object
|
149
154
|
# stopped referencing them.
|
150
155
|
#
|
151
|
-
# @return [void]
|
152
|
-
#
|
153
156
|
def remove_referrer(referrer)
|
154
157
|
values.each { |obj| obj.remove_referrer(referrer) }
|
155
158
|
end
|
156
159
|
|
160
|
+
private
|
161
|
+
|
162
|
+
# @!group Private helpers
|
157
163
|
#------------------------------------------------------------------------#
|
158
164
|
|
159
|
-
#
|
165
|
+
# @return [Symbol] Normalizes a key to a symbol converting the camel case
|
166
|
+
# format with underscores.
|
167
|
+
#
|
168
|
+
# @param [String, Symbol] key
|
169
|
+
# The key to normalize.
|
170
|
+
#
|
171
|
+
def normalize_key(key)
|
172
|
+
if key.is_a?(String)
|
173
|
+
key = Object::CaseConverter.convert_to_ruby(key)
|
174
|
+
end
|
160
175
|
|
161
|
-
|
176
|
+
unless allowed_keys.include?(key)
|
177
|
+
raise "[Xcodeproj] Unsupported key `#{key}` (allowed " \
|
178
|
+
"`#{allowed_keys}`) for `#{inspect}`"
|
179
|
+
end
|
180
|
+
key
|
181
|
+
end
|
162
182
|
|
163
183
|
# Informs an object that it was added to the dictionary. In practice it
|
164
184
|
# adds the owner of the list as referrer to the objects. It also
|
@@ -166,12 +186,9 @@ module Xcodeproj
|
|
166
186
|
#
|
167
187
|
# @return [void]
|
168
188
|
#
|
169
|
-
def perform_additions_operations(
|
170
|
-
|
171
|
-
|
172
|
-
obj.add_referrer(owner)
|
173
|
-
attribute.validate_value(obj)
|
174
|
-
end
|
189
|
+
def perform_additions_operations(object, key)
|
190
|
+
object.add_referrer(owner)
|
191
|
+
attribute.validate_value_for_key(object, key)
|
175
192
|
end
|
176
193
|
|
177
194
|
# Informs an object that it was removed from to the dictionary, so it can
|
@@ -180,12 +197,8 @@ module Xcodeproj
|
|
180
197
|
# @return [void]
|
181
198
|
#
|
182
199
|
def perform_deletion_operations(objects)
|
183
|
-
objects
|
184
|
-
objects.each do |obj|
|
185
|
-
obj.remove_referrer(owner)
|
186
|
-
end
|
200
|
+
objects.remove_referrer(owner)
|
187
201
|
end
|
188
202
|
end
|
189
203
|
end
|
190
204
|
end
|
191
|
-
|