[macruby-changes] [4631] DietRB/trunk

source_changes at macosforge.org source_changes at macosforge.org
Fri Oct 8 03:51:22 PDT 2010


Revision: 4631
          http://trac.macosforge.org/projects/ruby/changeset/4631
Author:   eloy.de.enige at gmail.com
Date:     2010-10-08 03:51:20 -0700 (Fri, 08 Oct 2010)
Log Message:
-----------
Match local variables, global variables, constants, and top level constants and return all methods of the object.

From: Eloy Duran <eloy.de.enige at gmail.com>

Modified Paths:
--------------
    DietRB/trunk/lib/irb/context.rb
    DietRB/trunk/lib/irb/ext/completion.rb
    DietRB/trunk/spec/completion_spec.rb
    DietRB/trunk/spec/context_spec.rb

Modified: DietRB/trunk/lib/irb/context.rb
===================================================================
--- DietRB/trunk/lib/irb/context.rb	2010-10-08 10:51:10 UTC (rev 4630)
+++ DietRB/trunk/lib/irb/context.rb	2010-10-08 10:51:20 UTC (rev 4631)
@@ -22,8 +22,12 @@
       clear_buffer
     end
     
+    def __evaluate__(source)
+      eval(source, @binding)
+    end
+    
     def evaluate(source)
-      result = eval("_ = (#{source})", @binding)
+      result = __evaluate__("_ = (#{source})")
       puts format_result(result)
       result
     rescue Exception => e

Modified: DietRB/trunk/lib/irb/ext/completion.rb
===================================================================
--- DietRB/trunk/lib/irb/ext/completion.rb	2010-10-08 10:51:10 UTC (rev 4630)
+++ DietRB/trunk/lib/irb/ext/completion.rb	2010-10-08 10:51:20 UTC (rev 4631)
@@ -2,16 +2,32 @@
 
 module IRB
   class Completion
+    # Returns an array of possible completion results, with the current
+    # IRB::Context.
+    #
+    # This is meant to be used with Readline which takes a completion proc.
     def self.call(source)
-      new(source).results
+      new(IRB::Context.current, source).results
     end
     
-    attr_reader :source
+    attr_reader :context, :source
     
-    def initialize(source)
-      @source = source
+    def initialize(context, source)
+      @context, @source = context, source
     end
     
+    def evaluate(s)
+      @context.__evaluate__(s)
+    end
+    
+    def local_variables
+      evaluate('local_variables').map(&:to_s)
+    end
+    
+    def constants
+      evaluate('self.class.constants').map(&:to_s)
+    end
+    
     def results
       src = @source
       
@@ -27,6 +43,22 @@
       #                                        ^
       sub = results[1][2]
       klass = case sub[0]
+      when :var_ref
+        type = sub[1][0]
+        name = sub[1][1]
+        if type == :@ident && local_variables.include?(name)
+          return evaluate(name).methods.map(&:to_s)
+        elsif type == :@const && constants.include?(name)
+          return evaluate(name).methods.map(&:to_s)
+        elsif type == :@gvar && global_variables.include?(name.to_sym)
+          return eval(name).methods.map(&:to_s)
+        end
+      when :top_const_ref
+        type = sub[1][0]
+        name = sub[1][1]
+        if type == :@const && Object.constants.include?(name.to_sym)
+          return evaluate("::#{name}").methods.map(&:to_s)
+        end
       when :regexp_literal then Regexp
       when :array, :words_add, :qwords_add then Array
       when :lambda then Proc
@@ -36,7 +68,7 @@
       when :dot2, :dot3 then Range
       when :@int then Fixnum
       when :@float then Float
-      when :unary then
+      when :unary
         # [:program, [:stmts_add, [:stmts_new], [:unary, :-@, [x, …]]]]
         #                                                      ^
         case sub[2][0]
@@ -45,7 +77,7 @@
         end
       end
       
-      klass.instance_methods.map(&:to_s)
+      klass.instance_methods.map(&:to_s) if klass
     end
   end
 end

