xcodeproj 0.1.0 → 0.2.0.rc1
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.
- data/ext/xcodeproj/extconf.h +8 -0
- data/ext/xcodeproj/extconf.rb +1 -0
- data/ext/xcodeproj/xcodeproj_ext.c +69 -11
- data/lib/xcodeproj.rb +1 -1
- data/lib/xcodeproj/config.rb +142 -10
- data/lib/xcodeproj/inflector.rb +1 -1
- data/lib/xcodeproj/project.rb +154 -566
- data/lib/xcodeproj/project/association.rb +54 -0
- data/lib/xcodeproj/project/association/has_many.rb +51 -0
- data/lib/xcodeproj/project/association/has_one.rb +39 -0
- data/lib/xcodeproj/project/association/reflection.rb +88 -0
- data/lib/xcodeproj/project/object.rb +207 -0
- data/lib/xcodeproj/project/object/build_phase.rb +89 -0
- data/lib/xcodeproj/project/object/configuration.rb +100 -0
- data/lib/xcodeproj/project/object/file_reference.rb +71 -0
- data/lib/xcodeproj/project/object/group.rb +102 -0
- data/lib/xcodeproj/project/object/native_target.rb +126 -0
- data/lib/xcodeproj/project/object_list.rb +146 -0
- metadata +19 -6
@@ -0,0 +1,100 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Project
|
3
|
+
module Object
|
4
|
+
|
5
|
+
class XCBuildConfiguration < AbstractPBXObject
|
6
|
+
COMMON_BUILD_SETTINGS = {
|
7
|
+
:all => {
|
8
|
+
'GCC_VERSION' => 'com.apple.compilers.llvm.clang.1_0',
|
9
|
+
'GCC_PRECOMPILE_PREFIX_HEADER' => 'YES',
|
10
|
+
'PRODUCT_NAME' => '$(TARGET_NAME)',
|
11
|
+
'SKIP_INSTALL' => 'YES',
|
12
|
+
'DSTROOT' => '/tmp/xcodeproj.dst',
|
13
|
+
'ALWAYS_SEARCH_USER_PATHS' => 'NO',
|
14
|
+
'GCC_C_LANGUAGE_STANDARD' => 'gnu99',
|
15
|
+
'INSTALL_PATH' => "$(BUILT_PRODUCTS_DIR)",
|
16
|
+
'GCC_WARN_ABOUT_MISSING_PROTOTYPES' => 'YES',
|
17
|
+
'GCC_WARN_ABOUT_RETURN_TYPE' => 'YES',
|
18
|
+
'GCC_WARN_UNUSED_VARIABLE' => 'YES',
|
19
|
+
'OTHER_LDFLAGS' => '',
|
20
|
+
'COPY_PHASE_STRIP' => 'YES',
|
21
|
+
}.freeze,
|
22
|
+
:debug => {
|
23
|
+
'GCC_DYNAMIC_NO_PIC' => 'NO',
|
24
|
+
'GCC_PREPROCESSOR_DEFINITIONS' => ["DEBUG=1", "$(inherited)"],
|
25
|
+
'GCC_SYMBOLS_PRIVATE_EXTERN' => 'NO',
|
26
|
+
'GCC_OPTIMIZATION_LEVEL' => '0',
|
27
|
+
'COPY_PHASE_STRIP' => 'NO',
|
28
|
+
}.freeze,
|
29
|
+
:ios => {
|
30
|
+
'ARCHS' => "$(ARCHS_STANDARD_32_BIT)",
|
31
|
+
'IPHONEOS_DEPLOYMENT_TARGET' => '4.3',
|
32
|
+
'PUBLIC_HEADERS_FOLDER_PATH' => "$(TARGET_NAME)",
|
33
|
+
'SDKROOT' => 'iphoneos',
|
34
|
+
}.freeze,
|
35
|
+
:osx => {
|
36
|
+
'ARCHS' => "$(ARCHS_STANDARD_64_BIT)",
|
37
|
+
'GCC_ENABLE_OBJC_EXCEPTIONS' => 'YES',
|
38
|
+
'GCC_WARN_64_TO_32_BIT_CONVERSION' => 'YES',
|
39
|
+
'GCC_VERSION' => 'com.apple.compilers.llvm.clang.1_0',
|
40
|
+
'MACOSX_DEPLOYMENT_TARGET' => '10.7',
|
41
|
+
'SDKROOT' => 'macosx',
|
42
|
+
}.freeze,
|
43
|
+
[:osx, :debug] => {
|
44
|
+
'ONLY_ACTIVE_ARCH' => 'YES',
|
45
|
+
}.freeze,
|
46
|
+
[:osx, :release] => {
|
47
|
+
'DEBUG_INFORMATION_FORMAT' => 'dwarf-with-dsym',
|
48
|
+
}.freeze,
|
49
|
+
[:ios, :release] => {
|
50
|
+
'VALIDATE_PRODUCT' => 'YES',
|
51
|
+
}.freeze,
|
52
|
+
}.freeze
|
53
|
+
|
54
|
+
def self.new_release(project)
|
55
|
+
new(project, nil,
|
56
|
+
'name' => 'Release',
|
57
|
+
'buildSettings' => COMMON_BUILD_SETTINGS[:all].dup
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.new_debug(project)
|
62
|
+
new(project, nil,
|
63
|
+
'name' => 'Debug',
|
64
|
+
'buildSettings' => COMMON_BUILD_SETTINGS[:all].merge(COMMON_BUILD_SETTINGS[:debug])
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
# [Hash] the build settings used when building a target
|
69
|
+
attribute :build_settings
|
70
|
+
|
71
|
+
# TODO why do I need to specify the uuid here?
|
72
|
+
has_one :base_configuration, :uuid => :base_configuration_reference
|
73
|
+
|
74
|
+
def initialize(*)
|
75
|
+
super
|
76
|
+
self.build_settings ||= {}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class XCConfigurationList < AbstractPBXObject
|
81
|
+
attribute :default_configuration_is_visible
|
82
|
+
attribute :default_configuration_name
|
83
|
+
|
84
|
+
has_many :build_configurations
|
85
|
+
|
86
|
+
def initialize(*)
|
87
|
+
super
|
88
|
+
self.build_configuration_references ||= []
|
89
|
+
end
|
90
|
+
|
91
|
+
def build_settings(build_configuration_name)
|
92
|
+
if config = build_configurations.where(:name => build_configuration_name)
|
93
|
+
config.build_settings
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'xcodeproj/project/object/group'
|
2
|
+
|
3
|
+
module Xcodeproj
|
4
|
+
class Project
|
5
|
+
module Object
|
6
|
+
|
7
|
+
# @todo Add a list of all possible file types for `explicit_file_type`
|
8
|
+
# and `last_known_file_type`.
|
9
|
+
class PBXFileReference < AbstractGroupEntry
|
10
|
+
# [String] the path to the file relative to the source tree
|
11
|
+
attribute :path
|
12
|
+
|
13
|
+
# [String] the source tree to which the file is relative. It can be one
|
14
|
+
# of `SOURCE_ROOT` or `SDKROOT`
|
15
|
+
attribute :source_tree
|
16
|
+
|
17
|
+
# [String] the file type regardless of what Xcode might think it is
|
18
|
+
attribute :explicit_file_type
|
19
|
+
|
20
|
+
# [String] the file type guessed by Xcode
|
21
|
+
attribute :last_known_file_type
|
22
|
+
|
23
|
+
# [String] wether of not this file should be indexed. This can be
|
24
|
+
# either "0" or "1".
|
25
|
+
attribute :include_in_index
|
26
|
+
|
27
|
+
has_many :build_files, :inverse_of => :file
|
28
|
+
|
29
|
+
def self.new_static_library(project, product_name)
|
30
|
+
new(project, nil,
|
31
|
+
"includeInIndex" => "0",
|
32
|
+
"sourceTree" => "BUILT_PRODUCTS_DIR",
|
33
|
+
"path" => "lib#{product_name}.a"
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(*)
|
38
|
+
super
|
39
|
+
self.path = path if path # sets default name
|
40
|
+
self.source_tree ||= 'SOURCE_ROOT'
|
41
|
+
self.include_in_index ||= "1"
|
42
|
+
set_default_file_type!
|
43
|
+
end
|
44
|
+
|
45
|
+
alias_method :_path=, :path=
|
46
|
+
def path=(path)
|
47
|
+
self._path = path
|
48
|
+
self.name ||= pathname.basename.to_s
|
49
|
+
path
|
50
|
+
end
|
51
|
+
|
52
|
+
def pathname
|
53
|
+
Pathname.new(path)
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_default_file_type!
|
57
|
+
return if explicit_file_type || last_known_file_type
|
58
|
+
case path
|
59
|
+
when /\.a$/
|
60
|
+
self.explicit_file_type = 'archive.ar'
|
61
|
+
when /\.framework$/
|
62
|
+
self.last_known_file_type = 'wrapper.framework'
|
63
|
+
when /\.xcconfig$/
|
64
|
+
self.last_known_file_type = 'text.xcconfig'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Project
|
3
|
+
module Object
|
4
|
+
|
5
|
+
class AbstractGroupEntry < AbstractPBXObject
|
6
|
+
has_one :group, :inverse_of => :children
|
7
|
+
|
8
|
+
def initialize(project, uuid, attributes)
|
9
|
+
is_new = uuid.nil?
|
10
|
+
super
|
11
|
+
# If there's no root_object yet, then this is probably the main group.
|
12
|
+
if is_new && @project.root_object
|
13
|
+
@project.main_group.children << self
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def destroy
|
18
|
+
group.child_references.delete(uuid)
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
# Sorts groups before files and inside those sorts by name.
|
23
|
+
def <=>(other)
|
24
|
+
if self.is_a?(PBXGroup) && other.is_a?(PBXFileReference)
|
25
|
+
-1
|
26
|
+
elsif self.is_a?(PBXFileReference) && other.is_a?(PBXGroup)
|
27
|
+
1
|
28
|
+
else
|
29
|
+
self.name <=> other.name
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @todo The `source_tree` can probably be more than just `<group>`.
|
35
|
+
class PBXGroup < AbstractGroupEntry
|
36
|
+
# [String] the source tree to which this group is relative. It can be
|
37
|
+
# `<group>`.
|
38
|
+
attribute :source_tree
|
39
|
+
|
40
|
+
has_many :children, :class => AbstractGroupEntry do |child|
|
41
|
+
# Associating the AbstractGroupEntry instance to this group through
|
42
|
+
# the inverse association will also remove it from the group it was
|
43
|
+
# in.
|
44
|
+
child.group = self
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(*)
|
48
|
+
super
|
49
|
+
self.source_tree ||= '<group>'
|
50
|
+
self.child_references ||= []
|
51
|
+
end
|
52
|
+
|
53
|
+
def main_group?
|
54
|
+
@project.main_group.uuid == uuid
|
55
|
+
end
|
56
|
+
|
57
|
+
def name
|
58
|
+
if name = super
|
59
|
+
name
|
60
|
+
elsif attributes.has_key?('path')
|
61
|
+
File.basename(attributes['path'])
|
62
|
+
elsif main_group?
|
63
|
+
'Main Group'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def files
|
68
|
+
children.list_by_class(PBXFileReference)
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_file(path)
|
72
|
+
files.new("path" => path)
|
73
|
+
end
|
74
|
+
|
75
|
+
def create_files(paths)
|
76
|
+
paths.map { |path| create_file(path) }
|
77
|
+
end
|
78
|
+
|
79
|
+
def source_files
|
80
|
+
children.list_by_class(PBXFileReference) do |list|
|
81
|
+
list.let(:uuid_scope) do
|
82
|
+
files.reject { |file| file.build_files.empty? }.map(&:uuid)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def groups
|
88
|
+
children.list_by_class(PBXGroup)
|
89
|
+
end
|
90
|
+
|
91
|
+
def create_group(name)
|
92
|
+
groups.new("name" => name)
|
93
|
+
end
|
94
|
+
|
95
|
+
def <<(child)
|
96
|
+
children << child
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Project
|
3
|
+
module Object
|
4
|
+
|
5
|
+
class PBXNativeTarget < AbstractPBXObject
|
6
|
+
STATIC_LIBRARY = 'com.apple.product-type.library.static'
|
7
|
+
|
8
|
+
# [String] the name of the build product
|
9
|
+
attribute :product_name
|
10
|
+
|
11
|
+
# [String] the build product type identifier
|
12
|
+
attribute :product_type
|
13
|
+
|
14
|
+
has_many :build_phases
|
15
|
+
has_many :dependencies # TODO :class => ?
|
16
|
+
has_many :build_rules # TODO :class => ?
|
17
|
+
has_one :build_configuration_list, :class => XCConfigurationList
|
18
|
+
has_one :product, :uuid => :product_reference
|
19
|
+
|
20
|
+
def self.new_static_library(project, platform, name)
|
21
|
+
project.add_system_framework(platform == :ios ? 'Foundation' : 'Cocoa')
|
22
|
+
|
23
|
+
target = new(project, nil, 'productType' => STATIC_LIBRARY, 'productName' => name)
|
24
|
+
target.product.path = "lib#{name}.a"
|
25
|
+
|
26
|
+
target.build_configurations.each do |config|
|
27
|
+
config.build_settings.merge!(XCBuildConfiguration::COMMON_BUILD_SETTINGS[platform])
|
28
|
+
|
29
|
+
# E.g. [:ios, :release]
|
30
|
+
extra_settings_key = [platform, config.name.downcase.to_sym]
|
31
|
+
if extra_settings = XCBuildConfiguration::COMMON_BUILD_SETTINGS[extra_settings_key]
|
32
|
+
config.build_settings.merge!(extra_settings)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
target
|
37
|
+
end
|
38
|
+
|
39
|
+
# You need to specify a product. For a static library you can use
|
40
|
+
# PBXFileReference.new_static_library.
|
41
|
+
def initialize(project, *)
|
42
|
+
super
|
43
|
+
self.name ||= product_name
|
44
|
+
self.build_rule_references ||= []
|
45
|
+
self.dependency_references ||= []
|
46
|
+
|
47
|
+
unless build_phase_references
|
48
|
+
self.build_phase_references = []
|
49
|
+
|
50
|
+
source_build_phases.new
|
51
|
+
copy_files_build_phases.new
|
52
|
+
#shell_script_build_phases.new
|
53
|
+
|
54
|
+
phase = frameworks_build_phases.new
|
55
|
+
if frameworks_group = @project.groups.where(:name => 'Frameworks')
|
56
|
+
frameworks_group.files.each { |framework| phase << framework }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
unless build_configuration_list
|
61
|
+
self.build_configuration_list = project.objects.add(XCConfigurationList, {
|
62
|
+
'defaultConfigurationIsVisible' => '0',
|
63
|
+
'defaultConfigurationName' => 'Release',
|
64
|
+
})
|
65
|
+
# TODO or should this happen in buildConfigurationList?
|
66
|
+
build_configuration_list.build_configurations.new_debug
|
67
|
+
build_configuration_list.build_configurations.new_release
|
68
|
+
end
|
69
|
+
|
70
|
+
unless product
|
71
|
+
self.product = @project.files.new_static_library(product_name)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
alias_method :_product=, :product=
|
76
|
+
def product=(product)
|
77
|
+
self._product = product
|
78
|
+
@project.products << product
|
79
|
+
end
|
80
|
+
|
81
|
+
def build_configurations
|
82
|
+
build_configuration_list.build_configurations
|
83
|
+
end
|
84
|
+
|
85
|
+
def build_settings(build_configuration_name)
|
86
|
+
build_configuration_list.build_settings(build_configuration_name)
|
87
|
+
end
|
88
|
+
|
89
|
+
def source_build_phases
|
90
|
+
build_phases.list_by_class(PBXSourcesBuildPhase)
|
91
|
+
end
|
92
|
+
|
93
|
+
def copy_files_build_phases
|
94
|
+
build_phases.list_by_class(PBXCopyFilesBuildPhase)
|
95
|
+
end
|
96
|
+
|
97
|
+
def frameworks_build_phases
|
98
|
+
build_phases.list_by_class(PBXFrameworksBuildPhase)
|
99
|
+
end
|
100
|
+
|
101
|
+
def shell_script_build_phases
|
102
|
+
build_phases.list_by_class(PBXShellScriptBuildPhase)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Finds an existing file reference or creates a new one.
|
106
|
+
def add_source_file(path, copy_header_phase = nil, compiler_flags = nil)
|
107
|
+
file = @project.files.find { |file| file.path == path.to_s } || @project.files.new('path' => path.to_s)
|
108
|
+
build_file = file.build_files.new
|
109
|
+
if path.extname == '.h'
|
110
|
+
build_file.settings = { 'ATTRIBUTES' => ["Public"] }
|
111
|
+
# Working around a bug in Xcode 4.2 betas, remove this once the Xcode bug is fixed:
|
112
|
+
# https://github.com/alloy/cocoapods/issues/13
|
113
|
+
#phase = copy_header_phase || headers_build_phases.first
|
114
|
+
phase = copy_header_phase || copy_files_build_phases.first
|
115
|
+
phase.build_files << build_file
|
116
|
+
else
|
117
|
+
build_file.settings = { 'COMPILER_FLAGS' => compiler_flags } if compiler_flags
|
118
|
+
source_build_phases.first.build_files << build_file
|
119
|
+
end
|
120
|
+
file
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Project
|
3
|
+
|
4
|
+
# In case `scoped` is an Array the list's order is maintained.
|
5
|
+
class PBXObjectList
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize(represented_class, project)
|
9
|
+
@represented_class = represented_class
|
10
|
+
@project = project
|
11
|
+
@callbacks = {}
|
12
|
+
|
13
|
+
yield self if block_given?
|
14
|
+
end
|
15
|
+
|
16
|
+
# Specify callbacks for:
|
17
|
+
# * :uuid_scope Returns the list of UUIDs to scope this list to.
|
18
|
+
# * :push When an object is added to the list.
|
19
|
+
def let(callback_name, &block)
|
20
|
+
raise ArgumentError, "Incorrect callback `#{callback_name}'." unless [:uuid_scope, :push].include?(callback_name)
|
21
|
+
@callbacks[callback_name] = block
|
22
|
+
end
|
23
|
+
|
24
|
+
def uuid_scope
|
25
|
+
@callbacks[:uuid_scope].call
|
26
|
+
end
|
27
|
+
|
28
|
+
def empty?
|
29
|
+
uuid_scope.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
def [](uuid)
|
33
|
+
if uuid_scope.include?(uuid) && hash = @project.objects_hash[uuid]
|
34
|
+
Object.const_get(hash['isa']).new(@project, uuid, hash)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def add(klass, hash = {})
|
39
|
+
object = klass.new(@project, nil, hash)
|
40
|
+
self << object
|
41
|
+
object
|
42
|
+
end
|
43
|
+
|
44
|
+
def new(hash = {})
|
45
|
+
add(@represented_class, hash)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Run Ruby in debug mode to receive warnings about calls to :push when a
|
49
|
+
# list does not have a callback registered for :push.
|
50
|
+
def push(object)
|
51
|
+
if @callbacks[:push]
|
52
|
+
@callbacks[:push].call(object)
|
53
|
+
else
|
54
|
+
if $DEBUG
|
55
|
+
warn "Pushed object onto a PBXObjectList that does not have a :push callback from: #{caller.first}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
self
|
59
|
+
end
|
60
|
+
alias_method :<<, :push
|
61
|
+
|
62
|
+
def each
|
63
|
+
uuid_scope.each do |uuid|
|
64
|
+
yield self[uuid]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def ==(other)
|
69
|
+
self.to_a == other.to_a
|
70
|
+
end
|
71
|
+
|
72
|
+
def size
|
73
|
+
uuid_scope.size
|
74
|
+
end
|
75
|
+
|
76
|
+
# Since order can't always be guaranteed, these might need to move to an order specific subclass.
|
77
|
+
def first
|
78
|
+
to_a.first
|
79
|
+
end
|
80
|
+
def last
|
81
|
+
to_a.last
|
82
|
+
end
|
83
|
+
|
84
|
+
def inspect
|
85
|
+
"<PBXObjectList: #{map(&:inspect).join(', ')}>"
|
86
|
+
end
|
87
|
+
|
88
|
+
def where(attributes)
|
89
|
+
find { |o| o.matches_attributes?(attributes) }
|
90
|
+
end
|
91
|
+
|
92
|
+
# @todo is it really necessary to have an extra method for this?
|
93
|
+
def object_named(name)
|
94
|
+
where :name => name
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns a PBXObjectList instance of objects in the list.
|
98
|
+
#
|
99
|
+
# By default this list will scope the list by objects matching the
|
100
|
+
# specified class and add objects, pushed onto the list, to the parent
|
101
|
+
# list
|
102
|
+
#
|
103
|
+
# If a block is given the list instance is yielded so that the default
|
104
|
+
# callbacks can be overridden.
|
105
|
+
#
|
106
|
+
# @param [AbstractPBXObject] klass The AbstractPBXObject subclass to
|
107
|
+
# which the list should be scoped.
|
108
|
+
#
|
109
|
+
# @yield [PBXObjectList] The list instance, allowing you to
|
110
|
+
# easily override the callbacks.
|
111
|
+
#
|
112
|
+
# @return [PBXObjectList<klass>] The list of matching objects.
|
113
|
+
def list_by_class(klass)
|
114
|
+
parent = self
|
115
|
+
PBXObjectList.new(klass, @project) do |list|
|
116
|
+
list.let(:push) do |object|
|
117
|
+
# Objects added to the subselection should still use the same
|
118
|
+
# callback as this list.
|
119
|
+
parent << object
|
120
|
+
end
|
121
|
+
list.let(:uuid_scope) do
|
122
|
+
parent.uuid_scope.select do |uuid|
|
123
|
+
@project.objects_hash[uuid]['isa'] == klass.isa
|
124
|
+
end
|
125
|
+
end
|
126
|
+
yield list if block_given?
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# This only makes sense on those with a specific represented class. Not the main objects list.
|
131
|
+
def method_missing(name, *args, &block)
|
132
|
+
if @represented_class.respond_to?(name)
|
133
|
+
object = @represented_class.send(name, @project, *args)
|
134
|
+
# The callbacks are only for AbstractPBXObject instances instantiated
|
135
|
+
# from the class method that we forwarded the message to.
|
136
|
+
self << object if object.is_a?(Object::AbstractPBXObject)
|
137
|
+
object
|
138
|
+
else
|
139
|
+
super
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|