opal 0.3.38 → 0.3.39

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,16 @@
1
- ## Edge ##
1
+ ## 0.3.39 2013-02-20
2
+
3
+ * Fix bug where methods defined on a parent class after subclass was defined
4
+ would not given subclass access to method. Subclasses are now also tracked
5
+ by superclass, by a private '_inherited' property.
6
+
7
+ * Fix bug where classes defined by `Class.new` did not have a constant scope.
8
+
9
+ * Move Date out of opal.rb loading, as it is part of stdlib not corelib.
10
+
11
+ * Fix for defining methods inside metaclass, or singleton_class scopes.
12
+
13
+ ## 0.3.38 2013-02-13
2
14
 
3
15
  * Add Native module used for wrapping objects to forward calls as native
4
16
  calls.
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source :rubygems
2
2
  gemspec
3
3
 
4
4
  gem 'rake'
5
+ gem 'racc'
6
+ gem 'opal-spec', '~> 0.2.12'
@@ -15,7 +15,6 @@ require 'opal/numeric'
15
15
  require 'opal/proc'
16
16
  require 'opal/range'
17
17
  require 'opal/time'
18
- require 'opal/date'
19
18
  require 'opal/json'
20
19
 
21
20
  # regexp matches
@@ -4,6 +4,7 @@ class Class
4
4
  function AnonClass(){};
5
5
  var klass = Opal.boot(sup, AnonClass)
6
6
  klass._name = nil;
7
+ klass._scope = sup._scope;
7
8
 
8
9
  sup.$inherited(klass);
9
10
 
@@ -77,7 +78,7 @@ class Class
77
78
  }
78
79
 
79
80
  if (prototype._smethods) {
80
- prototype._sdonate(methods);
81
+ prototype._smethods.push.apply(prototype._smethods, methods);
81
82
  }
82
83
 
83
84
  if (klass.$included_in) {
@@ -131,6 +131,7 @@
131
131
  prototype._isObject = true;
132
132
  prototype._klass = constructor;
133
133
 
134
+ constructor._inherited = [];
134
135
  constructor._included_in = [];
135
136
  constructor._isClass = true;
136
137
  constructor._name = id;
@@ -140,7 +141,7 @@
140
141
  constructor._isObject = false;
141
142
 
142
143
  constructor._donate = __donate;
143
- constructor._sdonate = __sdonate;
144
+ constructor._defs = __defs;
144
145
 
145
146
  constructor['$==='] = module_eqq;
146
147
  constructor.$to_s = module_to_s;
@@ -162,6 +163,7 @@
162
163
  prototype._klass = constructor;
163
164
  prototype.constructor = constructor;
164
165
 
166
+ constructor._inherited = [];
165
167
  constructor._included_in = [];
166
168
  constructor._isClass = true;
167
169
  constructor._super = superklass;
@@ -169,7 +171,7 @@
169
171
  constructor._isObject = false;
170
172
  constructor._klass = Class;
171
173
  constructor._donate = __donate
172
- constructor._sdonate = __sdonate;
174
+ constructor._defs = __defs;
173
175
 
174
176
  constructor['$==='] = module_eqq;
175
177
  constructor.$to_s = module_to_s;
@@ -185,12 +187,15 @@
185
187
  constructor[m] = superklass[m];
186
188
  }
187
189
 
190
+ superklass._inherited.push(constructor);
191
+
188
192
  return constructor;
189
193
  };
190
194
 
191
195
  var bridge_class = function(constructor) {
192
196
  constructor.prototype._klass = constructor;
193
197
 
198
+ constructor._inherited = [];
194
199
  constructor._included_in = [];
195
200
  constructor._isClass = true;
196
201
  constructor._super = Object;
@@ -200,7 +205,7 @@
200
205
  constructor._isObject = false;
201
206
 
202
207
  constructor._donate = function(){};
203
- constructor._sdonate = __sdonate;
208
+ constructor._defs = __defs;
204
209
 
205
210
  constructor['$==='] = module_eqq;
206
211
  constructor.$to_s = module_to_s;
@@ -296,9 +301,20 @@
296
301
  }
297
302
  }
298
303
 