Modified: DietRB/trunk/spec/completion_spec.rb
===================================================================
--- DietRB/trunk/spec/completion_spec.rb	2010-10-08 10:51:10 UTC (rev 4630)
+++ DietRB/trunk/spec/completion_spec.rb	2010-10-08 10:51:20 UTC (rev 4631)
@@ -3,12 +3,16 @@
 
 module CompletionHelper
   def complete(str)
-    IRB::Completion.new(str).results
+    IRB::Completion.new(@context, str).results
   end
   
   def imethods(klass)
     klass.instance_methods.map(&:to_s)
   end
+  
+  def methods(object)
+    object.methods.map(&:to_s)
+  end
 end
 
 describe "IRB::Completion" do
@@ -19,109 +23,155 @@
   end
 end
 
-
-describe "IRB::Completion, returns all instance methods if the source ends with a period and" do
-  extend CompletionHelper
-  
-  it "matches a Regexp literal" do
-    complete('//.').should == imethods(Regexp)
-    complete('/^(:[^:.]+)\.([^.]*)$/.').should == imethods(Regexp)
-    complete('/^(#{oops})\.([^.]*)$/.').should == imethods(Regexp)
-    complete('%r{/foo/.*/bar}.').should == imethods(Regexp)
+class CompletionStub
+  def self.a_cmethod
   end
   
-  it "matches an Array literal" do
-    complete('[].').should == imethods(Array)
-    complete('[:ok, {}, "foo",].').should == imethods(Array)
-    complete('[*foo].').should == imethods(Array)
-    complete('%w{foo}.').should == imethods(Array)
-    complete('%W{#{:foo}}.').should == imethods(Array)
+  def an_imethod
   end
+end
+
+class Playground
+  CompletionStub = Object.new
+  def CompletionStub.singleton_method; end
   
-  # fails on MacRuby
-  it "matches a lambda literal" do
-    complete('->{}.').should == imethods(Proc)
-    complete('->{x=:ok}.').should == imethods(Proc)
-    complete('->(x){x=:ok}.').should == imethods(Proc)
+  def a_local_method; end
+end
+
+$a_completion_stub = CompletionStub.new
+
+describe "IRB::Completion, when the source ends with a period, " do
+  describe "returns all public methods of the object that" do
+    extend CompletionHelper
+    
+    before do
+      @context = IRB::Context.new(Playground.new)
+    end
+    
+    it "matches as a local variable" do
+      @context.__evaluate__('foo = ::CompletionStub.new')
+      complete('foo.').should == imethods(::CompletionStub)
+      
+      @context.__evaluate__('def foo.singleton_method; end')
+      complete('foo.').should.include('singleton_method')
+    end
+    
+    it "matches as a global variable" do
+      complete('$a_completion_stub.').should == imethods(::CompletionStub)
+    end
+    
+    it "matches as a local constant" do
+      complete('CompletionStub.').should == methods(Playground::CompletionStub)
+    end
+    
+    it "matches as a top level constant" do
+      complete('::CompletionStub.').should == methods(::CompletionStub)
+    end
   end
   
