Skip to content

Commit

Permalink
Fix super() when used inside a block - to support define_method and n…
Browse files Browse the repository at this point in the history
…ormal iters
  • Loading branch information
adambeynon committed Oct 19, 2013
1 parent fd375dd commit 89a7499
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 10 deletions.
4 changes: 2 additions & 2 deletions corelib/kernel.rb
Expand Up @@ -87,9 +87,9 @@ def define_singleton_method(name, &body)
}
var jsid = '$' + name;
body._jsid = jsid;
body._sup = #{self}[jsid];
body._jsid = name;
body._s = null;
body._def = body;
#{self.singleton_class}._proto[jsid] = body;
Expand Down
7 changes: 3 additions & 4 deletions corelib/module.rb
Expand Up @@ -280,9 +280,9 @@ def define_method(name, method = undefined, &block)
}
var jsid = '$' + name;
block._jsid = jsid;
block._sup = #{self}._proto[jsid];
block._jsid = name;
block._s = null;
block._def = block;
#{self}._proto[jsid] = block;
$opal.donate(#{self}, [jsid]);
Expand All @@ -295,8 +295,7 @@ def remove_method(name)
%x{
var jsid = '$' + name;
var current = #{self}._proto[jsid];
var _sup = current._sup;
#{self}._proto[jsid] = _sup;
delete #{self}._proto[jsid];
// Check if we need to reverse $opal.donate
// $opal.retire(#{self}, [jsid]);
Expand Down
10 changes: 10 additions & 0 deletions corelib/runtime.js
Expand Up @@ -473,6 +473,16 @@
return dispatcher;
};

// Iter dispatcher for super in a block
Opal.find_iter_super_dispatcher = function(obj, jsid, current_func, iter, defs) {
if (current_func._def) {
return Opal.find_super_dispatcher(obj, current_func._jsid, current_func, iter, defs);
}
else {
return Opal.find_super_dispatcher(obj, jsid, current_func, iter, defs);
}
};

var find_obj_super_dispatcher = function(obj, jsid, current_func) {
var klass = obj.__meta__ || obj._klass;

Expand Down
6 changes: 3 additions & 3 deletions lib/opal/parser.rb
Expand Up @@ -2097,9 +2097,9 @@ def process_super(sexp, level, skip_call=false)
_super

elsif @scope.type == :iter
chain, _, mid = @scope.get_super_chain
trys = chain.map { |c| "#{c}._sup" }.join ' || '
super_method = "#{trys} || self._klass._super._proto[#{mid}]"
chain, cur_defn, mid = @scope.get_super_chain
trys = chain.map { |c| "#{c}._def" }.join ' || '
super_method = "$opal.find_iter_super_dispatcher(self, #{mid}, (#{trys} || #{cur_defn}), null)"
skip_call ? [f("(#{super_method})")] :
[f("(#{super_method}).apply(self, ", sexp), args, f(")", sexp)]
else
Expand Down
2 changes: 1 addition & 1 deletion lib/opal/target_scope.rb
Expand Up @@ -262,7 +262,7 @@ def get_super_chain

elsif scope.type == :def
defn = scope.identify!
mid = "'$#{scope.mid}'"
mid = "'#{scope.mid}'"
break

else
Expand Down
4 changes: 4 additions & 0 deletions spec/filters/bugs/language.rb
Expand Up @@ -365,4 +365,8 @@
fails "The defined? keyword for super for a method taking arguments returns nil when no superclass method exists"
fails "The defined? keyword for super for a method taking arguments returns nil from a block when no superclass method exists"

fails "The defined? keyword for super for a method taking no arguments returns nil from a #define_method when no superclass method exists"
fails "The defined? keyword for super for a method taking no arguments returns nil from a block in a #define_method when no superclass method exists"
fails "The defined? keyword for super for a method taking arguments returns nil from a #define_method when no superclass method exists"
fails "The defined? keyword for super for a method taking arguments returns nil from a block in a #define_method when no superclass method exists"
end

0 comments on commit 89a7499

Please sign in to comment.