cocoa 0.1.5 → 0.1.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 04969b65f9381a64dff26285eadea02ee22a5707
4
- data.tar.gz: 328544cf27ee82e63349e8e1978a972867243a51
3
+ metadata.gz: 5f71aa43ea295a1886c05be665d147e1312fb09a
4
+ data.tar.gz: c33bb6813e008b446256ceec2592d4b1dd897bcc
5
5
  SHA512:
6
- metadata.gz: 9eb8aa0801e1737d082428259cef0108ece9d5d95263ba0ffe1646b6c5324910074ad208b70e90a8ce60b28c0217772e0b5c719ce7c75f2ac04bc27d83135769
7
- data.tar.gz: 2d904420d15c59dfbe60962a7eb17e46dd029382ab00540817adb6b66fc961aa456c1a3c8254fcb8892380857cacd0735d369a379c29fd9da20873ca8bad54ac
6
+ metadata.gz: e655407c657e9e8b7a7bfbdf65fa7cd1f27cdbbaa050183e283c03a6308041abb71f678914e974d7f2a5caf6b8454cf808ce8269bf99b16612b657c3f401fb32
7
+ data.tar.gz: 4eddefb01fbb2b0bef984084a2adcb0ff50c144614887cf3591a29211cad5ca3fbe4d53471661446b5da273e3edf48c6dded60b20b89f2a50468eb4f089d787b
data/Rakefile CHANGED
@@ -1,6 +1,10 @@
1
1
  # encoding: utf-8
2
2
 
3
- PROJECT_SPECS = FileList['spec/**/*_spec.rb']
3
+ PROJECT_SPECS = if RUBY_VERSION.split.first.to_i >= 2
4
+ FileList['spec/**/*_spec.rb'] + FileList['spec/**/*_spec_r2.rb']
5
+ else
6
+ FileList['spec/**/*_spec.rb']
7
+ end
4
8
 
5
9
  require 'jeweler'
6
10
  Jeweler::Tasks.new do |gem|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.5
1
+ 0.1.6
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: cocoa 0.1.5 ruby lib
5
+ # stub: cocoa 0.1.6 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "cocoa"
9
- s.version = "0.1.5"
9
+ s.version = "0.1.6"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Patrick Hanevold"]
14
- s.date = "2014-04-11"
14
+ s.date = "2014-04-13"
15
15
  s.description = "Ruby FFI bindings for the OSX Cocoa API"
16
16
  s.email = "patrick.hanevold@gmail.com"
