Class: ZergXcode::XcodeObject

Inherits:
Object
  • Object
show all
Defined in:
lib/zerg_xcode/objects/xcode_object.rb

Overview

Superclass for all the objects in an Xcode project object graph.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash) ⇒ XcodeObject

Inheritance based on isa



28
29
30
31
32
33
34
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 28

def initialize(hash)
  @attrs = hash
  if self.class != ZergXcode::XcodeObject
    class_name = self.class.name
    @attrs['isa'] ||= class_name[(class_name.rindex(':') + 1)..-1]
  end
end

Instance Attribute Details

#archive_idObject

Returns the value of attribute archive_id.



14
15
16
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 14

def archive_id
  @archive_id
end

#versionObject

Returns the value of attribute version.



13
14
15
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 13

def version
  @version
end

Class Method Details

.from(object_or_hash) ⇒ Object

Deep copy



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 159

def self.from(object_or_hash)
  new_object = case object_or_hash
  when ZergXcode::XcodeObject
    object_or_hash.shallow_copy
  else
    self.new object_or_hash.dup
  end
  object_map = { object_or_hash => new_object }
  
  new_object.visit do |object, parent, key, value|
    case value
    when Hash, Array
      next value.dup
    when ZergXcode::XcodeObject
      if object_map[value]
        parent[key] = object_map[value]
        next false
      else
        object_map[value] = value.shallow_copy
        next object_map[value]
      end
    else
      next true
    end
  end
end

.new(*args) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 36

def self.new(*args)
  return super unless self == ZergXcode::XcodeObject
  if hash_isa = args.first['isa']
    hash_isa = hash_isa.to_sym
    classes = ZergXcode::Objects.constants.map(&:to_sym)
    if classes.include? hash_isa
      return ZergXcode::Objects.const_get(hash_isa).new(*args)
    end
  end
  super
end

Instance Method Details

#[](key) ⇒ Object

Hash-like behavior



18
19
20
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 18

def [](key)
  @attrs[key]
end

#[]=(key, value) ⇒ Object



22
23
24
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 22

def []=(key, value)
  @attrs[key] = value
end

#_attr_hashObject

The (internal) hash holding the file’s attributes.



56
57
58
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 56

def _attr_hash
  @attrs
end

#attrsObject

The names of the object’s attributes.



51
52
53
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 51

def attrs
  @attrs.keys
end

#copy_metadata(source) ⇒ Object



192
193
194
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 192

def (source)
  self.archive_id, self.version = source.archive_id, source.version 
end

#isaObject

Object type helpers



61
62
63
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 61

def isa
  return @attrs['isa'].to_sym
end

#shallow_copyObject



186
187
188
189
190
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 186

def shallow_copy
  new_object = self.class.new @attrs.dup
  new_object. self
  return new_object
end

#visit(&accept) ⇒ Object

Visits an object’s internal structure.

The given block is called like this:

yield object, parent, key, value

Where

object: the object currently visited (can be a sub-object)
parent: the collection currently visited (an object, hash, or array)
key: 
value:

The block can return

false: no recursive visiting for the given value
true: normal recursive visiting for the given value
something else: replace the given value with the return, the recursive
                visiting is done on the new value


81
82
83
84
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 81

def visit(&accept)
  visit_hash(@attrs, &accept)
  self
end

#visit_array(array, &accept) ⇒ Object



103
104
105
106
107
108
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 103

def visit_array(array, &accept)
  array.each_with_index do |value, index|
    visit_value(array, index, value, &accept)
  end
  array
end

#visit_hash(hash, &accept) ⇒ Object



96
97
98
99
100
101
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 96

def visit_hash(hash, &accept)
  hash.each_key do |key|
    visit_value(hash, key, hash[key], &accept)
  end
  hash
end

#visit_once(&accept) ⇒ Object

Convenience method mapping over visit and exploring each object once.



87
88
89
90
91
92
93
94
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 87

def visit_once(&accept)
  visited = Set.new([self])
  self.visit do |object, parent, key, value|
    visited << object
    next_value = yield object, parent, key, value
    visited.include?(value) ? false : next_value
  end
end

#visit_value(parent, key, value, &accept) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 110

def visit_value(parent, key, value, &accept)
  visit_parent = (parent == @attrs) ? self : parent
  recurse = yield self, visit_parent, key, value
  return if recurse == false
  
  if recurse != true
    value = recurse
    parent[key] = recurse
  end
  
  case value
  when ZergXcode::XcodeObject
    value.visit(&accept)
  when Hash
    visit_hash(value, &accept)
  when Array
    visit_array(value, &accept)
  end
  value    
end

#xref_keyObject

Key used for cross-referencing objects in different graphs. If two objects in different graphs have the same key, it is very likely that they represent the same entity.



136
137
138
139
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 136

def xref_key
  # If the object doesn't have a merge name, use its (unique) object_id.
  [isa, xref_name || object_id]
end

#xref_nameObject

Name used in referencing an object.

An object’s name should be unique among objects in the same context. For instance, objects in the same array (e.g. ‘children’ in a PBXGroup) should have distinct names.



146
147
148
149
150
151
152
153
154
155
# File 'lib/zerg_xcode/objects/xcode_object.rb', line 146

def xref_name
  # Do not use this to override xref_name for specific objects. Only use
  # it for object families.
  case isa.to_s
  when /BuildPhase$/
    isa.to_s
  else
    self['name'] || self['explicitPath'] || self['path'] 
  end
end