lib/ruby_less/processor.rb in rubyless-0.8.0 vs lib/ruby_less/processor.rb in rubyless-0.8.1

- old
+ new

@@ -117,11 +117,11 @@ end list << res end res.opts[:class] = Array - res.opts[:array_content_class] = content_class + res.opts[:elem] = content_class t "[#{list * ','}]", res.opts.merge(:literal => nil) end # Is this used ? def process_vcall(exp) @@ -227,21 +227,30 @@ args = nil signature = [method] cond = [] end + opts = get_method(receiver, signature) + + # method type can rewrite receiver + if opts[:receiver] + if receiver + receiver = "#{receiver}.#{opts[:receiver]}" + else + receiver = opts[:receiver] + end + end + if receiver - opts = get_method(receiver, signature) method_call_with_receiver(receiver, args, opts, cond, signature) else - opts = get_method(nil, signature) method = opts[:method] args = args_with_prepend(args, opts) if (proc = opts[:pre_processor]) && !args.list.detect {|a| !a.literal} if proc.kind_of?(Proc) - res = proc.call(*args.list.map(&:literal)) + res = proc.call(*([receiver] + args.list.map(&:literal))) else res = @helper.send(proc, *args.list.map(&:literal)) end return res.kind_of?(TypedString) ? res : t(res.inspect, :class => String, :literal => res) @@ -278,17 +287,31 @@ if receiver.could_be_nil? && !(opts == SafeClass.safe_method_type_for(NilClass, signature) && receiver.cond == [receiver]) # Do not add a condition if the method applies on nil cond += receiver.cond - elsif receiver.literal && (proc = opts[:pre_processor]) && !arg_list.detect {|a| !a.literal} + if (proc = opts[:pre_processor]) && !arg_list.detect {|a| !a.literal} + # pre-processor on element that can be nil + if proc.kind_of?(Proc) + res = proc.call([receiver] + arg_list.map(&:literal)) + return t_if cond, res, res.opts + end + end + elsif (proc = opts[:pre_processor]) && !arg_list.detect {|a| !a.literal} if proc.kind_of?(Proc) - res = proc.call([receiver.literal] + arg_list.map(&:literal)) - else + res = proc.call([receiver] + arg_list.map(&:literal)) + elsif receiver.literal res = receiver.literal.send(*([method] + arg_list.map(&:literal))) end - return res.kind_of?(TypedString) ? res : t(res.inspect, :class => String, :literal => res) + if res + if res.opts.nil? + # This can happen if we use native methods on TypedString (like gsub) that return a new + # typedstring without calling initialize.... + res.instance_variable_set(:@opts, :class => String, :literal => res) + end + return res.kind_of?(TypedString) ? res : t(res.inspect, :class => String, :literal => res) + end end if method == '/' t_if cond, "(#{receiver.raw}#{method}#{args.raw} rescue nil)", opts.merge(:nil => true) elsif INFIX_OPERATOR.include?(method) @@ -332,10 +355,10 @@ if type.nil? # We try to match with the superclass of the arguments end raise RubyLess::NoMethodError.new(receiver, klass, signature) if !type || type[:class].kind_of?(Symbol) # we cannot send: no object. - type[:class].kind_of?(Proc) ? type[:class].call(@helper, signature) : type + type[:class].kind_of?(Proc) ? type[:class].call(@helper, receiver ? receiver.klass : @helper, signature) : type end def get_lit_class(lit) unless lit_class = RubyLess::SafeClass.literal_class_for(lit.class) raise RubyLess::SyntaxError.new("#{klass} literal not supported by RubyLess.")