17
17
  s.extra_rdoc_files = [
@@ -425,6 +425,7 @@ Gem::Specification.new do |s|
425
425
  "lib/cocoa/structs/NSRect.rb",
426
426
  "lib/cocoa/structs/NSSize.rb",
427
427
  "spec/cocoa/cocoa_spec.rb",
428
+ "spec/cocoa/cocoa_spec_r2.rb",
428
429
  "spec/spec_helper.rb",
429
430
  "tasks/bacon.rake",
430
431
  "tasks/generate.rake",
@@ -26,7 +26,13 @@ class Cocoa::NSObject
26
26
  end
27
27
 
28
28
  def self.native_name
29
- name.split('::').last
29
+ arr = name.split('::')
30
+ native = if arr.first == 'Cocoa'
31
+ arr.last
32
+ else
33
+ name.gsub(/::/,'__')
34
+ end
35
+ native
30
36
  end
31
37
 
32
38
  def self.alloc
@@ -123,24 +123,27 @@ module Cocoa
123
123
 
124
124
  def self.attach_method method,*_params
125
125
  return if method==:class
126
- @@method_specs ||= {}
127
- @@method_specs[method] = []
126
+ @method_specs ||= {}
127
+ @method_specs[method] = []
128
128
  [_params].flatten.each do |spec|
129
- @@method_specs[method] << ObjC::MethodDef.new(method,spec)
129
+ @method_specs[method] << ObjC::MethodDef.new(method,spec)
130
130
  end
131
131
  define_method method do |*args|
132
+ klass = self.class; klass = klass.superclass while !klass.instance_methods(false).include?(method)
133
+ spec = klass.instance_variable_get(:@method_specs)[method]
134
+
132
135
  matching = if args.size <= 1
133
- matching = @@method_specs[method].select do |m|
136
+ matching = spec.select do |m|
134
137
  m.types.size == args.size
135
138
  end
136
139
  else
137
140
  matching = if args.last.is_a? Hash
138
- @@method_specs[method].select do |m|
141
+ spec.select do |m|
139
142
  args.last.keys == m.names
140
143
  end
141
144
  else
142
145
  raise "hell" unless args.size == 1
143
- @@method_specs[method].select do |m|
146
+ spec.select do |m|
144
147
  m.types.size == 1
145
148
  end
146
149
  end
@@ -157,18 +160,26 @@ module Cocoa
157
160
  end
158
161
 
159
162
  def self.method_defs method
160
- return nil unless @@method_specs[method]
163
+ klass = self
164
+ method_specs = klass.instance_variable_get(:@method_specs)
165
+ while klass && (!method_specs || !method_specs[method])
166
+ klass = klass.superclass
167
+ method_specs = klass.instance_variable_get(:@method_specs)
168
+ end
169
+ return nil unless method_specs
170
+
171
+ spec = method_specs[method]
161
172
  params = instance_method(method).parameters
162
173
  keys = params.select{ |param| param.first == :key }.map{ |param| param.last }
163
174
  if params.size > 0 && params.last.first == :rest
164
- filtered = @@method_specs[method].select do |m|
175
+ filtered = spec.select do |m|
165
176
  ((m.types.size == 0 && keys.size == 0) || (m.types.size > keys.size)) &&
166
177
  (m.names[0,keys.size-1] || []) == keys
167
178
  end
168
179
  return nil if filtered.size == 0
169
180
  filtered
170
181
  else
171
- filtered = @@method_specs[method].select do |m|
182
+ filtered = spec.select do |m|
172
183
  ((m.types.size == 0 && keys.size == 0) || (m.types.size == keys.size+1)) &&
173
184
  m.names == keys
174
185
  end
@@ -181,18 +192,42 @@ module Cocoa
181
192
  def self.method_added(name)
182
193
  return if name == :== # TODO: define as equals or something?
183
194
  return if name.to_s[-1] == '='
195
+ return if caller[1].split('`').last[0..-2] == 'method_added' # self
184
196
  return if caller.first.split('`').last[0..-2] == 'define_method' # MRI
185
197
  return if caller.first.split('`').last[0..-2] == 'attach_method' # Rubinius
186
198
 
199
+ # define an alias for keyword argument methods such that:
200
+ # class Foo
201
+ # def bar whatever, alpha: nil
202
+ # puts "alpha is: #{alpha}"
203
+ # end
204
+ # def bar whatever, omega: nil
205
+ # puts "omega is: #{omega}"
206
+ # end
207
+ # end
208
+ # Foo.new.bar "hello", omega: "is omega"
209
+ # Foo.new.bar "hello", alpha: "is alpha"
210
+ #=>
211
+ # omega is: is omega
212
+ # alpha is: is alpha
213
+ keys = instance_method(name).parameters.select{ |param| param.first == :key }.map{ |param| param.last }
214
+ ruby_name = name
215
+ if keys.size > 0
216
+ ruby_name = "_#{name}_with_#{keys.join('_and_')}".to_sym
217
+ alias_method ruby_name, name
218
+ end
219
+
220
+
187
221
  defs = method_defs name
188
222
  defs ||= ObjC::MethodDef.new(name, :names => [], :types => ['@'], :retval => 'v') # TODO: generate from method arguments!
189
223
 
190
224
  [defs].flatten.each do |m|
191
225
  @callbacks ||= []
192
226
  @callbacks << Proc.new do |this,cmd,*args|
227
+ m.ruby_name = ruby_name
193
228
  begin
194
229
  instance = Cocoa.instances[this.address]
195
- params = instance_method(name).parameters
230
+ params = instance_method(ruby_name).parameters
196
231
  m.callback(instance,params,args)
197
232
  rescue => e
198
233
  puts e.message
@@ -203,10 +238,20 @@ module Cocoa
203
238
  callback_name = "#{self.name.gsub('::','__')}_#{m.selector.gsub(/:/,'_')}".to_sym
204
239
  add_method = "add_#{callback_name}".to_sym
205
240
 
241
+ native_name = begin
242
+ arr = self.name.split('::')
243
+ native = if arr.first == 'Cocoa'
244
+ arr.last
245
+ else
246
+ self.name.gsub(/::/,'__')
247
+ end
248
+ native
249
+ end
250
+
206
251
  ObjC.callback callback_name, [:pointer, :pointer]+m.ffi_types, m.ffi_return_type
207
252
  ObjC.attach_function add_method, :class_addMethod, [:pointer,:pointer,callback_name,:string], :void
208
253
 
209
- ObjC.send(add_method,ObjC.objc_getClass(self.name.split('::').last),ObjC.sel_registerName(m.selector),@callbacks.last,m.objc_types)
254
+ ObjC.send(add_method,ObjC.objc_getClass(native_name),ObjC.sel_registerName(m.selector),@callbacks.last,m.objc_types)
210
255
  end
211
256
  end
212
257
  end
@@ -75,19 +75,23 @@ module ObjC
75
75
  instance = begin
76
76
  Cocoa::const_get(klass_name).new(true)
77
77
  rescue
78
- klass_name = if klass_name =~ /^__NSCF/
79
- "NS#{klass_name[6..-1]}"
80
- elsif klass_name[0]=='_'
81
- if superklass = Cocoa::const_get(NSString_to_String(Cocoa::NSStringFromClass(ObjC.msgSend_pointer(ret,"superclass"))))
82
- superklass.name.split('::').last
78
+ begin
79
+ Object.const_get(klass_name.gsub(/__/,'::')).new(true)
80
+ rescue
81
+ klass_name = if klass_name =~ /^__NSCF/
82
+ "NS#{klass_name[6..-1]}"
83
+ elsif klass_name[0]=='_'
84
+ if superklass = Cocoa::const_get(NSString_to_String(Cocoa::NSStringFromClass(ObjC.msgSend_pointer(ret,"superclass"))))
85
+ superklass.name.split('::').last
86
+ else
87
+ "FIX_#{klass_name}"
88
+ end
83
89
  else
84
- "FIX_#{klass_name}"
90
+ klass_name
85
91
  end
86
- else
87
- klass_name
92
+ klass = smart_constantize(ret,klass_name)
93
+ klass.new(true)
88
94
  end
89
- klass = smart_constantize(ret,klass_name)
90
- klass.new(true)
91
95
  end
92
96
  instance.object = ret
93
97
  instance
@@ -119,7 +123,7 @@ module ObjC
119
123
  case type
120
124
  when nil
121
125
  default
122
- when '@', 'v', 'q', 'Q', '^v'
126
+ when '@', 'v', 'q', 'Q', '^v', 'B'
123
127
  type
124
128
  when /^{([^=]*)=.*}$/
125
129
  type
@@ -1,6 +1,6 @@
1
1
  module ObjC
2
2
  class MethodDef
3
- attr_accessor :name,:names,:types,:return_type
3
+ attr_accessor :name,:names,:types,:return_type,:ruby_name
4
4
 
5
5
  TYPES = {
6
6
  'c' => :char,
@@ -31,6 +31,7 @@ module ObjC
31
31
 
32
32
  def initialize name,options
33
33
  @name = name.to_sym
34
+ @ruby_name = name.to_sym
34
35
  @names = options[:names].map(&:to_sym)
35
36
  @types = options[:types]
36
37
  @return_type = options[:retval]
@@ -280,12 +281,12 @@ module ObjC
280
281
 
281
282
  ret = if params.size > 0 && params.last.first == :rest
282
283
  args = args.map{ |arg| Cocoa::instance_for(arg) }
283
- instance.send(name, args.first, Hash[*names.zip(args[1..-1]).flatten])
284
+ instance.send(ruby_name, args.first, Hash[*names.zip(args[1..-1]).flatten])
284
285
  elsif keys.size > 0
285
286
  args = args.map{ |arg| Cocoa::instance_for(arg) }
286
- instance.send(name, args.first, Hash[*keys.zip(args[1..-1]).flatten])
287
+ instance.send(ruby_name, args.first, Hash[*keys.zip(args[1..-1]).flatten])
287
288
  else
288
- instance.send(name, *args.map{ |arg| Cocoa::instance_for(arg) })
289
+ instance.send(ruby_name, *args.map{ |arg| Cocoa::instance_for(arg) })
289
290
  end
290
291
  ffi_return_value(ret)
291
292
  end
@@ -17,6 +17,17 @@ describe 'Cocoa' do
17
17
  Derived.superclass.name.should == 'Cocoa::NSObject'
18
18
  end
19
19
 
20
+ it 'should provide native names' do
21
+ class Derived < Cocoa::NSObject
22
+ end
23
+ module Scoped; end
24
+ class Scoped::Derived < Cocoa::NSObject
25
+ end
26
+ Cocoa::NSObject.native_name.should == 'NSObject'
27
+ Derived.native_name.should == 'Derived'
28
+ Scoped::Derived.native_name.should == 'Scoped__Derived'
29
+ end
30
+
20
31
  it 'should provide correct return types for class methods' do
21
32
  Cocoa::NSMutableArray.array.class.name.should == 'Cocoa::NSMutableArray'
22
33
  end
@@ -115,6 +126,7 @@ describe 'Cocoa' do
115
126
  # fake ruby 2
116
127
  unbound_method = mock('UnboundMethod')
117
128
  Cocoa::NSObject.expects(:instance_method).with(:tableView).at_least_once.returns(unbound_method)
129
+ Cocoa::NSObject.expects(:instance_method).with(:_tableView_with_objectValueForTableColumn_and_row).at_least_once.returns(unbound_method)
118
130
  unbound_method.expects(:parameters).at_least_once.returns([[:req, :table_view], [:key, :objectValueForTableColumn], [:key, :row]])
119
131
  class Derived < Cocoa::NSObject
120
132
  #def tableView(table_view, objectValueForTableColumn: column, row: i); end
@@ -122,7 +134,7 @@ describe 'Cocoa' do
122
134
  end
123
135
 
124
136
  derived = Derived.new
125
- derived.expects(:tableView).with(
137
+ derived.expects(:_tableView_with_objectValueForTableColumn_and_row).with(
126
138
  Cocoa::NSString.stringWithString("arg1"),
127
139
  objectValueForTableColumn: Cocoa::NSString.stringWithString("arg2"),
128
140
  row: 123
@@ -137,6 +149,7 @@ describe 'Cocoa' do
137
149
  # fake ruby 2
138
150
  unbound_method = mock('UnboundMethod')
139
151
  Cocoa::NSObject.expects(:instance_method).with(:tableView).at_least_once.returns(unbound_method)
152
+ Cocoa::NSObject.expects(:instance_method).with(:_tableView_with_objectValueForTableColumn_and_row).at_least_once.returns(unbound_method)
140
153
  unbound_method.expects(:parameters).at_least_once.returns([[:req, :table_view], [:key, :objectValueForTableColumn], [:key, :row]])
141
154
  class Derived < Cocoa::NSObject
142
155
  #def tableView(table_view, objectValueForTableColumn: column, row: i); end
@@ -157,7 +170,7 @@ describe 'Cocoa' do
157
170
  end
158
171
 
159
172
  derived = Derived.new
160
- derived.expects(:tableView).with(
173
+ derived.expects(:_tableView_with_objectValueForTableColumn_and_row).with(
161
174
  Cocoa::NSString.stringWithString("arg1"),
162
175
  objectValueForTableColumn: Cocoa::NSString.stringWithString("arg2"),
163
176
  row: 123
@@ -0,0 +1,18 @@
1
+ require_relative '../spec_helper'
2
+ require 'cocoa'
3
+
4
+ describe 'Cocoa' do
5
+ # context 'callbacks' do
6
+ it 'should be able to call overridden methods with keword arguments and return a value' do
7
+ class Derived < Cocoa::NSObject
8
+ def tableView(table_view, objectValueForTableColumn: column, row: i)
9
+ "returned value"
10
+ end
11
+ end
12
+
13
+ derived = Derived.new
14
+ ret = derived.tableView("arg1", objectValueForTableColumn: "arg2", row: 123)
15
+ ret.to_s.should == "returned value"
16
+ end
17
+ # end
18
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocoa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Hanevold
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-11 00:00:00.000000000 Z
11
+ date: 2014-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -550,6 +550,7 @@ files:
550
550
  - lib/cocoa/structs/NSRect.rb
551
551
  - lib/cocoa/structs/NSSize.rb
552
552
  - spec/cocoa/cocoa_spec.rb
553
+ - spec/cocoa/cocoa_spec_r2.rb
553
554
  - spec/spec_helper.rb
554
555
  - tasks/bacon.rake
555
556
  - tasks/generate.rake