-  it "matches a Hash literal" do
-    complete('{}.').should == imethods(Hash)
-    complete('{:foo=>:bar,}.').should == imethods(Hash)
-    complete('{foo:"bar"}.').should == imethods(Hash)
+  describe "returns all public instance methods of the class that" do
+    extend CompletionHelper
+    
+    it "matches as a Regexp literal" do
+      complete('//.').should == imethods(Regexp)
+      complete('/^(:[^:.]+)\.([^.]*)$/.').should == imethods(Regexp)
+      complete('/^(#{oops})\.([^.]*)$/.').should == imethods(Regexp)
+      complete('%r{/foo/.*/bar}.').should == imethods(Regexp)
+    end
+    
+    it "matches as an Array literal" do
+      complete('[].').should == imethods(Array)
+      complete('[:ok, {}, "foo",].').should == imethods(Array)
+      complete('[*foo].').should == imethods(Array)
+      complete('%w{foo}.').should == imethods(Array)
+      complete('%W{#{:foo}}.').should == imethods(Array)
+    end
+    
+    # fails on MacRuby
+    it "matches as a lambda literal" do
+      complete('->{}.').should == imethods(Proc)
+      complete('->{x=:ok}.').should == imethods(Proc)
+      complete('->(x){x=:ok}.').should == imethods(Proc)
+    end
+    
+    it "matches as a Hash literal" do
+      complete('{}.').should == imethods(Hash)
+      complete('{:foo=>:bar,}.').should == imethods(Hash)
+      complete('{foo:"bar"}.').should == imethods(Hash)
+    end
+    
+    it "matches as a Symbol literal" do
+      complete(':foo.').should == imethods(Symbol)
+      complete(':"foo.bar".').should == imethods(Symbol)
+      complete(':"foo.#{"bar"}".').should == imethods(Symbol)
+      complete(':\'foo.#{"bar"}\'.').should == imethods(Symbol)
+      complete('%s{foo.bar}.').should == imethods(Symbol)
+    end
+    
+    it "matches as a String literal" do
+      complete("'foo\\'bar'.").should == imethods(String)
+      complete('"foo\"bar".').should == imethods(String)
+      complete('"foo#{"bar"}".').should == imethods(String)
+      complete('%{foobar}.').should == imethods(String)
+      complete('%q{foo#{:bar}}.').should == imethods(String)
+      complete('%Q{foo#{:bar}}.').should == imethods(String)
+    end
+    
+    it "matches as a Range literal" do
+      complete('1..10.').should == imethods(Range)
+      complete('1...10.').should == imethods(Range)
+      complete('"a".."z".').should == imethods(Range)
+      complete('"a"..."z".').should == imethods(Range)
+    end
+    
+    it "matches as a Fixnum literal" do
+      complete('42.').should == imethods(Fixnum)
+      complete('+42.').should == imethods(Fixnum)
+      complete('-42.').should == imethods(Fixnum)
+      complete('42_000.').should == imethods(Fixnum)
+    end
+    
+    it "matches as a Bignum literal as a Fixnum" do
+      complete('100_000_000_000_000_000_000.').should == imethods(Fixnum)
+      complete('-100_000_000_000_000_000_000.').should == imethods(Fixnum)
+      complete('+100_000_000_000_000_000_000.').should == imethods(Fixnum)
+    end
+    
+    it "matches as a Float with exponential literal" do
+      complete('1.2e-3.').should == imethods(Float)
+      complete('+1.2e-3.').should == imethods(Float)
+      complete('-1.2e-3.').should == imethods(Float)
+    end
+    
+    it "matches as a hex literal as a Fixnum" do
+      complete('0xffff').should == imethods(Fixnum)
+      complete('+0xffff').should == imethods(Fixnum)
+      complete('-0xffff').should == imethods(Fixnum)
+    end
+    
+    it "matches as a binary literal as a Fixnum" do
+      complete('0b01011').should == imethods(Fixnum)
+      complete('-0b01011').should == imethods(Fixnum)
+      complete('+0b01011').should == imethods(Fixnum)
+    end
+    
+    it "matches as an octal literal as a Fixnum" do
+      complete('0377').should == imethods(Fixnum)
+      complete('-0377').should == imethods(Fixnum)
+      complete('+0377').should == imethods(Fixnum)
+    end
+    
+    it "matches as a Float literal" do
+      complete('42.0.').should == imethods(Float)
+      complete('-42.0.').should == imethods(Float)
+      complete('+42.0.').should == imethods(Float)
+      complete('42_000.0.').should == imethods(Float)
+    end
+    
+    it "matches as a Bignum float literal as a Float" do
+      complete('100_000_000_000_000_000_000.0.').should == imethods(Float)
+      complete('+100_000_000_000_000_000_000.0.').should == imethods(Float)
+      complete('-100_000_000_000_000_000_000.0.').should == imethods(Float)
+    end
   end