299
- // Donator for singleton (class) methods
300
- function __sdonate(defined) {
301
- this._smethods = this._smethods.concat(defined);
304
+ // Define a singleton method on a class
305
+ function __defs(mid, body) {
306
+ this._smethods.push(mid);
307
+ this[mid] = body;
308
+
309
+ var inherited = this._inherited;
310
+ if (inherited.length) {
311
+ for (var i = 0, length = inherited.length, subclass; i < length; i++) {
312
+ subclass = inherited[i];
313
+ if (!subclass[mid]) {
314
+ subclass._defs(mid, body);
315
+ }
316
+ }
317
+ }
302
318
  }
303
319
 
304
320
  var bridged_classes = Object.$included_in = [];
@@ -952,7 +952,9 @@ module Opal
952
952
  code = nil
953
953
 
954
954
  in_scope(:sclass) do
955
- @scope.add_temp '__scope = self._scope'
955
+ @scope.add_temp "__scope = #{current_self}._scope"
956
+ @scope.add_temp "def = #{current_self}.prototype"
957
+
956
958
  code = @scope.to_vars + process(body, :stmt)
957
959
  end
958
960
 
@@ -1143,8 +1145,7 @@ module Opal
1143
1145
 
1144
1146
  if recvr
1145
1147
  if smethod
1146
- @scope.smethods << "$#{mid}"
1147
- "#{ @scope.name }#{jsid} = #{defcode}"
1148
+ "#{ @scope.name }._defs('$#{mid}', #{defcode})"
1148
1149
  else
1149
1150
  "#{ recv }#{ jsid } = #{ defcode }"
1150
1151
  end
@@ -27,9 +27,6 @@ module Opal
27
27
  # used by modules to know what methods to donate to includees
28
28
  attr_reader :methods
29
29
 
30
- # singleton methods defined on classes/modules
31
- attr_reader :smethods
32
-
33
30
  # uses parents super method
34
31
  attr_accessor :uses_super
35
32
 
@@ -49,7 +46,6 @@ module Opal
49
46
  @defines_defn = false
50
47
 
51
48
  @methods = []
52
- @smethods = []
53
49
 
54
50
  @uses_block = false
55
51
 
@@ -118,20 +114,11 @@ module Opal
118
114
 
119
115
  # Generates code for this module to donate methods
120
116
  def to_donate_methods
121
- out = ""
122
-
123
117
  if should_donate? and !@methods.empty?
124
- # unless @methods.empty?
125
- out += "%s;#{@name}._donate([%s]);" %
126
- [@parser.parser_indent, @methods.map(&:inspect).join(', ')]
127
- end
128
-
129
- unless @smethods.empty?
130
- out += "%s;#{@name}._sdonate([%s]);" %
131
- [@parser.parser_indent, @smethods.map(&:inspect).join(', ')]
118
+ "%s;#{@name}._donate([%s]);" % [@parser.parser_indent, @methods.map(&:inspect).join(', ')]
119
+ else
120
+ ""
132
121
  end
133
-
134
- out
135
122
  end
136
123
 
137
124
  def add_ivar(ivar)
@@ -1,3 +1,3 @@
1
1
  module Opal
2
- VERSION = '0.3.38'
2
+ VERSION = '0.3.39'
3
3
  end
@@ -16,7 +16,4 @@ Gem::Specification.new do |s|
16
16
  s.require_paths = ['lib']
17
17
 
18
18
  s.add_runtime_dependency 'sprockets'
19
-
20
- s.add_development_dependency 'opal-spec', '~> 0.2.10'
21
- s.add_development_dependency 'racc'
22
19
  end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ class Class
4
+ def get_inherited_classes
5
+ `#{self}._inherited`
6
+ end
7
+ end
8
+
9
+ module ClassInheritedSpecs
10
+ class None
11
+ end
12
+
13
+ class A
14
+ end
15
+
16
+ class B < A
17
+ end
18
+
19
+ class C < A
20
+ end
21
+
22
+ class D < C
23
+ end
24
+ end
25
+
26
+ describe "Class '_inherited' variable" do
27
+ it "contains an array of all subclasses of class" do
28
+ ClassInheritedSpecs::None.get_inherited_classes.should eq([])
29
+ ClassInheritedSpecs::A.get_inherited_classes.should eq([ClassInheritedSpecs::B, ClassInheritedSpecs::C])
30
+ ClassInheritedSpecs::C.get_inherited_classes.should eq([ClassInheritedSpecs::D])
31
+ end
32
+ end
@@ -0,0 +1,41 @@
1
+ require "spec_helper"
2
+
3
+ module ClassSingletonSpecs
4
+ class A
5
+ def self.foo; :foo; end
6
+ def self.bar; :bar; end
7
+ end
8
+
9
+ class B < A
10
+ def self.bar; :baz; end
11
+ end
12
+
13
+ class C < B
14
+ end
15
+
16
+ class A
17
+ def self.woosh; :kapow; end
18
+ end
19
+ end
20
+
21
+ describe "Class singleton methods" do
22
+ it "should be inherited by subclasses" do
23
+ ClassSingletonSpecs::B.foo.should eq(:foo)
24
+ end
25
+
26
+ it "should be inherited by subclasses of subclasses" do
27
+ ClassSingletonSpecs::C.foo.should eq(:foo)
28
+ end
29
+
30
+ it "subclasses can override inherited methods" do
31
+ ClassSingletonSpecs::A.bar.should eq(:bar)
32
+ ClassSingletonSpecs::B.bar.should eq(:baz)
33
+ ClassSingletonSpecs::C.bar.should eq(:baz)
34
+ end
35
+
36
+ it "subclasses inherit additional methods defined on superclass after they are defined" do
37
+ ClassSingletonSpecs::A.woosh.should eq(:kapow)
38
+ ClassSingletonSpecs::B.woosh.should eq(:kapow)
39
+ ClassSingletonSpecs::C.woosh.should eq(:kapow)
40
+ end
41
+ end
@@ -22,7 +22,7 @@ describe "Opal::Parser" do
22
22
  it "should parse constant lookups" do
23
23
  opal_eval("Object").should == Object
24
24
  opal_eval("Array").should == Array
25
- opal_eval("Spec::ExampleGroup").should == Spec::ExampleGroup
25
+ opal_eval("Opal::Parser").should == Opal::Parser
26
26
  end
27
27
 
28
28
  it "should parse class and module definitions" do
@@ -0,0 +1,48 @@
1
+ class DefSpecSingleton
2
+ class << self
3
+ def a_class_method;self;end
4
+ end
5
+ end
6
+
7
+ describe "A method definition inside a metaclass scope" do
8
+ it "can create a class method" do
9
+ DefSpecSingleton.a_class_method.should == DefSpecSingleton
10
+ lambda { Object.a_class_method }.should raise_error(NoMethodError)
11
+ end
12
+
13
+ it "can create a singleton method" do
14
+ obj = Object.new
15
+ class << obj
16
+ def a_singleton_method;self;end
17
+ end
18
+
19
+ obj.a_singleton_method.should == obj
20
+ lambda { Object.new.a_singleton_method }.should raise_error(NoMethodError)
21
+ end
22
+ end
23
+
24
+ describe "A method definition inside an instance_eval" do
25
+ it "creates a singleton method" do
26
+ obj = Object.new
27
+ obj.instance_eval do
28
+ def an_instance_eval_method;self;end
29
+ end
30
+ obj.an_instance_eval_method.should == obj
31
+
32
+ other = Object.new
33
+ lambda { other.an_instance_eval_method }.should raise_error(NoMethodError)
34
+ end
35
+
36
+ it "creates a singleton method when evaluated inside a metaclass" do
37
+ obj = Object.new
38
+ obj.instance_eval do
39
+ class << self
40
+ def a_metaclass_eval_method;self;end
41
+ end
42
+ end
43
+ obj.a_metaclass_eval_method.should == obj
44
+
45
+ other = Object.new
46
+ lambda { other.a_metaclass_eval_method }.should raise_error(NoMethodError)
47
+ end
48
+ end
@@ -1,3 +1,8 @@
1
+
2
+ module ClassSpecs
3
+ class A; end
4
+ end
5
+
1
6
  describe "A singleton class" do
2
7
  it "is NilClass for nil" do
3
8
  nil.singleton_class.should == NilClass
@@ -14,6 +19,15 @@ describe "A singleton class" do
14
19
  end
15
20
  end
16
21
 
17
- module ClassSpecs
18
- class A; end
19
- end
22
+ describe "Defining instance methods on a singleton class" do
23
+ before do
24
+ @object = Object.new
25
+ class << @object
26
+ def singleton_method; 1 end
27
+ end
28
+ end
29
+
30
+ it "defines public methods" do
31
+ @object.singleton_method.should eq(1)
32
+ end
33
+ end
@@ -1,3 +1,5 @@
1
+ require "spec_helper"
2
+
1
3
  describe "Date.new" do
2
4
  it "creates a date with arguments" do
3
5
  d = Date.new(2000, 3, 5)
@@ -1,3 +1,5 @@
1
+ require "spec_helper"
2
+
1
3
  describe "Date#to_s" do
2
4
  it "returns a string representation of date (YYYY-MM-DD)" do
3
5
  Date.new(2012, 10, 26).to_s.should == "2012-10-26"
@@ -1,3 +1,5 @@
1
+ require "spec_helper"
2
+
1
3
  describe "Date.today" do
2
4
  it "creates a new instance for current date" do
3
5
  Date.today.should be_kind_of(Date)
@@ -2,6 +2,9 @@ require 'opal'
2
2
  require 'opal-parser'
3
3
  require 'opal-spec'
4
4
 
5
+ # stdlib
6
+ require 'opal/date'
7
+
5
8
  module Kernel
6
9
  def opal_eval(str)
7
10
  code = Opal::Parser.new.parse str
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.38
4
+ version: 0.3.39
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-19 00:00:00.000000000 Z
12
+ date: 2013-02-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sprockets
@@ -27,38 +27,6 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
- - !ruby/object:Gem::Dependency
31
- name: opal-spec
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ~>
36
- - !ruby/object:Gem::Version
37
- version: 0.2.10
38
- type: :development
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- version: 0.2.10
46
- - !ruby/object:Gem::Dependency
47
- name: racc
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
30
  description: Ruby runtime and core library for javascript.
63
31
  email: adam.beynon@gmail.com
64
32
  executables:
@@ -188,9 +156,6 @@ files:
188
156
  - spec/core/class/instance_methods_spec.rb
189
157
  - spec/core/class/last_value_spec.rb
190
158
  - spec/core/class/new_spec.rb
191
- - spec/core/date/new_spec.rb
192
- - spec/core/date/to_s_spec.rb
193
- - spec/core/date/today_spec.rb
194
159
  - spec/core/enumerable/all_spec.rb
195
160
  - spec/core/enumerable/any_spec.rb
196
161
  - spec/core/enumerable/collect_spec.rb
@@ -407,6 +372,8 @@ files:
407
372
  - spec/core/time/now_spec.rb
408
373
  - spec/core/time/saturday_spec.rb
409
374
  - spec/core_ext/array/to_json_spec.rb
375
+ - spec/core_ext/class/_inherited_spec.rb
376
+ - spec/core_ext/class/singleton_methods_spec.rb
410
377
  - spec/core_ext/method_missing_spec.rb
411
378
  - spec/core_ext/native/fixtures/classes.rb
412
379
  - spec/core_ext/native/initialize_spec.rb
@@ -463,6 +430,7 @@ files:
463
430
  - spec/language/block_spec.rb
464
431
  - spec/language/break_spec.rb
465
432
  - spec/language/case_spec.rb
433
+ - spec/language/def_spec.rb
466
434
  - spec/language/defined_spec.rb
467
435
  - spec/language/ensure_spec.rb
468
436
  - spec/language/fixtures/next.rb
@@ -488,6 +456,9 @@ files:
488
456
  - spec/language/variables_spec.rb
489
457
  - spec/language/while_spec.rb
490
458
  - spec/language/yield_spec.rb
459
+ - spec/library/date/new_spec.rb
460
+ - spec/library/date/to_s_spec.rb
461
+ - spec/library/date/today_spec.rb
491
462
  - spec/spec_helper.rb
492
463
  homepage: http://opalrb.org
493
464
  licenses: []
@@ -590,9 +561,6 @@ test_files:
590
561
  - spec/core/class/instance_methods_spec.rb
591
562
  - spec/core/class/last_value_spec.rb
592
563
  - spec/core/class/new_spec.rb
593
- - spec/core/date/new_spec.rb
594
- - spec/core/date/to_s_spec.rb
595
- - spec/core/date/today_spec.rb
596
564
  - spec/core/enumerable/all_spec.rb
597
565
  - spec/core/enumerable/any_spec.rb
598
566
  - spec/core/enumerable/collect_spec.rb
@@ -809,6 +777,8 @@ test_files:
809
777
  - spec/core/time/now_spec.rb
810
778
  - spec/core/time/saturday_spec.rb
811
779
  - spec/core_ext/array/to_json_spec.rb
780
+ - spec/core_ext/class/_inherited_spec.rb
781
+ - spec/core_ext/class/singleton_methods_spec.rb
812
782
  - spec/core_ext/method_missing_spec.rb
813
783
  - spec/core_ext/native/fixtures/classes.rb
814
784
  - spec/core_ext/native/initialize_spec.rb
@@ -865,6 +835,7 @@ test_files:
865
835
  - spec/language/block_spec.rb
866
836
  - spec/language/break_spec.rb
867
837
  - spec/language/case_spec.rb
838
+ - spec/language/def_spec.rb
868
839
  - spec/language/defined_spec.rb
869
840
  - spec/language/ensure_spec.rb
870
841
  - spec/language/fixtures/next.rb
@@ -890,4 +861,7 @@ test_files:
890
861
  - spec/language/variables_spec.rb
891
862
  - spec/language/while_spec.rb
892
863
  - spec/language/yield_spec.rb
864
+ - spec/library/date/new_spec.rb
865
+ - spec/library/date/to_s_spec.rb
866
+ - spec/library/date/today_spec.rb
893
867
  - spec/spec_helper.rb