Skip to content

Commit

Permalink
Add CallNode#add_special to make it easier to register special methods
Browse files Browse the repository at this point in the history
  • Loading branch information
adambeynon committed Oct 26, 2013
1 parent d453167 commit 0c883ef
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 12 deletions.
30 changes: 22 additions & 8 deletions lib/opal/nodes/call.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'set'
require 'opal/nodes/base'

module Opal
Expand All @@ -7,9 +8,16 @@ class CallNode < Base

children :recvr, :meth, :arglist, :iter

SPECIALS = Set.new

def self.add_special(name, &handler)
SPECIALS << name
define_method("handle_#{name}", &handler)
end

def compile
# if we handle this call specially, just do that and return early
return if self.handle_special_call
return if self.handle_special

compiler.method_calls << meth.to_sym

Expand Down Expand Up @@ -82,40 +90,46 @@ def using_irb?
# Handle "special" method calls, e.g. require(). Subclasses can override
# this method. If this method returns nil, then the method will continue
# to be generated by CallNode.
def handle_special_call
if respond_to? "handle_#{meth}"
def handle_special
if SPECIALS.include? meth
push __send__("handle_#{meth}")
return true
end
end

def handle_require
add_special :require do
str = DependencyResolver.new(compiler, arglist[1]).resolve
compiler.requires << str unless str.nil?
fragment ''
end

def handle_autoload
add_special :autoload do
if scope.class_scope?
str = DependencyResolver.new(compiler, arglist[2]).resolve
compiler.requires << str unless str.nil?
fragment ''
end
end

def handle_block_given?
add_special :block_given? do
compiler.handle_block_given_call @sexp
end

def handle___callee__
add_special :__callee__ do
if scope.def?
fragment scope.mid.to_s.inspect
else
fragment 'nil'
end
end

alias handle___method__ handle___callee__
add_special :__method__ do
if scope.def?
fragment scope.mid.to_s.inspect
else
fragment 'nil'
end
end

class DependencyResolver
def initialize(compiler, sexp)
Expand Down
6 changes: 2 additions & 4 deletions tasks/mspec.rake
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ require 'opal-sprockets'
# do this at the top level). We figure out which file we are including, and
# add it to our require list
class Opal::Nodes::CallNode
alias_method :mspec_handle_special, :handle_special_call

def handle_special_call
add_special :language_version do
if meth == :language_version and scope.top?
lang_type = arglist[2][1]
target = "rubyspec/language/versions/#{lang_type}_1.9"
Expand All @@ -21,7 +19,7 @@ class Opal::Nodes::CallNode
return fragment("nil")
end

mspec_handle_special
nil
end
end

Expand Down

0 comments on commit 0c883ef

Please sign in to comment.