-  
-  it "matches a Symbol literal" do
-    complete(':foo.').should == imethods(Symbol)
-    complete(':"foo.bar".').should == imethods(Symbol)
-    complete(':"foo.#{"bar"}".').should == imethods(Symbol)
-    complete(':\'foo.#{"bar"}\'.').should == imethods(Symbol)
-    complete('%s{foo.bar}.').should == imethods(Symbol)
-  end
-  
-  it "matches a String literal" do
-    complete("'foo\\'bar'.").should == imethods(String)
-    complete('"foo\"bar".').should == imethods(String)
-    complete('"foo#{"bar"}".').should == imethods(String)
-    complete('%{foobar}.').should == imethods(String)
-    complete('%q{foo#{:bar}}.').should == imethods(String)
-    complete('%Q{foo#{:bar}}.').should == imethods(String)
-  end
-  
-  it "matches a Range literal" do
-    complete('1..10.').should == imethods(Range)
-    complete('1...10.').should == imethods(Range)
-    complete('"a".."z".').should == imethods(Range)
-    complete('"a"..."z".').should == imethods(Range)
-  end
-  
-  it "matches a Fixnum literal" do
-    complete('42.').should == imethods(Fixnum)
-    complete('+42.').should == imethods(Fixnum)
-    complete('-42.').should == imethods(Fixnum)
-    complete('42_000.').should == imethods(Fixnum)
-  end
-  
-  it "matches a Bignum literal as a Fixnum" do
-    complete('100_000_000_000_000_000_000.').should == imethods(Fixnum)
-    complete('-100_000_000_000_000_000_000.').should == imethods(Fixnum)
-    complete('+100_000_000_000_000_000_000.').should == imethods(Fixnum)
-  end
-  
-  it "matches a Float with exponential literal" do
-    complete('1.2e-3.').should == imethods(Float)
-    complete('+1.2e-3.').should == imethods(Float)
-    complete('-1.2e-3.').should == imethods(Float)
-  end
-  
-  it "matches a hex literal as a Fixnum" do
-    complete('0xffff').should == imethods(Fixnum)
-    complete('+0xffff').should == imethods(Fixnum)
-    complete('-0xffff').should == imethods(Fixnum)
-  end
-  
-  it "matches a binary literal as a Fixnum" do
-    complete('0b01011').should == imethods(Fixnum)
-    complete('-0b01011').should == imethods(Fixnum)
-    complete('+0b01011').should == imethods(Fixnum)
-  end
-  
-  it "matches an octal literal as a Fixnum" do
-    complete('0377').should == imethods(Fixnum)
-    complete('-0377').should == imethods(Fixnum)
-    complete('+0377').should == imethods(Fixnum)
-  end
-  
-  it "matches a Float literal" do
-    complete('42.0.').should == imethods(Float)
-    complete('-42.0.').should == imethods(Float)
-    complete('+42.0.').should == imethods(Float)
-    complete('42_000.0.').should == imethods(Float)
-  end
-  
-  it "matches a Bignum float literal as a Float" do
-    complete('100_000_000_000_000_000_000.0.').should == imethods(Float)
-    complete('+100_000_000_000_000_000_000.0.').should == imethods(Float)
-    complete('-100_000_000_000_000_000_000.0.').should == imethods(Float)
-  end
 end
\ No newline at end of file

Modified: DietRB/trunk/spec/context_spec.rb
===================================================================
--- DietRB/trunk/spec/context_spec.rb	2010-10-08 10:51:10 UTC (rev 4630)
+++ DietRB/trunk/spec/context_spec.rb	2010-10-08 10:51:20 UTC (rev 4631)
@@ -77,7 +77,7 @@
   end
   
   it "evaluates code with the object's binding" do
-    @context.evaluate("self").should == main
+    @context.__evaluate__("self").should == main
   end
   
   it "prints the result" do
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20101008/4b487bbb/attachment-0001.html>


More information about the macruby-changes mailing list