diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..e2512c3 Binary files /dev/null and b/.DS_Store differ diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..962f370 --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' +ruby '2.0.0' + +gem 'pry-byebug' \ No newline at end of file diff --git a/data/stopwords.txt b/data/stopwords.txt index 7336c7c..effee63 100644 --- a/data/stopwords.txt +++ b/data/stopwords.txt @@ -1 +1 @@ -a,able,about,across,after,all,almost,also,am,among,an,and,any,are,as,at,be,because,been,but,by,can,cannot,could,dear,did,do,does,either,else,ever,every,for,from,get,got,had,has,have,he,her,hers,him,his,how,however,i,if,in,into,is,it,its,just,least,let,like,likely,may,me,might,most,must,my,neither,no,nor,not,of,off,often,on,only,or,other,our,own,rather,said,say,says,she,should,since,so,some,than,that,the,their,them,then,there,these,they,this,tis,to,too,twas,us,wants,was,we,were,what,when,where,which,while,who,whom,why,will,with,would,yet,you,your,one,out,more,now,first,two,very,such,same,shall,upon,before,therefore,great,made,even,same,work,make,being,through,here,way,true,see,time,those,place,much,without,body,whole,another,thus,set,new,given,both,above,well,part,between,end,order,each,form,gutenberg +a,able,about,across,after,all,almost,also,am,among,an,and,any,are,as,at,be,because,been,but,by,can,cannot,could,dear,did,do,does,either,else,ever,every,for,from,get,got,had,has,have,he,her,hers,him,his,how,however,i,if,in,into,is,it,its,just,least,let,like,likely,may,me,might,most,must,my,neither,no,nor,not,of,off,often,on,only,or,other,our,own,rather,said,say,says,she,should,since,so,some,than,that,the,their,them,then,there,these,they,this,tis,to,too,twas,us,wants,was,we,were,what,when,where,which,while,who,whom,why,will,with,would,yet,you,your,one,out,more,now,first,two,very,such,same,shall,upon,before,therefore,great,made,even,same,work,make,being,through,here,way,true,see,time,those,place,much,without,body,whole,another,thus,set,new,given,both,above,well,part,between,end,order,each,form,gutenberg, diff --git a/gutenberg.rb b/gutenberg.rb index 84d20f6..f064355 100644 --- a/gutenberg.rb +++ b/gutenberg.rb @@ -1,6 +1,7 @@ require_relative 'lib/simple_predictor' require_relative 'lib/complex_predictor' + def run!(predictor_klass, opts={}) puts "+----------------------------------------------------+" puts "| #{predictor_klass}#{" " * (51 - predictor_klass.to_s.size)}|" diff --git a/lib/complex_predictor.rb b/lib/complex_predictor.rb index b8921f3..1ab86ee 100644 --- a/lib/complex_predictor.rb +++ b/lib/complex_predictor.rb @@ -1,12 +1,37 @@ require_relative 'predictor' +require 'pry-byebug' class ComplexPredictor < Predictor # Public: Trains the predictor on books in our dataset. This method is called # before the predict() method is called. # # Returns nothing. + def train! + # iterates through all the words for each category, and creates a hash that has + # each word as a key, and the value is the number of times it appears. + @data = {} + @temp_data = {} + + @all_books.each do |category, books| + @data[category] = {} + @temp_data[category] = {} + books.each do |filename, tokens| + tokens.each do |token| + if good_token?(token) + @data[category][token] ||= 1 + @data[category][token] += 1 + end + end + @data_array = @data[category].sort_by {|k,v| v}.reverse + limit = @data_array[100].last + @data[category].keep_if do |key, value| + value > limit + end + end + end + end # Public: Predicts category. @@ -15,8 +40,33 @@ def train! # # Returns a category. def predict(tokens) - # Always predict astronomy, for now. - :astronomy + + input_words = {} + match_words = {} + +# put good tokens in an input_words hash with their counts + tokens.each do |token| + if good_token?(token) + input_words[token] ||= 1 + input_words[token] += 1 + end + end + +# find words in the input_words hash that match words from the @data hash and +# create match_words hash that counts total number of words from each category + @data.each do |category, word_hash| + word_hash.each do |word, count| + if input_words.has_key?(word) + match_words[category] ||= 1 + match_words[category] += input_words[word] + end + end + end + +#return category with highest number of matches + return match_words.max_by{|k,v| v}.first + end + end diff --git a/vendor/bundle/bin/byebug b/vendor/bundle/bin/byebug new file mode 100755 index 0000000..785cd12 --- /dev/null +++ b/vendor/bundle/bin/byebug @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'byebug' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ + version = $1 + ARGV.shift + end +end + +gem 'byebug', version +load Gem.bin_path('byebug', 'byebug', version) diff --git a/vendor/bundle/bin/coderay b/vendor/bundle/bin/coderay new file mode 100755 index 0000000..d6d76cb --- /dev/null +++ b/vendor/bundle/bin/coderay @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'coderay' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ + version = $1 + ARGV.shift + end +end + +gem 'coderay', version +load Gem.bin_path('coderay', 'coderay', version) diff --git a/vendor/bundle/bin/pry b/vendor/bundle/bin/pry new file mode 100755 index 0000000..d26856b --- /dev/null +++ b/vendor/bundle/bin/pry @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'pry' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ + version = $1 + ARGV.shift + end +end + +gem 'pry', version +load Gem.bin_path('pry', 'pry', version) diff --git a/vendor/bundle/build_info/byebug-2.7.0.info b/vendor/bundle/build_info/byebug-2.7.0.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/byebug-2.7.0.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/coderay-1.1.0.info b/vendor/bundle/build_info/coderay-1.1.0.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/coderay-1.1.0.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/columnize-0.8.9.info b/vendor/bundle/build_info/columnize-0.8.9.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/columnize-0.8.9.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/debugger-linecache-1.2.0.info b/vendor/bundle/build_info/debugger-linecache-1.2.0.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/debugger-linecache-1.2.0.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/method_source-0.8.2.info b/vendor/bundle/build_info/method_source-0.8.2.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/method_source-0.8.2.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/pry-0.10.0.info b/vendor/bundle/build_info/pry-0.10.0.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/pry-0.10.0.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/pry-byebug-1.3.3.info b/vendor/bundle/build_info/pry-byebug-1.3.3.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/pry-byebug-1.3.3.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/slop-3.6.0.info b/vendor/bundle/build_info/slop-3.6.0.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/slop-3.6.0.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/gems/byebug-2.7.0/.gitignore b/vendor/bundle/gems/byebug-2.7.0/.gitignore new file mode 100644 index 0000000..c7d47ea --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/.gitignore @@ -0,0 +1,18 @@ +tmp +pkg +doc + +.rvmrc +.ruby-version +.ruby-gemset +.gdbinit +.gdb_history +.bundle +.tags +.ackrc +.jrubyrc + +Gemfile.lock + +lib/byebug/byebug.so +lib/byebug/byebug.bundle diff --git a/vendor/bundle/gems/byebug-2.7.0/.travis.yml b/vendor/bundle/gems/byebug-2.7.0/.travis.yml new file mode 100644 index 0000000..23a32c8 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/.travis.yml @@ -0,0 +1,8 @@ +before_script: bundle exec rake compile +rvm: +- 2.0.0 +- 2.1.0 +- ruby-head +matrix: + allow_failures: + - rvm: ruby-head diff --git a/vendor/bundle/gems/byebug-2.7.0/CHANGELOG.md b/vendor/bundle/gems/byebug-2.7.0/CHANGELOG.md new file mode 100644 index 0000000..796689b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/CHANGELOG.md @@ -0,0 +1,214 @@ +# 2.7.0 +* Bugfix release (#52, #53 and #54) + + +# 2.6.0 + +* Fix circular dependency that was affecting `pry-byebug`, thanks @andreychernih + + +# 2.5.0 + +* Support for `sublime-debugger` + + +# 2.4.1 + +* Fix installation error in Mac OSX (#40), thanks @luislavena + + +# 2.4.0 + +* Use `require` instead of `require_relative` for loading byebug's extension +library (thanks @nobu) +* Adds back `debugger` as an alias to `byebug` (thanks @wallace) +* Adds -R option to byebug's binary to specify server's hostname:port for remote +debugging (thanks @mrkn) +* Fixes `thread list` showing too many threads +* Change in tracing global variables. Use `trace variable foo` instead of `trace +variable $foo` +* Fix setting post mortem mode with `set post_mortem`. Now this is the only +post mortem functionality available as specifying `Byebug.post_mortem` with a +block has been removed in this version. + + +# 2.3.1 + +* Fixes bug preventing users from deleting breakpoints +* Fix broken test suite + + +# 2.3.0 + +* Compatibility with Phusion Passenger Enterprise (thanks @FooBarWidget) +* More minimalist help system + + +# 2.2.2 + +* Fix another compilation issue in 64 bit systems + + +# 2.2.1 + +* Fix compilation issue introduced by 2.2.0 (#26) +* "show" and "set" option `stack_trace_on_error` is now called `stack_on_error` + + +# 2.2.0 + +* Small fixes in stack_size calculations +* Warning free byebug +* Add `verbose` setting for TracePoint API event inspection +* Fix setting `post_mortem` mode +* Allow `edit ` without a line number + + +# 2.1.1 + +* Fix bug when debugging code inside '-e' flag + + +# 2.1.0 + +* Fix bug in remote debugging display +* Fix bug where eval would crash when inspect raised an exception (reported by +@iblue) +* `enable breakpoints` now enables every breakpoint +* `disable breakpoints` now disables every breakpoint + + +# 2.0.0 + +* Various bug fixes +* "Official" definition of a command API +* Thread support + + +## 1.8.2 + +* More user friendly regexps for commands +* Better help for some commands +* `save` command now saves the list of "displays" +* Fixes bug in calculating stacksize + + +## 1.8.1 + +* Bugfix release + + +## 1.8.0 + +* Remote debugging support + + +## 1.7.0 + +* Callstack display: specifically mark c-frames +* Callstack navigation: skip c-frames +* Callstack navigation: autolist after navigation commands + + +## 1.6.1 + +* Windows compatibiliy: compilation and terminal width issues + + +## 1.6.0 + +* `byebug` placed at the end of a block or method call now works as expected +* Don't autolist when ruby '-e' option is used +* Fixes callstyles. From now on, use 'long' for detailed frames in callstack and +'short' for more concise frames + + +## 1.5.0 + +* No more Byebug.start to get correct callstack information! Dropping `byebug` +anywhere and inmediately printing the stack just works now. :) + + +## 1.4.2 + +* Fixes crash when using "help command subcommand" +* Byebug now works with Rails Console debugging flag +* Fix post-mortem mode when running byebug from the outset +* Fix --no-quit flag when running byebug from the outset + + +## 1.4.1 + +* Fixes crash when printing some filenames in backtraces +* Allows byebug developers to easily use compilers different from gcc (thanks +@GarthSnyder!) + + +## 1.4.0 + +* Byebug now uses the Debug Inspector API: faster and nicer! +* Fixes bug that prevents some random crashes + + +## 1.3.1 + +* Byebug now works with Rails debugging flag +* Fix bug which would make byebug crash when trying to print lines of code +containing the character '%' +* Fix bug which prevented basename and linetrace options from working together + + +## 1.3.0 + +* Support colon-delimited include paths in command-line front-end (@ender672) + + +## 1.2.0 + +* Added 'pry' command. +* Ctrl+C during command line editing is handled and works like pry/irb + + +## 1.1.1 + +* Better help system +* Code cleanup +* First version compatible with pry-byebug + + +## 1.1.0 + +* Post-mortem support + + +## 1.0.3 + +* "autoreload" is set by default now +* "list" command: no negative line numbers shown, and line range behaves as +expected at the begining/end of file +* In some weird cases, "backtrace" command segfaults when trying to show info on +some frame args. Don't know the reason yet, but the exception is handled now and +and the command doesn't segfault anymore. +* Try some thread support (not even close to usable) + + +## 1.0.2 + +* "autolist" and "autoeval" are default settings now +* Fixes bug which messed up the call-stack when manipulating backtrace +information and when nexting/stepping + + +## 1.0.1 + +* Corrected small bug preventing byebug from loading + + +## 1.0.0 + +* Green test suite + + +## 0.0.1 + +* Initial release diff --git a/vendor/bundle/gems/byebug-2.7.0/CONTRIBUTING.md b/vendor/bundle/gems/byebug-2.7.0/CONTRIBUTING.md new file mode 100644 index 0000000..e34290b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/CONTRIBUTING.md @@ -0,0 +1,21 @@ +Thanks for your interest in contributing to ByeBug! + +To make your changes, follow this steps: + +* [Fork the project](https://help.github.com/fork-a-repo) +* Create a topic branch - `git checkout -b my_branch` +* Insert awesome code - See below +* Push your branch to your forked repo - `git push origin my_branch` +* [Make a pull request](https://help.github.com/articles/using-pull-requests) + +How to insert awesome code: + +This gem uses `rake-compiler` to build native gems. You can use `rake compile` to build the native gem +and start the tests using `rake test` + +```bash +rake compile +rake test +``` + +It's appreciated if you add tests for new functionality. Thanks! \ No newline at end of file diff --git a/vendor/bundle/gems/byebug-2.7.0/GUIDE.md b/vendor/bundle/gems/byebug-2.7.0/GUIDE.md new file mode 100644 index 0000000..40f425b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/GUIDE.md @@ -0,0 +1,1368 @@ +### First Steps + +A handful of commands are enough to get started using `byebug`. The following +session illustrates these commands. + +``` +$ byebug triangle.rb +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 1: # Compute the n'th triangle number: triangle(n) == (n*(n+1))/2 +=> 2: def triangle(n) + 3: tri = 0 + 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: + 10: t = triangle(3) +(byebug) +``` + +We are currently stopped before the first executable line of the program: line 2 +of `triangle.rb`. If you are used to less dynamic languages and have used +debuggers for more statically compiled languages like C, C++, or Java, it may +seem odd to be stopped before a function definition but in Ruby line 2 is +executed. + +Byebug's prompt is `(byebug)`. If the program has died and you are in +post-mortem debugging, `(byebug:post-mortem)` is used instead. If the program +has terminated normally, the string this position will be `(byebug:ctrl)`. The +commands available change depending on the program's state. + +Byebug automatically lists 10 lines of code centered around the current line +everytime it is stopped. The current line is marked with `=>`, so the range +byebug would like to show is [-3..6]. However since there aren't 5 lines before +the current line, the range is moved _up_ so we can actually display 10 lines +of code. + +Now let us step through the program. + +``` +(byebug) step +[2, 11] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 2: def triangle(n) + 3: tri = 0 + 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: +=> 10: t = triangle(3) + 11: puts t +(byebug) # hit enter +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 1: # Compute the n'th triangle number: triangle(n) == (n*(n+1))/2 + 2: def triangle(n) +=> 3: tri = 0 + 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: + 10: t = triangle(3) +(byebug) p tri +nil +(byebug) step +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 1: # Compute the n'th triangle number: triangle(n) == (n*(n+1))/2 + 2: def triangle(n) + 3: tri = 0 +=> 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: + 10: t = triangle(3) +(byebug) p tri +0 +``` + +The first `step` command runs the script one executable unit. The second command +we entered was just hitting the return key; `byebug` remembers the last command +you entered was `step` and it runs it again. + +One way to print the values of variables is `p` (there are other ways). When we +look at the value of `tri` the first time, we see it is `nil`. Again we are +stopped _before_ the assignment on line 3, and this variable hasn't been set +previously. However after issuing another `step` command we see that the value +is 0 as expected. If every time we stop we want to see the value of `tri` to see +how things are going, there is a better way by setting a display expression: + +``` +(byebug) display tri +1: tri = 0 +``` + +Now let us run the program until we return from the function. We'll want to see +which lines get run, so we turn on _line tracing_. If we don't want whole paths +to be displayed when tracing, we can turn on _basename_. + +``` +(byebug) display i +2: i = +(byebug) set linetrace on +line tracing is on. +(byebug) set basename on +basename is on. +(byebug) finish +Tracing: triangle.rb:5 tri += i +1: tri = 0 +2: i = 0 +Tracing: triangle.rb:5 tri += i +1: tri = 0 +2: i = 1 +Tracing: triangle.rb:5 tri += i +1: tri = 1 +2: i = 2 +Tracing: triangle.rb:5 tri += i +1: tri = 3 +2: i = 3 +Tracing: triangle.rb:7 tri +1: tri = 6 +2: i = +Tracing: triangle.rb:11 puts t +1: tri = +2: i = +[2, 11] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 2: def triangle(n) + 3: tri = 0 + 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: + 10: t = triangle(3) +=> 11: puts t +1: tri = +2: i = +(byebug) quit +Really quit? (y/n) y +``` + +So far, so good. As you can see from the above to get out of `byebug`, one +can issue a `quit` command (`q` and `exit` are just as good). If you want to +quit without being prompted, suffix the command with an exclamation mark, e.g., +`q!`. + + +### Second Sample Session: Delving Deeper + +In this section we'll introduce breakpoints, the call stack and restarting. +Below we will debug a simple Ruby program to solve the classic Towers of Hanoi +puzzle. It is augmented by the bane of programming: some command-parameter +processing with error checking. + +```bash +$ byebug hanoi.rb +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 1: # Solves the classic Towers of Hanoi puzzle. +=> 2: def hanoi(n,a,b,c) + 3: if n-1 > 0 + 4: hanoi(n-1, a, c, b) + 5: end + 6: puts "Move disk %s to %s" % [a, b] + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end +(byebug) +``` + +Recall in the first section iwe said that before the `def` is run, the method it +names is undefined. Let's check that out. First let's see what private methods +we can call before running `def hanoi`. + +```bash +(byebug) private_methods +[:public, :private, :include, :using, :define_method, :default_src_encoding, ... +``` + +`private_methods` is not a byebug command but a Ruby feature. By default, when +byebug doesn't understand a command, it will evaluate it as if it was a Ruby +command. If you don't want this behaviour, you can use `set autoeval off` or +even drop it in your `.byebugrc` file if you want that behaviour permanently. +The output of `private_methods`, thought, is unwieldy for our porpuse: check +whether `hanoi` method is in the list. Fortunately, byebug has nice formatting +features: we can sort the output and put it into columns list using the print +command `ps`. + +```bash +(byebug) ps private_methods +Array debug_program open sprintf +Complex default_src_encoding p srand +DelegateClass define_method pp syscall +Digest eval print system +Float exec printf test +Hash exit private throw +Integer exit! proc trace_var +Pathname fail process_options trap +Rational fork public untrace_var +String format putc using +__callee__ gem puts warn +__dir__ gem_original_require raise whence_file +__method__ gets rand +` global_variables readline +abort include readlines +at_exit initialize require +autoload initialize_clone require_relative +autoload? initialize_copy respond_to_missing? +binding initialize_dup select +block_given? iterator? set_trace_func +caller lambda singleton_method_added +caller_locations load singleton_method_removed +catch local_variables singleton_method_undefined +dbg_print loop sleep +dbg_puts method_missing spawn +(byebug) +``` + +Now let's see what happens after stepping: + +```bash +(byebug) private_methods.member?(:hanoi) +false +(byebug:1) step +[7, 16] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end + 11: +=> 12: i_args=ARGV.length + 13: if i_args > 1 + 14: puts "*** Need number of disks or no parameter" + 15: exit 1 + 16: end +(byebug) private_methods.member?(:hanoi) +true +(byebug) +``` + +Okay, lets go on and talk about program arguments. + +```bash +(byebug) ARGV +[] +``` + +Ooops. We forgot to specify any parameters to this program. Let's try again. We +can use the `restart` command here. + +```bash +(byebug) restart 3 +Re exec'ing: + /home/davidr/.rvm/gems/ruby-2.0.0-p195@byebug/gems/byebug-1.1.1/bin/byebug /home/davidr/Proyectos/byebug/old_doc/hanoi.rb 3 +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 1: # Solves the classic Towers of Hanoi puzzle. +=> 2: def hanoi(n,a,b,c) + 3: if n-1 > 0 + 4: hanoi(n-1, a, c, b) + 5: end + 6: puts "Move disk %s to %s" % [a, b] + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end +(byebug) break 4 +Created breakpoint 1 at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3 +(byebug) continue +Stopped by breakpoint 1 at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3 +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 1: # Solves the classic Towers of Hanoi puzzle. + 2: def hanoi(n,a,b,c) +=> 3: if n-1 > 0 + 4: hanoi(n-1, a, c, b) + 5: end + 6: puts "Move disk %s to %s" % [a, b] + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end +(byebug) display n +1: n = 3 +(byebug) display a +2: a = a +(byebug) undisplay 2 +(byebug) display a.inspect +3: a.inspect = :a +(byebug) display b.inspect +4: b.inspect = :b +(byebug) continue +Stopped by breakpoint 1 at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3 +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 1: # Solves the classic Towers of Hanoi puzzle. + 2: def hanoi(n,a,b,c) +=> 3: if n-1 > 0 + 4: hanoi(n-1, a, c, b) + 5: end + 6: puts "Move disk %s to %s" % [a, b] + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end +1: n = 2 +3: a.inspect = :a +4: b.inspect = :c +(byebug) c +Stopped by breakpoint 1 at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3 +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 1: # Solves the classic Towers of Hanoi puzzle. + 2: def hanoi(n,a,b,c) +=> 3: if n-1 > 0 + 4: hanoi(n-1, a, c, b) + 5: end + 6: puts "Move disk %s to %s" % [a, b] + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end +1: n = 1 +3: a.inspect = :a +4: b.inspect = :b +(byebug) set nofullpath +Displaying frame's full file names is off. +(byebug) where +--> #0 Object.hanoi(n#Fixnum, a#Symbol, b#Symbol, c#Symbol) at .../byebug/old_doc/hanoi.rb:4 + #1 Object.hanoi(n#Fixnum, a#Symbol, b#Symbol, c#Symbol) at .../byebug/old_doc/hanoi.rb:8 + #2 at .../byebug/old_doc/hanoi.rb:34 +(byebug) +``` + +In the above we added new commands: `break` (see [breakpoints]()), which +indicates to stop just before that line of code is run, and `continue`, which +resumes execution. Notice the difference between `display a` and +`display a.inspect`. An implied string conversion is performed on the expression +after it is evaluated. To remove a display expression `undisplay` is used. If we +give a display number, just that display expression is removed. + +We also used a new command `where`(see [backtrace]()) to show the callstack. In +the above situation, starting from the bottom line we see we called the `hanoi` +method from line 34 of the file `hanoi.rb` and the `hanoi` method called itself +two more times at line 4. + +In the callstack we show a _current frame_ mark, the frame number, the method +being called, the names of the parameters, the types those parameters +_currently_ have and the file-line position. Remember it's possible that when +the program was called the parameters had different types, since the types of +variables can change dynamically. You can alter the style of what to show in the +trace (see [callstyle]()). + +Now let's move around the callstack. + +```bash +(byebug) undisplay +Clear all expressions? (y/n) y +(byebug) i_args +NameError Exception: undefined local variable or method `i_args' for main:Object +(byebug) frame -1 +[25, 34] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 25: exit 2 + 26: end + 27: end + 28: + 29: if n < 1 or n > 100 + 30: puts "*** number of disks should be between 1 and 100" + 31: exit 2 + 32: end + 33: +=> 34: hanoi(n, :a, :b, :c) +(byebug) i_args +0 +(byebug) p n +3 +(byebug) down 2 +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 1: # Solves the classic Towers of Hanoi puzzle. + 2: def hanoi(n,a,b,c) + 3: if n-1 > 0 +=> 4: hanoi(n-1, a, c, b) + 5: end + 6: puts "Move disk %s to %s" % [a, b] + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end +(byebug:1) p n +2 +``` + +Notice in the above to get the value of variable `n` we had to use a print +command like `p n`. If we entered just `n`, that would be taken to mean byebug +command `next`. In the current scope, variable `i_args` is not defined. +However I can change to the top-most frame by using the `frame` command. Just as +with arrays, -1 means the last one. Alternatively using frame number 3 would +have been the same thing; so would issuing `up 3`. Note that in the outside +frame #3, the value of `i_args` can be shown. Also note that the value of +variable `n` is different. + + +### Attaching to a running program with `byebug` + +In the previous sessions we've been calling byebug right at the outset, but +there is another mode of operation you might use. If there's a lot of code that +needs to be run before the part you want to inspect, it might not be efficient +or convenient to run byebug from the outset. + +In this section we'll show how to enter the code in the middle of your program, +while delving more into byebug's operation. We will also use unit testing. Using +unit tests will greatly reduce the amount of debugging needed, while at the same +time, will increase the quality of your program. + +What we'll do is take the `triangle` code from the first session and write a +unit test for that. In a sense we did write a tiny test for the program which +was basically the last line where we printed the value of `triangle(3)`. This +test however wasn't automated: the expectation is that someone would look at the +output and verify that what was printed is what was expected. + +Before we can turn that into something that can be `required`, we probably want +to remove that output. However I like to keep in that line so that when I +look at the file, I have an example of how to run it. Therefore we will +conditionally run this line if that file is invoked directly, but skip it if it +is not. _NOTE: `byebug` resets `$0` to try to make things like this work._ + +```ruby +if __FILE__ == $0 + t = triangle(3) + puts t +end +``` + +Okay, we're now ready to write our unit test. We'll use `minitest` which comes +with the standard Ruby distribution. Here's the test code; it should be in the +same directory as `triangle.rb`. + +```ruby +require 'minitest/autorun' +require_relative 'triangle.rb' + +class TestTri < MiniTest::Unit::TestCase + def test_basic + solutions = [] + 0.upto(5) do |i| + solutions << triangle(i) + end + assert_equal([0, 1, 3, 6, 10, 15], solutions, + 'Testing the first 5 triangle numbers') + end +end +``` + +Let's say we want to stop before the first statement in our test method, we'll +add the following: + +```ruby +... +def test_basic + byebug + solutions = [] +... +``` + +Now we run the program, requiring `byebug` + +```bash +$ ruby -rbyebug test-triangle.rb +Run options: --seed 13073 + +# Running tests: + +[2, 11] in test-triangle.rb + 2: require_relative 'triangle.rb' + 3: + 4: class TestTri < MiniTest::Unit::TestCase + 5: def test_basic + 6: byebug +=> 7: solutions = [] + 8: 0.upto(5) do |i| + 9: solutions << triangle(i) + 10: end + 11: assert_equal([0, 1, 3, 6, 10, 15], solutions, +(byebug) +``` + +and we see that we are stopped at line 7 just before the initialization of the +list `solutions`. + +Now let's see where we are... + +```bash +(byebug) set nofullpath +Displaying frame's full file names is off. +(byebug) bt +--> #0 TestTri.test_basic at test-triangle.rb:7 + #1 MiniTest::Unit::TestCase.run(runner#MiniTest::Unit) at .../2.0.0/minitest/unit.rb:1301 + #2 MiniTest::Unit.block in _run_suite(suite#Class, type#Symbol) at .../2.0.0/minitest/unit.rb:919 + +-- #3 Array.map at .../2.0.0/minitest/unit.rb:912 + #4 MiniTest::Unit._run_suite(suite#Class, type#Symbol) at .../2.0.0/minitest/unit.rb:912 + #5 MiniTest::Unit.block in _run_suites(suites#Array, type#Symbol) at .../2.0.0/minitest/unit.rb:899 + +-- #6 Array.map at .../2.0.0/minitest/unit.rb:899 + #7 MiniTest::Unit._run_suites(suites#Array, type#Symbol) at .../2.0.0/minitest/unit.rb:899 + #8 MiniTest::Unit._run_anything(type#Symbol) at .../2.0.0/minitest/unit.rb:867 + #9 MiniTest::Unit.run_tests at .../2.0.0/minitest/unit.rb:1060 + #10 MiniTest::Unit.block in _run(args#Array) at .../2.0.0/minitest/unit.rb:1047 + +-- #11 Array.each at .../2.0.0/minitest/unit.rb:1046 + #12 MiniTest::Unit._run(args#Array) at .../2.0.0/minitest/unit.rb:1046 + #13 MiniTest::Unit.run(args#Array) at .../2.0.0/minitest/unit.rb:1035 + #14 #.block in autorun at .../2.0.0/minitest/unit.rb:789 +(byebug) +``` + +We get the same result as if we had run byebug from the outset, just faster! + +__NOTICE: In ruby-debug, debugger and older versions of byebug, this would not +work as expected. If you are having issues, please upgrade to byebug >= 1.5.0__ + + +### Byebug.start with a block + +We saw that `Byebug.start()` and `Byebug.stop()` allow fine-grain control over +where byebug tracking should occur. + +Rather than use an explicit `stop()`, you can also pass a block to the `start()` +method. This causes `start()` to run and then `yield` to that block. When the +block is finished, `stop()` is run. In other words, this wraps a +`Byebug.start()` and `Byebug.stop()` around the block of code. But it also has a +side benefit of ensuring that in the presence of an uncaught exception `stop` is +run, without having to explicitly use `begin ... ensure Byebug.stop() end`. + +For example, in Ruby on Rails you might want to debug code in one of the +controllers without causing any slowdown to any other code. And this can be done +by wrapping the controller in a `start()` with a block; when the method wrapped +this way finishes, byebug is turned off and the application proceeds at regular +speed. + +Of course, inside the block you will probably want to enter the byebug using +`Byebug.byebug()`, otherwise there would be little point in using the `start`. +For example, you can do this in `irb`: + +```bash +$ irb +2.0.0p195 :001 > require 'byebug' + => true +2.0.0p195 :002 > def foo +2.0.0p195 :003?> x=1 +2.0.0p195 :004?> puts 'foo' +2.0.0p195 :005?> end + => nil +2.0.0p195 :006 > Byebug.start{byebug; foo} +(irb) @ 6 +(byebug) s +(irb) @ 3 +(byebug) s +(irb) @ 4 +(byebug) p x +1 +(byebug) s +foo + => true +2.0.0p195 :007 > +``` + +There is a counter inside of `Byebug.start` method to make sure that this works +when another `Byebug.start` method is called inside of the outer one. However, +if you are stopped inside byebug, issuing another `byebug` call will not have +any effect even if it is nested inside another `Byebug.start`. + + +### Debugging Oddities: How debugging Ruby may be different from other languages + +If you are used to debugging in other languages like C, C++, Perl, Java or even +Bash (see [bashdb](http://bashdb.sf.net)), there may be a number of things that +seem or feel a little bit different and may confuse you. A number of these +things aren't oddities of the debugger per se but differences in how Ruby works +compared to those other languages. Because Ruby works a little differently from +those other languages, writing a debugger has to also be a little different as +well if it is to be useful. In this respect, using byebug may help you +understand Ruby better. + +We've already seen one such difference: the fact that we stop on method +definitions or `def`'s and that is because these are in fact executable +statements. In other compiled languages this would not happen because that's +already been done when you compile the program (or in Perl when it scans in the +program). In this section we'll consider some other things that might throw off +new users to Ruby who are familiar with other languages and debugging in them. + +* Bouncing Around in Blocks (iterators) +* No Parameter Values in a Call Stack +* Lines You Can Stop At + +#### Bouncing Around in Blocks (iterators) + +When debugging languages with coroutines like Python and Ruby, a method call may +not necessarily go to the first statement after the method header. It's possible +that the call will continue after a `yield` statement from a prior call. + +```ruby +# Enumerator for primes +class SievePrime + @@odd_primes = [] + def self.next_prime(&block) + candidate = 2 + yield candidate + not_prime = false + candidate += 1 + while true do + @@odd_primes.each do |p| + not_prime = (0 == (candidate % p)) + break if not_prime + end + unless not_prime + @@odd_primes << candidate + yield candidate + end + candidate += 2 + end + end +end +SievePrime.next_prime do |prime| + puts prime + break if prime > 10 +end +``` + +```bash +$ byebug primes.rb +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/primes.rb + 1: # Enumerator for primes +=> 2: class SievePrime + 3: @@odd_primes = [] + 4: def self.next_prime(&block) + 5: candidate = 2 + 6: yield candidate + 7: not_prime = false + 8: candidate += 1 + 9: while true do + 10: @@odd_primes.each do |p| +(byebug) set linetrace +line tracing is on. +(byebug) set basename +basename in on. +(byebug) step 9 +Tracing: primes.rb:3 @@odd_primes = [] +Tracing: primes.rb:4 def self.next_prime(&block) +Tracing: primes.rb:22 SievePrime.next_prime do |prime| +Tracing: primes.rb:5 candidate = 2 +Tracing: primes.rb:6 yield candidate +Tracing: primes.rb:23 puts prime +2 +Tracing: primes.rb:24 break if prime > 10 +Tracing: primes.rb:7 not_prime = false +Tracing: primes.rb:8 candidate += 1 +[3, 12] in /home/davidr/Proyectos/byebug/old_doc/primes.rb + 3: @@odd_primes = [] + 4: def self.next_prime(&block) + 5: candidate = 2 + 6: yield candidate + 7: not_prime = false +=> 8: candidate += 1 + 9: while true do + 10: @@odd_primes.each do |p| + 11: not_prime = (0 == (candidate % p)) + 12: break if not_prime +(byebug) +``` + +The loop between lines 23-26 gets interleaved between those of +`Sieve::next_prime`, lines 6-19 above. + + +#### No Parameter Values in a Call Stack + +In traditional debuggers, in a call stack you can generally see the names of the +parameters and the values that were passed in. + +Ruby is a very dynamic language and it tries to be efficient within the confines +of the language definition. Values generally aren't taken out of a variable or +expression and pushed onto a stack. Instead a new scope is created and the +parameters are given initial values. Parameter passing is by _reference_ not by +_value_ as it is say Algol, C, or Perl. During the execution of a method, +parameter values can change (and often do). In fact even the _class_ of the +object can change. + +So at present, the name of the parameter is shown. The call-style setting +([callstyle]()) can be used to set whether the name is shown or the name and the +_current_ class of the object. It has been contemplated that a style might be +added which saves on call shorter "scalar" types of values and the class name. + + +#### Lines You Can Stop At + +As with the duplicate stops per control (e.g. `if` statement), until tools like +debuggers get more traction among core ruby developers there are going to be +weirdness. Here we describe the stopping locations which effects the breakpoint +line numbers you can stop at. + +Consider the following little Ruby program. + +```ruby +'Yes it does' =~ / +(Yes) \s+ +it \s+ +does +/ix +puts $1 +``` + +The stopping points that Ruby records are the last two lines, lines 5 and 6. + +Inside `byebug` you can get a list of stoppable lines for a file using the `info +file` command with the attribute `breakpoints`. + +To be continued... +* more complex example with objects, pretty printing and irb. +* line tracing and non-interactive tracing. +* mixing in Byebug.debug with byebug +* post-mortem debugging and setting up for that + + +## Getting in & out + +### Starting byebug + +There is a wrapper script called `byebug` which basically `require`'s the gem +then loads `byebug` before its argument (the program to be debugged) is started. + +```bash +byebug [byebug-options] [--] ruby-script ruby-script-arguments +``` + +If you don't need to pass dash options to your program, which might be confused +with byebug options, then you don't need to add the `--`. To get a brief list of +options and descriptions, use the `--help` option. + +```bash +$ byebug --help +byebug 1.6.1 +Usage: byebug [options] -- + +Options: + -d, --debug Set $DEBUG=true + -I, --include PATH Add PATH (single or multiple:path:list) to $LOAD_PATH + --no-quit Do not quit when script finishes + --no-stop Do not stop when script is loaded + --nx Don't run any byebug initialization files + --post-mortem Enable post-mortem mode for uncaught exceptions + -r, --require SCRIPT Require library before script + --restart-script FILE Name of the script file to run. Erased after read + --script FILE Name of the script file to run + -x, --trace Turn on line tracing + +Common options: + --help Show this message + --version Print program version + -v Print version number, then turn on verbose mode +``` + +Many options appear as a long option name, such as `--help` and a short one +letter option name, such as `-h`. The list of options is detailed below: + +* **-h | --help**. It causes `byebug` to print some basic help and exit +* **-v | --version**. It causes `byebug` to print its version number and +exit. +* **-d | --debug**. Set `$DEBUG` to `true`. Compatible with Ruby's. +* **-I | --include **. Add `path` to load path. `path` can be a single +path ar a colon separated path list. +* **--post-mortem**. If your program raises an exception that isn't caught you +can enter byebug for inspection of what went wrong. You may also want to use +this option in conjunction with `--no-stop`. See also [Post-Mortem Debugging](). +* **--no-quit**. Restart `byebug` when your program terminates normally. +* **--no-stop**. Normally `byebug` stops before executing the first statement. +If instead you want it to start running initially and perhaps break it later in +the execution, use this option. +* **--require | -r**. Require the library before executing the script. However, +if the library happened to be `debug`, we'll just ignore the require since we're +already a debugger. This option is compatible with Ruby's. +* **--script **. Script to run before byebug's execution. +* **-x | --trace**. Turn on line tracing. Running `byebug --trace +.rb` is pretty much like running `ruby -rtracer +.rb`. If all you want to do however is get a linetrace, `tracer` is +most likely faster than `byebug` + +```bash +$ time ruby -rtracer old_doc/gcd.rb 24 31 >/dev/null + +real 0m0.066s +user 0m0.048s +sys 0m0.016s + +$ time byebug --trace old_doc/gcd.rb 24 31 >/dev/null + +real 0m0.660s +user 0m0.588s +sys 0m0.056s +``` + +### Byebug default options + +Byebug has many command-line options,; it seems that some people want to set +them differently from the defaults. For example, some people may want +`--no-quit` to be the default behavior. One could write a wrapper script or set +a shell alias to handle this. But `byebug` has another way to do it. Before +processing command options, if the file `$HOME/.byebugoptrc` is found, it is +loaded. If you want to set the defaults in some other way, you can put Ruby code +here and set variable `options` which is an OpenStruct. For example here's how +you'd set `-no-quit` and a personal message. + +```ruby +# This file contains how you want the default options to byebug to be set. Any +# Ruby code can be put here. +# +# byebug # Uncomment if you want to debug byebug! +options.control = false +puts "rocky's byebugrc run" +``` + +Here are the default values in `options` + +``` +# +``` + +### Command Files + +A command file is a file of lines that are `byebug` commands. Comments (lines +starting with `#`) may also be included. An empty line in a command file does +nothing; it does not mean to repeat the last command, as it would from the +terminal. + +When you start `byebug`, it automatically executes commands from its +_init file_, called `.byebugrc`. During startup, `byebug` does the following: + +* __Processes command line options and operands.__ Reads the init file in your +current directory, if any, and then checks your home directory. The home +directory is the directory named in the `$HOME` or `$HOMEPATH` environment +variable. Thus, you can have more than one init file, one generic in your home +directory, and another, specific to the program you are debugging, in the +directory where you invoke `byebug`. + +* __Reads command files specified by the `--script` option.__ + +You can also request the execution of a command file with the `source` command +(see [Source]()). + + +### Quitting byebug + +To exit `byebug`, use the `quit` command (abbreviated `q` and aliased `exit`). +Normally if you are in an interactive session, this command will prompt to ask +if you really want to quit. If you don't want any questions asked, enter +`quit unconditionally` (abbreviated `q!`). Another way to terminate byebug is to +use the `kill` command. This does the more forceful `kill -9`. It can be used in +cases where `quit` doesn't work (I haven't seen those yet). + + +### Calling byebug from inside your program + +Running a program from byebug adds a bit of overhead and slows it down a little. +Furthermore, by necessity, debuggers change the operation of the program they +are debugging. And this can lead to unexpected and unwanted differences. It has +happened so often that the term +[Heisenbugs](http://en.wikipedia.org/wiki/Heisenbug}) was coined to describe the +situation where using a debugger (among other possibilities) changes the +behavior of the program so that the bug doesn't manifest itself anymore. + +There is another way to get into byebug which adds no overhead or slowdown until +you reach the point at which you want to start debugging. However here you must +change the script and make an explicit call to byebug. Because byebug isn't +involved before the first call, there is no overhead and the script will run +at the same speed as if there were no byebug. + +To enter byebug this way, just drop `byebug` in whichever line you want to start +debugging at. You also have to require byebug somehow. If using bundler, it will +take care of that for you, otherwise you can use the ruby `-r` flag or add +`require 'byebug'` in the line previous to the `byebug` call. + +If speed is crucial, you may want to start and stop this around certain sections +of code, using `Byebug.start` and `Byebug.stop`. Alternatively, instead of +issuing an explicit `Byebug.stop` you can add a block to the `Byebug.start` and +debugging is turned on for that block. If the block of code raises an uncaught +exception that would cause the block to terminate, the `stop` will occur. See +[Byebug.start with a block](). + +When `byebug`is run, `.byebugrc` is read. + +You may want to enter byebug at several points in the program where there is a +problem you want to investigate. And since `byebug` is just a method call it's +possible to enclose it in a conditional expression, for example + +```ruby +byebug if 'bar' == foo and 20 == iter_count +``` + +### Restarting Byebug + +You can restart the program using `restart [program args]`. This is a re-exec - +all byebug state is lost. If command arguments are passed, those are used. +Otherwise program arguments from the last invocation are used. + +You won't be able to restart your program in all cases. First, the program +should have been invoked at the outset rather than having been called from +inside your program or invoked as a result of post-mortem handling. + +Also, since this relies on the OS `exec` call, this command is available only if +your OS supports `exec`. + + +## Byebug Command Reference + +### Command Syntax +Usually a command is put on a single line. There is no limit on how long it can be. +It starts with a command name, which is followed by arguments whose meaning depends +on the command name. For example, the command `step` accepts an argument which is the +number of times to step, as in `step 5`. You can also use the `step` command with no +arguments. Some commands do not allow any arguments. + +Multiple commands can be put on a line by separating each with a semicolon `;`. You +can disable the meaning of a semicolon to separate commands by escaping it with a +backslash. + +For example, if you have [autoeval]() set, which is the default, you might want to +enter the following code to compute the 5th Fibonacci number. + +```bash +(byebug) fib1=0; fib2=1; 5.times {|temp| temp=fib1; fib1=fib2; fib2 += temp } +0 +1 +SyntaxError Exception: /home/davidr/Proyectos/sample_app/trace.rb:1: syntax +error, unexpected end-of-input, expecting '}' + 5.times { |temp| temp=fib1 + ^ +nil +1 +SyntaxError Exception: /home/davidr/Proyectos/sample_app/trace.rb:1: syntax +error, unexpected tSTRING_DEND, expecting end-of-input + fib2 += temp } + ^ +nil +(byebug) fib1=0\; fib2=1\; 5.times {|temp| temp=fib1\; fib1=fib2\; fib2 += temp } +5 +(byebug) fib2 +8 +``` + +You might also consider using the [irb]() or [pry]() commands and then you won't have +to escape semicolons. + +A blank line as input (typing just ``) means to repeat the previous command. + +Byebug uses readline, which handles line editing and retrieval of previous commands. +Up arrow, for example, moves to the previous byebug command; down arrow moves to the +next more recent command (provided you are not already at the last command). Command +history is saved in file `.byebug_hist`. A limit is put on the history size. You +can see this with the `show history size` command. See [history]() for history +parameters. + +### Command Output +In the command-line interface, when `byebug` is waiting for input it presents a +prompt of the form `(byebug)`. If the program has terminated normally the prompt will +be `(byebug:ctrl)` and in post-mortem debugging it will be +`(byebug:post-mortem)`. + +Whenever `byebug` gives an error message such as for an invalid command or an invalid +location position, it will generally preface the message with `***`. + +### Command Help + +Once inside `byebug` you can always ask it for information on its commands using the +`help` command. You can use `help` (abbreviated `h`) with no arguments to display a +short list of named classes of commands + +```bash +(byebug) help +Type "help " for help on a specific command + +Available commands: +backtrace delete enable help method ps save step where +break disable eval info next putl set trace +catch display exit irb p quit show undisplay +condition down finish kill pp reload skip up +continue edit frame list pry restart source var +``` + +With a command name as `help` argument, `byebug` displays short information on how to +use that command. + +```bash +(byebug) help list +l[ist] list forward +l[ist] - list backward +l[ist] = list current line +l[ist] nn-mm list given lines +* NOTE - to turn on autolist, use 'set autolist' +(byebug) +``` + +A number of commands, namely `info`, `set`, `show`, `enable` and `disable`, have many +sub-parameters or _subcommands_. When you ask for help for one of these commands, you +will get help for all of the subcommands that command offers. Sometimes you may want +help only on a subcommand and to do this just follow the command with its subcommand +name. For example, `help info breakpoints`will just give help about the `info +breakpoints` command. Furthermore it will give longer help than the summary +information that appears when you ask for help. You don't need to list the full +subcommand name, just enough of the letters to make that subcommand distinct from +others will do. For example, `help info b` is the same as `help info breakpoints`. + +Some examples follow. + +```bash +(byebug) help info +info[ subcommand] + +Generic command for showing things about the program being debugged. + +-- +List of "info" subcommands: +-- +info args -- Argument variables of current stack frame +info breakpoints -- Status of user-settable breakpoints +info catch -- Exceptions that can be caught in the current stack +frame +info display -- Expressions to display when program stops +info file -- Info about a particular file read in +info files -- File names and timestamps of files read in +info global_variables -- Global variables +info instance_variables -- Instance variables of the current stack frame +info line -- Line number and file name of current position in +source file +info locals -- Local variables of the current stack frame +info program -- Execution status of the program +info stack -- Backtrace of the stack +info variables -- Local and instance variables of the current stack +frame +``` + +```bash +(byebug) help info breakpoints +Status of user-settable breakpoints. +Without argument, list info about all breakpoints. +With an integer argument, list info on that breakpoint. +``` + +```bash +(byebug) help info b +Status of user-settable breakpoints. +Without argument, list info about all breakpoints. +With an integer argument, list info on that breakpoint. +``` + +### Control Commands: quit, restart, source + +#### Quit + +To exit `byebug`, type `quit` (abbreviated `q` and aliased `exit`). Normally if +you are in an interactive session, this command will prompt you to confirm you +really want to quit. If you don't want any questions asked, enter +`quit unconditionally` (abbreviated `q!`). + +#### Restart + +To restart the program, use the `restart|r` command. This is a re-exec - all +`byebug` state is lost. If command arguments are passed, those are used. +Otherwise program arguments from the last invocation are used. + +You won't be able to restart your program in all cases. First, the program +should have been invoked at the outset rather than having been called from +inside your program or invoked as a result of post-mortem handling. + +#### Source + +You can run `byebug` commands inside a file, using the command `source `. +The lines in a command file are executed sequentially. They are not printed as +they are executed. If there is an error, execution proceeds to the next command +in the file. For information about command files that get run automatically on +startup see [Command Files](). + + +### Display Commands: display, undisplay + +#### Display + +If you find that you want to print the value of an expression frequently (to see +how it changes), you might want to add it to the *automatic display list** so +that `byebug` evaluates it each time your program stops or after a line is +printed if line tracing is enabled. Each expression added to the list is given a +number to identify it; to remove an expression from the list, you specify that +number. The automatic display looks like this: + +```bash +(byebug) display n +1: n = 3 +``` + +This display shows item numbers, expressions and their current values. If the +expression is undefined or illegal the expression will be printed but no value +will appear. + +```bash +(byebug) display undefined_variable +2: undefined_variable = +(byebug) display 1/0 +3: 1/0 = +``` + +If you use `display` with no argument, `byebug` will display the current values +of the expressions in the list, just as it is done when your program stops. +Using `info display` has the same effect. + +#### Undisplay + +To remove an item from the list, use `undisplay` followed by the number +identifying the expression you want to remove. `undisplay` does not repeat if +you press ``after using it (otherwise you would just get the error _No +display number n_) + +You can also temporarily disable or enable display expressions, so that the will +not be printed but they won't be forgotten either, so you can toggle them again +later. To do that, use `disable display` or `enable display` followed by the +expression number. + + +### Print Commands + +One way to examine and change data in your script is with the `eval` command +(abbreviated `p`). `byebug` by default evaluates any input that is not +recognized as a command, so in most situations `eval` is not necessary and +`byebug` will work like a REPL. One case where it's necessary could be when +trying to print a variable called `n`. In this case, you have no choice because +typing just `n` will execute `byebug`'s command `next`. + +A similar command to `eval|p` is `pp` which tries to pretty print the result. + +If the value you want to print is an array, sometimes a columnized list looks +nicer. Use `putl` for that. Notice however that entries are sorted to run down +first rather than across. If the value is not an array `putl` will just call +pretty-print. + +Sometimes you may want to print the array not only columnized, but sorted as +well. The list of byebug help commands appears this way, and so does the output +of the `method` commands. Use `ps` for that. If the value is not an array `ps` +will just call pretty-print. + +```bash +(byebug) Kernel.instance_methods +[:nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, +:dup, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, +:frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods, +:private_methods, :public_methods, :instance_variables, :instance_variable_get, +:instance_variable_set, :instance_variable_defined?, :remove_instance_variable, +:instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, +:extend, :display, :method, :public_method, :define_singleton_method, +:object_id, :to_enum, :enum_for, :gem, :pretty_inspect, :byebug] +(byebug) p Kernel.instance_methods +[:nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, +:dup, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, +:frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods, +:private_methods, :public_methods, :instance_variables, :instance_variable_get, +:instance_variable_set, :instance_variable_defined?, :remove_instance_variable, +:instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, +:extend, :display, :method, :public_method, :define_singleton_method, +:object_id, :to_enum, :enum_for, :gem, :pretty_inspect, :byebug] +(byebug) pp Kernel.instance_methods +[:nil?, + :===, + :=~, + :!~, + :eql?, + :hash, + :<=>, + :class, + :singleton_class, + :clone, + :dup, + :taint, + :tainted?, + :untaint, + :untrust, + :untrusted?, + :trust, + :freeze, + :frozen?, + :to_s, + :inspect, + :methods, + :singleton_methods, + :protected_methods, + :private_methods, + :public_methods, + :instance_variables, + :instance_variable_get, + :instance_variable_set, + :instance_variable_defined?, + :remove_instance_variable, + :instance_of?, + :kind_of?, + :is_a?, + :tap, + :send, + :public_send, + :respond_to?, + :extend, + :display, + :method, + :public_method, + :define_singleton_method, + :object_id, + :to_enum, + :enum_for, + :gem, + :pretty_inspect, + :byebug] +(byebug) putl Kernel.instance_methods +nil? <=> tainted? frozen? private_methods remove_instance_variable public_send define_singleton_method byebug +=== class untaint to_s public_methods instance_of? respond_to? object_id +=~ singleton_class untrust inspect instance_variables kind_of? extend to_enum +!~ clone untrusted? methods instance_variable_get is_a? display enum_for +eql? dup trust singleton_methods instance_variable_set tap method gem +hash taint freeze protected_methods instance_variable_defined? send public_method pretty_inspect +(byebug) ps Kernel.instance_methods +!~ clone extend instance_of? kind_of? private_methods respond_to? tap untrusted? +<=> define_singleton_method freeze instance_variable_defined? method protected_methods send to_enum +=== display frozen? instance_variable_get methods public_method singleton_class to_s +=~ dup gem instance_variable_set nil? public_methods singleton_methods trust +byebug enum_for hash instance_variables object_id public_send taint untaint +class eql? inspect is_a? pretty_inspect remove_instance_variable tainted? untrust +``` + +Finally, if you need more advanced functionality from REPL's, you can enter +`irb` or `pry` using `irb` or `pry` commands. The bindings environment will be +set to the current state in the program. When you leave the repl and go back to +`byebug`'s command prompt we show the file, line and text position of the +program. If you issue a `list` without location information, the default +location used is the current line rather than the current position that may have +got updated via a prior `list` command. + +``` +$ byebug triangle.rb +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 1: # Compute the n'th triangle number, the hard way: triangle(n) == (n*(n+1))/2 +=> 2: def triangle(n) + 3: tri = 0 + 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: + 10: if __FILE__ == $0 +(byebug) irb +2.0.0-p247 :001 > (0..6).inject{|sum, i| sum +=i} + => 21 +2.0.0-p247 :002 > exit +/home/davidr/Proyectos/byebug/old_doc/triangle.rb @ 2 +def triangle(n) +(byebug) list # same line range as before going into irb +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 1: # Compute the n'th triangle number, the hard way: triangle(n) == (n*(n+1))/2 +=> 2: def triangle(n) + 3: tri = 0 + 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: + 10: if __FILE__ == $0 +(byebug) +``` + +### Printing variables + +Byebug can print many different information about variables. Such as +* `var const `. Show the constants of ``. This is basically +listing variables and their values in `.constant`. +* `var instance `. Show the instance variables of ``. This is +basically listing `.instance_variables`. +* `info instance_variables`. Show instance_variables of `self`. +* `info locals`. Show local variables. +* `info globals`. Show global variables. +* `info variables`. Show local and instance variables of `self`. +* `method instance `. Show methods of ``. Basically this is the +same as running `ps .instance_methods(false)`. +* `method iv `. Show method instance variables of `object`. Basically +this is the same as running +``` + .instance_variables.each do |v| + puts "%s = %s\n" % [v, .instance_variable_get(v)] + end +``` +* `signature `. Show signature of method ``. _This command is +available only if the nodewrap gem is installed_. + +```ruby + def mymethod(a, b=5, &bock) + end + (byebug) method sig mymethod + Mine#mymethod(a, b=5, &bock) +``` + +* `method `. Show methods of the class or module +``. Basically this is the same as running +`ps .methods`. + +### Examining Program Source Files (`list`) + +`byebug` can print parts of your script's source. When your script stops, +`byebug` spontaneously lists the source code around the line where it stopped +that line. It does that when you change the current stack frame as well. +Implicitly there is a default line location. Each time a list command is run +that implicit location is updated, so that running several list commands in +succession shows a contiguous block of program text. + +If you don't need code context displayed every time, you can issue the `set +noautolist` command. Now whenever you want code listed, you can explicitly issue +the `list` command or its abbreviation `l`. Notice that when a second listing is +displayed, we continue listing from the place we last left off. When the +beginning or end of the file is reached, the line range to be shown is adjusted +so "it doesn't overflow". You can set the `noautolist` option by default by +dropping `set noautolist` in byebug's startup file `.byebugrc`. + +If you want to set how many lines to be printed by default rather than use the +initial number of lines, 10, use the `set listsize` command ([listsize()). To +see the entire program in one shot, give an explicit starting and ending line +number. You can print other portions of source files by giving explicit position +as a parameter to the list command. + +There are several ways to specify what part of the file you want to print. `list +nnn` prints lines centered around line number `nnn` in the current source file. +`l` prints more lines, following the last lines printed. `list -` prints lines +just before the lines last printed. `list nnn-mmm` prints lines between `nnn` +and `mmm` inclusive. `list =` prints lines centered around where the script is +stopped. Repeating a `list` command with `RET` discards the argument, so it is +equivalent to typing just `list`. This is more useful than listing the same +lines again. An exception is made for an argument of `-`: that argument is +preserved in repetition so that each repetition moves up in the source file. + +### Editing Source files (`edit`) + +To edit a source file, use the `edit` command. The editor of your choice is invoked +with the current line set to the active line in the program. Alternatively, you can +give a line specification to specify what part of the file you want to edit. + +You can customize `byebug` to use any editor you want by using the `EDITOR` +environment variable. The only restriction is that your editor (say `ex`) recognizes +the following command-line syntax: +``` +ex +nnn file +``` + +The optional numeric value `+nnn` specifies the line number in the file where +you want to start editing. For example, to configure `byebug` to use the `vi` editor, +you could use these commands with the `sh` shell: + +```bash +EDITOR=/usr/bin/vi +export EDITOR +byebug ... +``` + +or in the `csh` shell, +```bash +setenv EDITOR /usr/bin/vi +byebug ... +``` diff --git a/vendor/bundle/gems/byebug-2.7.0/Gemfile b/vendor/bundle/gems/byebug-2.7.0/Gemfile new file mode 100644 index 0000000..fa75df1 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gemspec diff --git a/vendor/bundle/gems/byebug-2.7.0/LICENSE b/vendor/bundle/gems/byebug-2.7.0/LICENSE new file mode 100644 index 0000000..84d0ba5 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/LICENSE @@ -0,0 +1,23 @@ +Copyright (C) 2013 David Rodríguez +All rights reserved. + * +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/gems/byebug-2.7.0/README.md b/vendor/bundle/gems/byebug-2.7.0/README.md new file mode 100644 index 0000000..e5ffed7 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/README.md @@ -0,0 +1,167 @@ +# Byebug +[![Version][VersionBadge]][VersionURL] +[![Build][TravisBadge]][TravisURL] +[![Climate][CodeClimateBadge]][CodeClimateURL] +[![Dependencies][GemnasiumBadge]][GemnasiumURL] +[![Coverage][CoverallsBadge]][CoverallsURL] +[![Gittip][GittipBadge]][GittipURL] + +_Debugging in Ruby 2_ + +Byebug is a simple to use, feature rich debugger for Ruby 2. It uses the new +TracePoint API for execution control and the new Debug Inspector API for call +stack navigation, so it doesn't depend on internal core sources. It's developed +as a C extension, so it's fast. And it has a full test suite so it's reliable. + +It allows you to see what is going on _inside_ a Ruby program while it executes +and can do four main kinds of things to help you catch bugs in the act: + +* Start your program or attach to it, specifying anything that might affect its +behavior. +* Make your program stop on specified conditions. +* Examine what has happened when your program has stopped. +* Change things in your program, so you can experiment with correcting the +effects of one bug and go on to learn about another. + + +## Install + + $ gem install byebug + + +## Usage + +Simply drop + + byebug + +wherever you want to start debugging and the execution will stop there. If you +are debugging rails, start the server and once the execution gets to your +`byebug` command you will get a debugging prompt. + +Former [debugger](https://github.com/cldwalker/debugger) or +[ruby-debug](https://github.com/mark-moseley/ruby-debug) users, notice: + +* Some gems (rails, rspec) implement debugging flags (-d, --debugger) that early +require and start the debugger. These flags are a performance penalty and Byebug +doesn't need them anymore so my recommendation is not to use them. +* The startup configuration file is now called `.byebugrc` instead of +`.rdebugrc`. + + +## What's different from debugger + +* Works on Ruby 2.x and it doesn't on 1.9.x. +* Has no MRI internal source code dependencies, just a clean API. +* Fixes all of debugger's open bugs in its issue tracker and provides some +enhancements, such as a markdown guide or the fact that `byebug` can now be +placed at the end of a block or method call. +* Actively mantained. +* Editor agnostic: no external editor built-in support. +* Pry command is built-in. No need of external gem like debugger-pry. + + +## Semantic Versioning + +Byebug tries to follow [semantic versioning](http://semver.org). Backwards +compatibility doesn't seem like a critic issue for a debugger because it's not +supposed to be used permanently by any program, let alone in production +environments. However, I still like the idea of giving some meaning to version +changes. + +Byebug's public API is determined by its set of commands + + Command | Aliases | Subcommands + ----------- |:------------ |:----------- + `backtrace` | `bt` `where` | + `break` | | + `catch` | | + `condition` | | + `continue` | | + `delete` | | + `disable` | | `breakpoints` `display` + `display` | | + `down` | | + `edit` | | + `enable` | | `breakpoints` `display` + `finish` | | + `frame` | | + `help` | | + `info` | | `args` `breakpoints` `catch` `display` `file` `files` `global_variables` `instance_variables` `line` `locals` `program` `stack` `variables` + `irb` | | + `kill` | | + `list` | | + `method` | | `instance` `iv` + `next` | | + `p` | `eval` | + `pp` | | + `pry` | | + `ps` | | + `putl` | | + `quit` | `exit` | + `reload` | | + `restart` | | + `save` | | + `set` | | `args` `autoeval` `autoirb` `autolist` `autoreload` `basename` `callstyle` `callstyle` `forcestep` `fullpath` `history` `linetrace` `linetrace_plus` `listsize` `post_mortem` `stack_on_error` `testing` `verbose` `width` + `show` | | `args` `autoeval` `autoirb` `autolist` `autoreload` `basename` `callstyle` `callstyle` `commands` `forcestep` `fullpath` `history` `linetrace` `linetrace_plus` `listsize` `post_mortem` `stack_on_error` `verbose` `width` + `skip` | | + `source` | | + `step` | | + `thread` | | `current` `list` `resume` `stop` `switch` + `trace` | | + `undisplay` | | + `up` | | + `var` | | `class` `constant` `global` `instance` `local` `ct` + + +## Getting Started + +Read [byebug's markdown +guide](https://github.com/deivid-rodriguez/byebug/blob/master/GUIDE.md) to get +started. Proper documentation will be eventually written. + + +## Related projects + +* [pry-byebug](https://github.com/deivid-rodriguez/pry-byebug) adds `next`, + `step`, `finish`, `continue` and `break` commands to pry using byebug. +* [ruby-debug-passenger](https://github.com/davejamesmiller/ruby-debug-passenger) +adds a rake task that restarts Passenger with byebug connected. +* [minitest-byebug](https://github.com/kaspth/minitest-byebug) starts a byebug +session on minitest failures. +* [sublime-debugger](https://github.com/shuky19/sublime_debugger) provides a plugin +for ruby debugging on Sublime Text. + + +## Future (possible) directions + +* JRuby support. +* Libify and test byebug's executable. +* Add printers support. + + +## Credits + +Everybody who has ever contributed to this forked and reforked piece of +software, specially: + +* Kent Sibilev and Mark Moseley, original authors of +[ruby-debug](https://github.com/mark-moseley/ruby-debug). +* Gabriel Horner, [debugger](https://github.com/cldwalker/debugger)'s mantainer. +* Koichi Sasada, author of the new C debugging API for Ruby. +* Dennis Ushakov, author of [debase](https://github.com/denofevil/debase), the +starting point of this. +* @kevjames3 for testing, bug reports and the interest in the project. + +[VersionBadge]: https://badge.fury.io/rb/byebug.png +[VersionURL]: http://badge.fury.io/rb/byebug +[TravisBadge]: https://travis-ci.org/deivid-rodriguez/byebug.png +[TravisURL]: http://travis-ci.org/deivid-rodriguez/byebug +[CodeClimateBadge]: https://codeclimate.com/github/deivid-rodriguez/byebug.png +[CodeClimateURL]: https://codeclimate.com/github/deivid-rodriguez/byebug +[GemnasiumBadge]: https://gemnasium.com/deivid-rodriguez/byebug.png +[GemnasiumURL]: https://gemnasium.com/deivid-rodriguez/byebug +[CoverallsBadge]: https://coveralls.io/repos/deivid-rodriguez/byebug/badge.png +[CoverallsURL]: https://coveralls.io/r/deivid-rodriguez/byebug +[GittipBadge]: http://img.shields.io/gittip/deivid-rodriguez.png +[GittipURL]: https://www.gittip.com/deivid-rodriguez diff --git a/vendor/bundle/gems/byebug-2.7.0/Rakefile b/vendor/bundle/gems/byebug-2.7.0/Rakefile new file mode 100644 index 0000000..b5b86c1 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/Rakefile @@ -0,0 +1,39 @@ +require 'rake/testtask' +require 'rake/extensiontask' +require 'bundler/gem_tasks' + +Rake::ExtensionTask.new('byebug') do |ext| + ext.lib_dir = 'lib/byebug' +end + +# Override default rake tests loader +class Rake::TestTask + def rake_loader + 'test/test_helper.rb' + end +end + +desc "Run MiniTest suite" +task :test do + Rake::TestTask.new do |t| + t.verbose = true + t.warning = true + t.pattern = 'test/*_test.rb' + end +end + +base_spec = eval(File.read('byebug.gemspec'), binding, 'byebug.gemspec') + +task :default => :test + +desc 'Run a test in looped mode so that you can look for memory leaks' +task 'test_loop' do + code = %Q[loop{ require '#{$*[1]}' }] + cmd = %Q[ruby -Itest -e "#{ code }"] + system cmd +end + +desc 'Watch memory use of a looping test' +task 'test_loop_mem' do + system "watch \"ps aux | grep -v 'sh -c r' | grep [I]test\"" +end diff --git a/vendor/bundle/gems/byebug-2.7.0/bin/byebug b/vendor/bundle/gems/byebug-2.7.0/bin/byebug new file mode 100755 index 0000000..829cffa --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/bin/byebug @@ -0,0 +1,251 @@ +#!/usr/bin/env ruby + +#=== Summary +# +#A command-line front-end to byebug +# +#Command invocation: +# +# byebug [options] [--] [script-options] ruby-script-to-debug +# byebug [options] [script-options] +# byebug [--version | --help] +# +#=== Options +# +#-d | --debug:: +# Set $DEBUG true. +# +#--help:: +# Show invocation help and exit. +# +#-I | --include path +# Add path to $LOAD_PATH. Like the ruby -I command, +# it supports multiple load paths separated by colons. +# +#--post-mortem:: +# Activate post-mortem mode. +# +#--no-quit:: +# Do not quit when script terminates. Instead rerun the program. +# +#--no-stop:: +# Do not stop when script is loaded. +# +#--nx:: +# Don’t execute commands found in any initialization files like +# .byebugrc. +# +#-r | --requirescript:: +# Require the library, before executing your script. +# +#--script=file:: +# Run script file file +# +#--v:: +# Print the version number, then turn on verbose mode if a script name is +# given. If no script name is given just exit after printing the version +# number. +# +#--verbose:: +# Turn on verbose mode. +# +#--version:: +# Show the version number and exit. +# +#-x | --trace:: +# Show lines before executing them. +# + +require 'optparse' +require 'ostruct' +require File.dirname(__FILE__) + "/../lib/byebug" + +def debug_program(options) + # Make sure Ruby script syntax checks okay. + output = `ruby -c "#{Byebug::PROG_SCRIPT}" 2>&1` + if $?.exitstatus != 0 + puts output + exit $?.exitstatus + end + if bt = Byebug.debug_load(Byebug::PROG_SCRIPT, options.stop) + p bt, bt.backtrace + end +end + +# Do a shell-like path lookup for prog_script and return the results. +# If we can't find anything return prog_script. +def whence_file(prog_script) + if prog_script.index(File::SEPARATOR) + # Don't search since this name has path separator components + return prog_script + end + for dirname in ENV['PATH'].split(File::PATH_SEPARATOR) do + prog_script_try = File.join(dirname, prog_script) + return prog_script_try if File.exist?(prog_script_try) + end + # Failure + return prog_script +end + +options = OpenStruct.new( + 'nx' => false, + 'post_mortem' => false, + 'quit' => true, + 'restart_script' => nil, + 'script' => nil, + 'server' => nil, + 'stop' => true, + 'tracing' => false, +) + +def process_options(options) + program = File.basename($0) + opts = OptionParser.new do |opts| + opts.banner = < -- +EOB + opts.separator "" + opts.separator "Options:" + + opts.on("-d", "--debug", "Set $DEBUG=true") { + $DEBUG = true } + opts.on('-I', '--include PATH', String, + 'Add PATH (single or multiple:path:list) to $LOAD_PATH.') { + |path| $LOAD_PATH.unshift(*path.split(':')) } + opts.on('--no-quit', 'Do not quit when script finishes') { + options.quit = false } + opts.on('--no-stop', 'Do not stop when script is loaded') { + options.stop = false } + opts.on('-nx', 'Don\'t run any byebug initialization files') { + options.nx = true } + opts.on('--post-mortem', 'Run byebug in post-mortem mode') { + options.post_mortem = true } + opts.on('-r', '--require SCRIPT', String, 'Require library before script') { + |name| if name == 'debug' + puts 'byebug not compatible with Ruby\'s \'debug\' lib, option ignored' + else + require name + end } + opts.on('-R', '--remote HOST[:PORT]', String, 'Specify byebug server spec') { + |server| host, port = server.split(':', 2) + host = 'localhost' if host.empty? + port = nil if port && port.empty? + port &&= port.to_i + options.server = [host, port].compact + } + opts.on('--restart-script FILE', String, + 'Name of the script file to run. Erased after read') do + |restart_script| + options.restart_script = restart_script + unless File.exist?(options.restart_script) + puts "Script file '#{options.restart_script}' is not found" + exit + end + end + opts.on('--script FILE', String, 'Name of the script file to run') do + |script| + options.script = script + unless File.exist?(options.script) + puts "Script file '#{options.script}' is not found" + exit + end + end + opts.on('-x', '--trace', 'Turn on line tracing') { + options.tracing = true } + + opts.separator '' + opts.separator 'Common options:' + opts.on_tail('--help', 'Show this message') do + puts opts + exit + end + opts.on_tail('--version', 'Print program version') do + puts "byebug #{Byebug::VERSION}" + exit + end + opts.on_tail('-v', 'Print version number, then turn on verbose mode') do + puts "byebug #{Byebug::VERSION}" + $VERBOSE = true + end + end + return opts +end + +# What file is used for byebug startup commands. +unless defined?(OPTS_INITFILE) + OPTS_INITFILE = '.byebugoptrc' + HOME_DIR = ENV['HOME'].to_s +end + +begin + initfile = File.join(HOME_DIR, OPTS_INITFILE) + eval(File.read(initfile)) if File.exist?(initfile) +rescue +end + +opts = process_options(options) + +begin + Byebug::ARGV = ARGV.clone if not defined? Byebug::ARGV + Byebug::BYEBUG_SCRIPT = File.expand_path(__FILE__) + Byebug::IGNORED_FILES << Byebug::BYEBUG_SCRIPT + Byebug::INITIAL_DIR = Dir.pwd + opts.parse! ARGV +rescue StandardError => e + puts opts + puts + puts e.message + exit(-1) +end + +if options.server + puts "Connecting to byebug server #{options.server.join(':')}" + Byebug.start_client(*options.server) + exit +end + +if ARGV.empty? + puts opts + puts + puts 'Must specify a script to run' + exit(-1) +end + +# save script name +prog_script = ARGV.shift +prog_script = whence_file(prog_script) unless File.exist?(prog_script) +Byebug::PROG_SCRIPT = File.expand_path prog_script + +# Set up trace hook for byebug +Byebug.start post_mortem: options.post_mortem + +# load initrc script (e.g. .byebugrc) +Byebug.run_init_script(StringIO.new) unless options.nx + +# run restore-settings startup script if specified +if options.restart_script + require 'fileutils' + Byebug.run_script(options.restart_script) + FileUtils.rm(options.restart_script) +end + +# run startup script if specified +if options.script + Byebug.run_script(options.script) +end + +options.stop = false if options.tracing +Byebug.tracing = options.tracing + +loop do + debug_program(options) + + break if options.quit + + interface = Byebug::LocalInterface.new + # Not sure if ControlCommandProcessor is really the right + # thing to use. CommandProcessor requires a state. + processor = Byebug::ControlCommandProcessor.new(interface) + processor.process_commands +end diff --git a/vendor/bundle/gems/byebug-2.7.0/byebug.gemspec b/vendor/bundle/gems/byebug-2.7.0/byebug.gemspec new file mode 100644 index 0000000..c0c5816 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/byebug.gemspec @@ -0,0 +1,34 @@ +require File.dirname(__FILE__) + '/lib/byebug/version' + +Gem::Specification.new do |s| + s.name = 'byebug' + s.version = Byebug::VERSION + s.authors = ['David Rodriguez', 'Kent Sibilev', 'Mark Moseley'] + s.email = 'deivid.rodriguez@mail.com' + s.license = 'BSD' + s.homepage = 'http://github.com/deivid-rodriguez/byebug' + s.summary = %q{Ruby 2.0 fast debugger - base + cli} + s.description = %q{Byebug is a Ruby 2 debugger. It's implemented using the + Ruby 2 TracePoint C API for execution control and the Debug Inspector C API + for call stack navigation. The core component provides support that + front-ends can build on. It provides breakpoint handling and bindings for + stack frames among other things and it comes with an easy to use command + line interface.} + + s.required_ruby_version = '>= 2.0.0' + + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- test/*`.split("\n") + s.executables = ['byebug'] + s.extra_rdoc_files = ['README.md'] + s.extensions = ['ext/byebug/extconf.rb'] + + s.add_dependency 'columnize', '~> 0.3' + s.add_dependency 'debugger-linecache', '~> 1.2' + + s.add_development_dependency 'rake', '~> 10.1' + s.add_development_dependency 'rake-compiler', '~> 0.9' + s.add_development_dependency 'mocha', '~> 1.0' + s.add_development_dependency 'minitest', '~> 5.2' + s.add_development_dependency 'coveralls', '~> 0.7' +end diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/.RUBYARCHDIR.time b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/.RUBYARCHDIR.time new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/Makefile b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/Makefile new file mode 100644 index 0000000..85cee7f --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/Makefile @@ -0,0 +1,237 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@:) +ECHO = $(ECHO1:0=@echo) + +#### Start of system configuration section. #### + +srcdir = . +topdir = /home/vagrant/.rbenv/versions/2.0.0-p481/include/ruby-2.0.0 +hdrdir = $(topdir) +arch_hdrdir = /home/vagrant/.rbenv/versions/2.0.0-p481/include/ruby-2.0.0/i686-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = /home/vagrant/.rbenv/versions/2.0.0-p481 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = ./.gem.20140731-3348-1hz26dy +sitelibdir = ./.gem.20140731-3348-1hz26dy +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = /usr/include +includedir = $(prefix)/include +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_A) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-R -Wl,$(libdir) -L$(libdir) +LIBRUBYARG_STATIC = -Wl,-R -Wl,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) + +RUBY_EXTCONF_H = +cflags = $(optflags) $(debugflags) $(warnflags) +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -Wall -Werror -Wno-unused-parameter $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = -D_FILE_OFFSET_BITS=64 +CPPFLAGS = -I/home/vagrant/.rbenv/versions/2.0.0-p481/include $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(cxxflags) $(ARCH_FLAG) +ldflags = -L. -L/home/vagrant/.rbenv/versions/2.0.0-p481/lib -fstack-protector -rdynamic -Wl,-export-dynamic +dldflags = +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +AR = ar +EXEEXT = + +RUBY_INSTALL_NAME = ruby +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = i686-linux +sitearch = $(arch) +ruby_version = 2.0.0 +ruby = $(bindir)/ruby +RUBY = $(ruby) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = $(RUBY) -run -e rm -- -rf +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = + +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-R$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = /byebug +LOCAL_LIBS = +LIBS = -lpthread -lrt -ldl -lcrypt -lm -lc +ORIG_SRCS = breakpoint.c byebug.c context.c locker.c threads.c +SRCS = $(ORIG_SRCS) +OBJS = breakpoint.o byebug.o context.o locker.o threads.o +HDRS = $(srcdir)/byebug.h +TARGET = byebug +TARGET_NAME = byebug +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +BINDIR = $(DESTDIR)$(bindir) +RUBYCOMMONDIR = $(DESTDIR)$(sitedir)$(target_prefix) +RUBYLIBDIR = $(DESTDIR)$(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(DESTDIR)$(sitearchdir)$(target_prefix) +HDRDIR = $(DESTDIR)$(rubyhdrdir)/ruby$(target_prefix) +ARCHHDRDIR = $(DESTDIR)$(rubyhdrdir)/$(arch)/ruby$(target_prefix) + +TARGET_SO = $(DLLIB) +CLEANLIBS = $(TARGET).so +CLEANOBJS = *.o *.bak + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) ./.RUBYARCHDIR.time + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb install-rb-default +install-rb-default: pre-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +pre-install-rb-default: + $(ECHO) installing default byebug libraries +./.RUBYARCHDIR.time: + $(Q) $(MAKEDIRS) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .C .o + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.C.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $< + +$(DLLIB): $(OBJS) Makefile + $(ECHO) linking shared-object byebug/$(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.c b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.c new file mode 100644 index 0000000..055998e --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.c @@ -0,0 +1,504 @@ +#include + +#ifdef _WIN32 +#include +#endif + +#if defined DOSISH +#define isdirsep(x) ((x) == '/' || (x) == '\\') +#else +#define isdirsep(x) ((x) == '/') +#endif + +static VALUE cBreakpoint; +static int breakpoint_max; + +static ID idEval; + +static VALUE +eval_expression(VALUE args) +{ + return rb_funcall2(rb_mKernel, idEval, 2, RARRAY_PTR(args)); +} + +/* + * call-seq: + * breakpoint.enabled? -> bool + * + * Returns +true+ if breakpoint is enabled, false otherwise. + */ +static VALUE +brkpt_enabled(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return breakpoint->enabled; +} + +/* + * call-seq: + * breakpoint.enabled = bool + * + * Enables or disables breakpoint. + */ +static VALUE +brkpt_set_enabled(VALUE self, VALUE bool) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return breakpoint->enabled = bool; +} + +/* + * call-seq: + * breakpoint.expr -> string + * + * Returns a conditional expression which indicates when this breakpoint should + * be activated. + */ +static VALUE +brkpt_expr(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return breakpoint->expr; +} + +/* + * call-seq: + * breakpoint.expr = string | nil + * + * Sets or unsets the conditional expression which indicates when this + * breakpoint should be activated. + */ +static VALUE +brkpt_set_expr(VALUE self, VALUE expr) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr); + return expr; +} + +/* + * call-seq: + * breakpoint.hit_condition -> symbol + * + * Returns the hit condition of the breakpoint: +nil+ if it is an + * unconditional breakpoint, or :greater_or_equal, :equal or :modulo otherwise + */ +static VALUE +brkpt_hit_condition(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + switch(breakpoint->hit_condition) + { + case HIT_COND_GE: + return ID2SYM(rb_intern("greater_or_equal")); + case HIT_COND_EQ: + return ID2SYM(rb_intern("equal")); + case HIT_COND_MOD: + return ID2SYM(rb_intern("modulo")); + case HIT_COND_NONE: + default: + return Qnil; + } +} + +/* + * call-seq: + * breakpoint.hit_condition = symbol + * + * Sets the hit condition of the breakpoint which must be one of the following + * values: + * + * +nil+ if it is an unconditional breakpoint, or + * :greater_or_equal(:ge), :equal(:eq), :modulo(:mod) + */ +static VALUE +brkpt_set_hit_condition(VALUE self, VALUE value) +{ + breakpoint_t *breakpoint; + ID id_value; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + id_value = rb_to_id(value); + + if(rb_intern("greater_or_equal") == id_value || rb_intern("ge") == id_value) + breakpoint->hit_condition = HIT_COND_GE; + else if(rb_intern("equal") == id_value || rb_intern("eq") == id_value) + breakpoint->hit_condition = HIT_COND_EQ; + else if(rb_intern("modulo") == id_value || rb_intern("mod") == id_value) + breakpoint->hit_condition = HIT_COND_MOD; + else + rb_raise(rb_eArgError, "Invalid condition parameter"); + return value; +} + +/* + * call-seq: + * breakpoint.hit_count -> int + * + * Returns the number of times this breakpoint has been hit. + */ +static VALUE +brkpt_hit_count(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return INT2FIX(breakpoint->hit_count); +} + +/* + * call-seq: + * breakpoint.hit_value -> int + * + * Returns the hit value of the breakpoint, namely, a value to build a + * condition on the number of hits of the breakpoint. + */ +static VALUE +brkpt_hit_value(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return INT2FIX(breakpoint->hit_value); +} + +/* + * call-seq: + * breakpoint.hit_value = int + * + * Sets the hit value of the breakpoint. This allows the user to set conditions + * on the number of hits to enable/disable the breakpoint. + */ +static VALUE +brkpt_set_hit_value(VALUE self, VALUE value) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + breakpoint->hit_value = FIX2INT(value); + return value; +} + +/* + * call-seq: + * breakpoint.id -> int + * + * Returns the id of the breakpoint. + */ +static VALUE +brkpt_id(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return INT2FIX(breakpoint->id); +} + +/* + * call-seq: + * breakpoint.pos -> string or int + * + * Returns the position of this breakpoint, either a method name or a line + * number. + */ +static VALUE +brkpt_pos(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + if (breakpoint->type == BP_METHOD_TYPE) + return rb_str_new2(rb_id2name(breakpoint->pos.mid)); + else + return INT2FIX(breakpoint->pos.line); +} + +/* + * call-seq: + * breakpoint.source -> string + * + * Returns the source file of the breakpoint. + */ +static VALUE +brkpt_source(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return breakpoint->source; +} + +static void +mark_breakpoint(breakpoint_t *breakpoint) +{ + rb_gc_mark(breakpoint->source); + rb_gc_mark(breakpoint->expr); +} + +static VALUE +brkpt_create(VALUE klass) +{ + breakpoint_t *breakpoint = ALLOC(breakpoint_t); + + return Data_Wrap_Struct(klass, mark_breakpoint, xfree, breakpoint); +} + +static VALUE +brkpt_initialize(VALUE self, VALUE source, VALUE pos, VALUE expr) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + + breakpoint->type = FIXNUM_P(pos) ? BP_POS_TYPE : BP_METHOD_TYPE; + if(breakpoint->type == BP_POS_TYPE) + breakpoint->pos.line = FIX2INT(pos); + else + breakpoint->pos.mid = SYM2ID(pos); + + breakpoint->id = ++breakpoint_max; + breakpoint->source = StringValue(source); + breakpoint->enabled = Qtrue; + breakpoint->expr = NIL_P(expr) ? expr : StringValue(expr); + breakpoint->hit_count = 0; + breakpoint->hit_value = 0; + breakpoint->hit_condition = HIT_COND_NONE; + + return Qnil; +} + +int +filename_cmp_impl(VALUE source, char *file) +{ + char *source_ptr, *file_ptr; + long s_len, f_len, min_len; + long s,f; + int dirsep_flag = 0; + + s_len = RSTRING_LEN(source); + f_len = strlen(file); + min_len = s_len < f_len ? s_len : f_len; + + source_ptr = RSTRING_PTR(source); + file_ptr = file; + + for( s = s_len - 1, f = f_len - 1; s >= s_len - min_len && f >= f_len - min_len; s--, f-- ) + { + if((source_ptr[s] == '.' || file_ptr[f] == '.') && dirsep_flag) + return 1; + if(isdirsep(source_ptr[s]) && isdirsep(file_ptr[f])) + dirsep_flag = 1; +#ifdef DOSISH_DRIVE_LETTER + else if (s == 0) + return(toupper(source_ptr[s]) == toupper(file_ptr[f])); +#endif + else if(source_ptr[s] != file_ptr[f]) + return 0; + } + return 1; +} + +int +filename_cmp(VALUE source, char *file) +{ +#ifdef _WIN32 + return filename_cmp_impl(source, file); +#else +#ifdef PATH_MAX + char path[PATH_MAX + 1]; + path[PATH_MAX] = 0; + return filename_cmp_impl(source, realpath(file, path) != NULL ? path : file); +#else + char *path; + int result; + path = realpath(file, NULL); + result = filename_cmp_impl(source, path == NULL ? file : path); + free(path); + return result; +#endif +#endif +} + +static int +check_breakpoint_by_hit_condition(VALUE breakpoint_object) +{ + breakpoint_t *breakpoint; + + if (breakpoint_object == Qnil) + return 0; + + Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint); + breakpoint->hit_count++; + + if (Qtrue != breakpoint->enabled) + return 0; + + switch (breakpoint->hit_condition) + { + case HIT_COND_NONE: + return 1; + case HIT_COND_GE: + { + if (breakpoint->hit_count >= breakpoint->hit_value) + return 1; + break; + } + case HIT_COND_EQ: + { + if (breakpoint->hit_count == breakpoint->hit_value) + return 1; + break; + } + case HIT_COND_MOD: + { + if (breakpoint->hit_count % breakpoint->hit_value == 0) + return 1; + break; + } + } + return 0; +} + +static int +check_breakpoint_by_pos(VALUE breakpoint_object, char *file, int line) +{ + breakpoint_t *breakpoint; + + if (breakpoint_object == Qnil) + return 0; + + Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint); + + if ( (Qtrue != breakpoint->enabled) || + (breakpoint->type != BP_POS_TYPE) || + (breakpoint->pos.line != line) ) + return 0; + + return filename_cmp(breakpoint->source, file); +} + +static int +check_breakpoint_by_method(VALUE breakpoint_object, VALUE klass, ID mid, + VALUE self) +{ + breakpoint_t *breakpoint; + + if (breakpoint_object == Qnil) + return 0; + + Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint); + + if ( (Qfalse == breakpoint->enabled) || + (breakpoint->type != BP_METHOD_TYPE) || + (breakpoint->pos.mid != mid) ) + return 0; + + if ( (classname_cmp(breakpoint->source, klass)) || + ((rb_type(self) == T_CLASS) && classname_cmp(breakpoint->source, self)) ) + return 1; + + return 0; +} + +static int +check_breakpoint_by_expr(VALUE breakpoint_object, VALUE binding) +{ + breakpoint_t *breakpoint; + VALUE args, expr_result; + + if (NIL_P(breakpoint_object)) + return 0; + + Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint); + + if (Qtrue != breakpoint->enabled) + return 0; + + if (NIL_P(breakpoint->expr)) + return 1; + + args = rb_ary_new3(2, breakpoint->expr, binding); + expr_result = rb_protect(eval_expression, args, 0); + + return RTEST(expr_result); +} + +extern VALUE +find_breakpoint_by_pos(VALUE breakpoints, VALUE source, VALUE pos, + VALUE binding) +{ + VALUE breakpoint_object; + char *file; + int line; + int i; + + file = RSTRING_PTR(source); + line = FIX2INT(pos); + for (i = 0; i < RARRAY_LENINT(breakpoints); i++) + { + breakpoint_object = rb_ary_entry(breakpoints, i); + if (check_breakpoint_by_pos(breakpoint_object, file, line) && + check_breakpoint_by_expr(breakpoint_object, binding) && + check_breakpoint_by_hit_condition(breakpoint_object)) + { + return breakpoint_object; + } + } + return Qnil; +} + +extern VALUE +find_breakpoint_by_method(VALUE breakpoints, VALUE klass, ID mid, VALUE binding, + VALUE self) +{ + VALUE breakpoint_object; + int i; + + for (i = 0; i < RARRAY_LENINT(breakpoints); i++) + { + breakpoint_object = rb_ary_entry(breakpoints, i); + if (check_breakpoint_by_method(breakpoint_object, klass, mid, self) && + check_breakpoint_by_expr(breakpoint_object, binding) && + check_breakpoint_by_hit_condition(breakpoint_object)) + { + return breakpoint_object; + } + } + return Qnil; +} + +void +Init_breakpoint(VALUE mByebug) +{ + breakpoint_max = 0; + + cBreakpoint = rb_define_class_under(mByebug, "Breakpoint", rb_cObject); + + rb_define_alloc_func(cBreakpoint, brkpt_create); + rb_define_method(cBreakpoint, "initialize", brkpt_initialize, 3); + + rb_define_method(cBreakpoint, "enabled?" , brkpt_enabled , 0); + rb_define_method(cBreakpoint, "enabled=" , brkpt_set_enabled , 1); + rb_define_method(cBreakpoint, "expr" , brkpt_expr , 0); + rb_define_method(cBreakpoint, "expr=" , brkpt_set_expr , 1); + rb_define_method(cBreakpoint, "hit_count" , brkpt_hit_count , 0); + rb_define_method(cBreakpoint, "hit_condition" , brkpt_hit_condition , 0); + rb_define_method(cBreakpoint, "hit_condition=", brkpt_set_hit_condition, 1); + rb_define_method(cBreakpoint, "hit_value" , brkpt_hit_value , 0); + rb_define_method(cBreakpoint, "hit_value=" , brkpt_set_hit_value , 1); + rb_define_method(cBreakpoint, "id" , brkpt_id , 0); + rb_define_method(cBreakpoint, "pos" , brkpt_pos , 0); + rb_define_method(cBreakpoint, "source" , brkpt_source , 0); + + idEval = rb_intern("eval"); +} diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.o b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.o new file mode 100644 index 0000000..a0b1de8 Binary files /dev/null and b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.o differ diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.c b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.c new file mode 100644 index 0000000..7f9a350 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.c @@ -0,0 +1,781 @@ +#include + +static VALUE mByebug; /* Ruby Byebug Module object */ + +static VALUE tracing = Qfalse; +static VALUE post_mortem = Qfalse; +static VALUE verbose = Qfalse; + +static VALUE catchpoints = Qnil; +static VALUE breakpoints = Qnil; +static VALUE tracepoints = Qnil; + +/* Implements thread syncronization, we must stop threads when debugging */ +VALUE locker = Qnil; + +/* Threads table */ +VALUE threads = Qnil; +VALUE cThreadsTable; + +#define IS_STARTED (catchpoints != Qnil) +static void +check_started() +{ + if (!IS_STARTED) + { + rb_raise(rb_eRuntimeError, "Byebug is not started yet."); + } +} + +static void +trace_print(rb_trace_arg_t *trace_arg, debug_context_t *dc) +{ + if (trace_arg) + { + int i = 0; + VALUE path = rb_tracearg_path(trace_arg); + VALUE line = rb_tracearg_lineno(trace_arg); + VALUE event = rb_tracearg_event(trace_arg); + VALUE mid = rb_tracearg_method_id(trace_arg); + for (i=0; icalced_stack_size; i++) putc('|', stderr); + fprintf(stderr, "[#%d] %s@%s:%d %s\n", dc->thnum, + rb_id2name(SYM2ID(event)), RSTRING_PTR(path), NUM2INT(line), + NIL_P(mid) ? "" : rb_id2name(SYM2ID(mid))); + } +} + +static void +cleanup(debug_context_t *dc) +{ + VALUE thread; + + dc->stop_reason = CTX_STOP_NONE; + + /* checks for dead threads */ + check_thread_contexts(); + + /* release a lock */ + locker = Qnil; + + /* let the next thread to run */ + thread = remove_from_locked(); + if (thread != Qnil) + rb_thread_run(thread); +} + +#define EVENT_SETUP \ + rb_trace_arg_t *trace_arg = rb_tracearg_from_tracepoint(trace_point); \ + debug_context_t *dc; \ + VALUE context; \ + thread_context_lookup(rb_thread_current(), &context); \ + Data_Get_Struct(context, debug_context_t, dc); \ + if (verbose == Qtrue) trace_print(trace_arg, dc); \ + +#define EVENT_COMMON if (!trace_common(trace_arg, dc)) { return; } + +static int +trace_common(rb_trace_arg_t *trace_arg, debug_context_t *dc) +{ + /* return if thread marked as 'ignored', like byebug's control thread */ + if (CTX_FL_TEST(dc, CTX_FL_IGNORE)) + { + cleanup(dc); + return 0; + } + + halt_while_other_thread_is_active(dc); + + /* Get the lock! */ + locker = rb_thread_current(); + + /* Many events per line, but only *one* breakpoint */ + if (dc->last_line != rb_tracearg_lineno(trace_arg) || + dc->last_file != rb_tracearg_path(trace_arg)) + { + CTX_FL_SET(dc, CTX_FL_ENABLE_BKPT); + } + + return 1; +} + +static void +save_current_position(debug_context_t *dc, VALUE file, VALUE line) +{ + dc->last_file = file; + dc->last_line = line; + CTX_FL_UNSET(dc, CTX_FL_ENABLE_BKPT); + CTX_FL_UNSET(dc, CTX_FL_FORCE_MOVE); +} + +/* Functions that return control to byebug after the different events */ + +static VALUE +call_at(VALUE context_obj, debug_context_t *dc, ID mid, int argc, VALUE a0, + VALUE a1) +{ + struct call_with_inspection_data cwi; + VALUE argv[2]; + + argv[0] = a0; + argv[1] = a1; + + cwi.dc = dc; + cwi.context_obj = context_obj; + cwi.id = mid; + cwi.argc = argc; + cwi.argv = &argv[0]; + + return call_with_debug_inspector(&cwi); +} + +static VALUE +call_at_line(VALUE context_obj, debug_context_t *dc, VALUE file, VALUE line) +{ + save_current_position(dc, file, line); + return call_at(context_obj, dc, rb_intern("at_line"), 2, file, line); +} + +static VALUE +call_at_tracing(VALUE context_obj, debug_context_t *dc, VALUE file, VALUE line) +{ + return call_at(context_obj, dc, rb_intern("at_tracing"), 2, file, line); +} + +static VALUE +call_at_breakpoint(VALUE context_obj, debug_context_t *dc, VALUE breakpoint) +{ + dc->stop_reason = CTX_STOP_BREAKPOINT; + return call_at(context_obj, dc, rb_intern("at_breakpoint"), 1, breakpoint, 0); +} + +static VALUE +call_at_catchpoint(VALUE context_obj, debug_context_t *dc, VALUE exp) +{ + dc->stop_reason = CTX_STOP_CATCHPOINT; + return call_at(context_obj, dc, rb_intern("at_catchpoint"), 1, exp, 0); +} + +static VALUE +call_at_return(VALUE context_obj, debug_context_t *dc, VALUE file, VALUE line) +{ + dc->stop_reason = CTX_STOP_BREAKPOINT; + return call_at(context_obj, dc, rb_intern("at_return"), 2, file, line); + +} + +static void +call_at_line_check(VALUE context_obj, debug_context_t *dc, + VALUE breakpoint, VALUE file, VALUE line) +{ + dc->stop_reason = CTX_STOP_STEP; + + if (breakpoint != Qnil) + call_at_breakpoint(context_obj, dc, breakpoint); + + reset_stepping_stop_points(dc); + call_at_line(context_obj, dc, file, line); +} + + +/* TracePoint API event handlers */ + +static void +line_event(VALUE trace_point, void *data) +{ + VALUE breakpoint, file, line, binding; + int moved = 0; + + EVENT_SETUP + + breakpoint = Qnil; + file = rb_tracearg_path(trace_arg); + line = rb_tracearg_lineno(trace_arg); + binding = rb_tracearg_binding(trace_arg); + + EVENT_COMMON + + if (dc->calced_stack_size == 0) dc->calced_stack_size++; + + if (dc->last_line != rb_tracearg_lineno(trace_arg) || + dc->last_file != rb_tracearg_path(trace_arg)) + { + moved = 1; + } + + if (RTEST(tracing)) + call_at_tracing(context, dc, file, line); + + if (moved || !CTX_FL_TEST(dc, CTX_FL_FORCE_MOVE)) + { + dc->steps = dc->steps <= 0 ? -1 : dc->steps - 1; + if (dc->calced_stack_size <= dc->dest_frame) + { + dc->lines = dc->lines <= 0 ? -1 : dc->lines - 1; + if (dc->calced_stack_size < dc->dest_frame) + { + dc->dest_frame = dc->calced_stack_size; + rb_funcall(mByebug, rb_intern("print"), 1, + rb_str_new2("Next went up a frame because previous frame finished\n")); + } + } + } + + if (dc->steps == 0 || dc->lines == 0 || + (CTX_FL_TEST(dc, CTX_FL_ENABLE_BKPT) && + (!NIL_P( + breakpoint = find_breakpoint_by_pos(breakpoints, file, line, binding))))) + { + call_at_line_check(context, dc, breakpoint, file, line); + } + + cleanup(dc); +} + +static void +call_event(VALUE trace_point, void *data) +{ + VALUE breakpoint, klass, mid, binding, self, file, line; + + EVENT_SETUP + + dc->calced_stack_size++; + + EVENT_COMMON + + breakpoint = Qnil; + klass = rb_tracearg_defined_class(trace_arg); + mid = SYM2ID(rb_tracearg_method_id(trace_arg)); + binding = rb_tracearg_binding(trace_arg); + self = rb_tracearg_self(trace_arg); + file = rb_tracearg_path(trace_arg); + line = rb_tracearg_lineno(trace_arg); + + breakpoint = find_breakpoint_by_method(breakpoints, klass, mid, binding, self); + if (breakpoint != Qnil) + { + call_at_breakpoint(context, dc, breakpoint); + call_at_line(context, dc, file, line); + } + + cleanup(dc); +} + +static void +return_event(VALUE trace_point, void *data) +{ + EVENT_SETUP + + if (dc->calced_stack_size > 0) dc->calced_stack_size--; + + EVENT_COMMON + + if (dc->calced_stack_size + 1 == dc->before_frame) + { + VALUE file, line; + + reset_stepping_stop_points(dc); + file = rb_tracearg_path(trace_arg); + line = rb_tracearg_lineno(trace_arg); + call_at_return(context, dc, file, line); + } + + if (dc->calced_stack_size + 1 == dc->after_frame) + { + reset_stepping_stop_points(dc); + dc->steps = 1; + } + + cleanup(dc); +} + +static void +c_call_event(VALUE trace_point, void *data) +{ + EVENT_SETUP + + dc->calced_stack_size++; + + EVENT_COMMON + + cleanup(dc); +} + +static void +c_return_event(VALUE trace_point, void *data) +{ + EVENT_SETUP + + if (dc->calced_stack_size > 0) dc->calced_stack_size--; + + EVENT_COMMON + + cleanup(dc); +} + +static void +raise_event(VALUE trace_point, void *data) +{ + VALUE expn_class, aclass; + VALUE err; + VALUE ancestors; + int i; + debug_context_t *new_dc; + VALUE binding, path, lineno; + + EVENT_SETUP + + err = rb_errinfo(); + + EVENT_COMMON + + binding = rb_tracearg_binding(trace_arg); + path = rb_tracearg_path(trace_arg); + lineno = rb_tracearg_lineno(trace_arg); + + if (post_mortem == Qtrue) + { + context = context_dup(dc); + rb_ivar_set(err, rb_intern("@__bb_file") , path); + rb_ivar_set(err, rb_intern("@__bb_line") , lineno); + rb_ivar_set(err, rb_intern("@__bb_binding"), binding); + rb_ivar_set(err, rb_intern("@__bb_context"), context); + + Data_Get_Struct(context, debug_context_t, new_dc); + rb_debug_inspector_open(context_backtrace_set, (void *)new_dc); + } + + expn_class = rb_obj_class(err); + + if (catchpoints == Qnil || dc->calced_stack_size == 0 || + CTX_FL_TEST(dc, CTX_FL_CATCHING) || + RHASH_TBL(catchpoints)->num_entries == 0) + { + cleanup(dc); + return; + } + + ancestors = rb_mod_ancestors(expn_class); + for (i = 0; i < RARRAY_LENINT(ancestors); i++) + { + VALUE mod_name; + VALUE hit_count; + + aclass = rb_ary_entry(ancestors, i); + mod_name = rb_mod_name(aclass); + hit_count = rb_hash_aref(catchpoints, mod_name); + + /* increment exception */ + if (hit_count != Qnil) + { + rb_hash_aset(catchpoints, mod_name, INT2FIX(FIX2INT(hit_count) + 1)); + call_at_catchpoint(context, dc, err); + call_at_line(context, dc, path, lineno); + break; + } + } + + cleanup(dc); +} + + +/* Setup TracePoint functionality */ + +static void +register_tracepoints(VALUE self) +{ + int i; + VALUE traces = tracepoints; + + if (NIL_P(traces)) + { + int line_msk = RUBY_EVENT_LINE; + int call_msk = RUBY_EVENT_CALL | RUBY_EVENT_B_CALL | RUBY_EVENT_CLASS; + int return_msk = RUBY_EVENT_RETURN | RUBY_EVENT_B_RETURN | RUBY_EVENT_END; + int c_call_msk = RUBY_EVENT_C_CALL; + int c_return_msk = RUBY_EVENT_C_RETURN; + int raise_msk = RUBY_EVENT_RAISE; + + VALUE tpLine = rb_tracepoint_new(Qnil, line_msk , line_event , 0); + VALUE tpCall = rb_tracepoint_new(Qnil, call_msk , call_event , 0); + VALUE tpReturn = rb_tracepoint_new(Qnil, return_msk , return_event , 0); + VALUE tpCCall = rb_tracepoint_new(Qnil, c_call_msk , c_call_event , 0); + VALUE tpCReturn = rb_tracepoint_new(Qnil, c_return_msk, c_return_event, 0); + VALUE tpRaise = rb_tracepoint_new(Qnil, raise_msk , raise_event , 0); + + traces = rb_ary_new(); + rb_ary_push(traces, tpLine); + rb_ary_push(traces, tpCall); + rb_ary_push(traces, tpReturn); + rb_ary_push(traces, tpCCall); + rb_ary_push(traces, tpCReturn); + rb_ary_push(traces, tpRaise); + + tracepoints = traces; + } + + for (i = 0; i < RARRAY_LENINT(traces); i++) + rb_tracepoint_enable(rb_ary_entry(traces, i)); +} + +static void +clear_tracepoints(VALUE self) +{ + int i; + + for (i = RARRAY_LENINT(tracepoints)-1; i >= 0; i--) + rb_tracepoint_disable(rb_ary_entry(tracepoints, i)); +} + + +/* Byebug's Public API */ + +/* + * call-seq: + * Byebug.contexts -> array + * + * Returns an array of all contexts. + */ +static VALUE +bb_contexts(VALUE self) +{ + volatile VALUE list; + volatile VALUE new_list; + VALUE context; + threads_table_t *t_tbl; + debug_context_t *dc; + int i; + + check_started(); + + new_list = rb_ary_new(); + list = rb_funcall(rb_cThread, rb_intern("list"), 0); + + for (i = 0; i < RARRAY_LENINT(list); i++) + { + VALUE thread = rb_ary_entry(list, i); + thread_context_lookup(thread, &context); + rb_ary_push(new_list, context); + } + + threads_clear(threads); + Data_Get_Struct(threads, threads_table_t, t_tbl); + + for (i = 0; i < RARRAY_LENINT(new_list); i++) + { + context = rb_ary_entry(new_list, i); + Data_Get_Struct(context, debug_context_t, dc); + st_insert(t_tbl->tbl, dc->thread, context); + } + + return new_list; +} + +/* + * call-seq: + * Byebug.thread_context(thread) -> context + * + * Returns context of the thread passed as an argument. + */ +static VALUE +bb_thread_context(VALUE self, VALUE thread) +{ + VALUE context; + + check_started(); + + thread_context_lookup(thread, &context); + + return context; +} + +/* + * call-seq: + * Byebug.current_context -> context + * + * Returns the current context. + * Note: Byebug.current_context.thread == Thread.current + */ +static VALUE +bb_current_context(VALUE self) +{ + VALUE context; + + check_started(); + + thread_context_lookup(rb_thread_current(), &context); + + return context; +} + +/* + * call-seq: + * Byebug.started? -> bool + * + * Returns +true+ byebug is started. + */ +static VALUE +bb_started(VALUE self) +{ + return IS_STARTED; +} + +/* + * call-seq: + * Byebug.stop -> bool + * + * This method disables byebug. It returns +true+ if byebug was already + * disabled, otherwise it returns +false+. + */ +static VALUE +bb_stop(VALUE self) +{ + if (IS_STARTED) + { + clear_tracepoints(self); + + breakpoints = Qnil; + catchpoints = Qnil; + threads = Qnil; + + return Qfalse; + } + return Qtrue; +} + +/* + * call-seq: + * Byebug.start_ -> bool + * Byebug.start_ { ... } -> bool + * + * This method is internal and activates the debugger. Use Byebug.start (from + * lib/byebug.rb) instead. + * + * The return value is the value of !Byebug.started? before issuing the + * +start+; That is, +true+ is returned, unless byebug was previously started. + * + * If a block is given, it starts byebug and yields to block. When the block + * is finished executing it stops the debugger with Byebug.stop method. + */ +static VALUE +bb_start(VALUE self) +{ + VALUE result; + + if (IS_STARTED) + result = Qfalse; + else + { + locker = Qnil; + breakpoints = rb_ary_new(); + catchpoints = rb_hash_new(); + threads = threads_create(); + + register_tracepoints(self); + result = Qtrue; + } + + if (rb_block_given_p()) + rb_ensure(rb_yield, self, bb_stop, self); + + return result; +} + +/* + * call-seq: + * Byebug.debug_load(file, stop = false) -> nil + * + * Same as Kernel#load but resets current context's frames. + * +stop+ parameter forces byebug to stop at the first line of code in +file+ + */ +static VALUE +bb_load(int argc, VALUE *argv, VALUE self) +{ + VALUE file, stop, context; + debug_context_t *dc; + VALUE status = Qnil; + int state = 0; + + if (rb_scan_args(argc, argv, "11", &file, &stop) == 1) + { + stop = Qfalse; + } + + bb_start(self); + + context = bb_current_context(self); + Data_Get_Struct(context, debug_context_t, dc); + + if (RTEST(stop)) dc->steps = 1; + + /* Initializing $0 to the script's path */ + ruby_script(RSTRING_PTR(file)); + rb_load_protect(file, 0, &state); + if (0 != state) + { + status = rb_errinfo(); + reset_stepping_stop_points(dc); + } + + /* We should run all at_exit handler's in order to provide, for instance, a + * chance to run all defined test cases */ + rb_exec_end_proc(); + + return status; +} + +/* + * call-seq: + * Byebug.verbose -> bool + * + * Returns +true+ if verbose output of TracePoint API events is enabled. + */ +static VALUE +bb_verbose(VALUE self) +{ + return verbose; +} + +/* + * call-seq: + * Byebug.verbose = bool + * + * Enable verbose output of every TracePoint API events, useful for debugging + * byebug. + */ +static VALUE +bb_set_verbose(VALUE self, VALUE value) +{ + verbose = RTEST(value) ? Qtrue : Qfalse; + return value; +} + +/* + * call-seq: + * Byebug.tracing -> bool + * + * Returns +true+ if global tracing is enabled. + */ +static VALUE +bb_tracing(VALUE self) +{ + return tracing; +} + +/* + * call-seq: + * Byebug.tracing = bool + * + * Sets the global tracing flag. + */ +static VALUE +bb_set_tracing(VALUE self, VALUE value) +{ + tracing = RTEST(value) ? Qtrue : Qfalse; + return value; +} + +/* + * call-seq: + * Byebug.post_mortem? -> bool + * + * Returns +true+ if post-moterm debugging is enabled. + */ +static VALUE +bb_post_mortem(VALUE self) +{ + return post_mortem; +} + +/* + * call-seq: + * Byebug.post_mortem = bool + * + * Sets post-moterm flag. + */ +static VALUE +bb_set_post_mortem(VALUE self, VALUE value) +{ + post_mortem = RTEST(value) ? Qtrue : Qfalse; + return value; +} + +/* + * call-seq: + * Byebug.breakpoints -> array + * + * Returns an array of breakpoints. + */ +static VALUE +bb_breakpoints(VALUE self) +{ + return breakpoints; +} + +/* + * call-seq: + * Byebug.catchpoints -> array + * + * Returns an array of catchpoints. + */ +static VALUE +bb_catchpoints(VALUE self) +{ + return catchpoints; +} + +/* + * call-seq: + * Byebug.add_catchpoint(exception) -> exception + * + * Adds a new exception to the catchpoints array. + */ +static VALUE +bb_add_catchpoint(VALUE self, VALUE value) +{ + if (TYPE(value) != T_STRING) + rb_raise(rb_eTypeError, "value of a catchpoint must be String"); + + rb_hash_aset(catchpoints, rb_str_dup(value), INT2FIX(0)); + return value; +} + +/* + * Document-class: Byebug + * + * == Summary + * + * This is a singleton class allows controlling byebug. Use it to start/stop + * byebug, set/remove breakpoints, etc. + */ +void +Init_byebug() +{ + mByebug = rb_define_module("Byebug"); + + rb_define_module_function(mByebug, "add_catchpoint" , bb_add_catchpoint , 1); + rb_define_module_function(mByebug, "breakpoints" , bb_breakpoints , 0); + rb_define_module_function(mByebug, "catchpoints" , bb_catchpoints , 0); + rb_define_module_function(mByebug, "contexts" , bb_contexts , 0); + rb_define_module_function(mByebug, "current_context", bb_current_context, 0); + rb_define_module_function(mByebug, "debug_load" , bb_load , -1); + rb_define_module_function(mByebug, "post_mortem?" , bb_post_mortem , 0); + rb_define_module_function(mByebug, "post_mortem=" , bb_set_post_mortem, 1); + rb_define_module_function(mByebug, "_start" , bb_start , 0); + rb_define_module_function(mByebug, "started?" , bb_started , 0); + rb_define_module_function(mByebug, "stop" , bb_stop , 0); + rb_define_module_function(mByebug, "thread_context" , bb_thread_context , 1); + rb_define_module_function(mByebug, "tracing?" , bb_tracing , 0); + rb_define_module_function(mByebug, "tracing=" , bb_set_tracing , 1); + rb_define_module_function(mByebug, "verbose" , bb_verbose , 0); + rb_define_module_function(mByebug, "verbose=" , bb_set_verbose , 1); + + cThreadsTable = rb_define_class_under(mByebug, "ThreadsTable", rb_cObject); + + Init_context(mByebug); + Init_breakpoint(mByebug); + + rb_global_variable(&breakpoints); + rb_global_variable(&catchpoints); + rb_global_variable(&tracepoints); + rb_global_variable(&threads); +} diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.h b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.h new file mode 100644 index 0000000..e7767ac --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.h @@ -0,0 +1,128 @@ +#ifndef BYEBUG +#define BYEBUG + +#include +#include + +/* flags */ +#define CTX_FL_CATCHING (1<<1) /* catching of exceptions enabled */ +#define CTX_FL_DEAD (1<<2) /* this context belonged to a dead thread */ +#define CTX_FL_ENABLE_BKPT (1<<3) /* cab check for breakpoints */ +#define CTX_FL_FORCE_MOVE (1<<4) /* don't stop unless we've changed line */ +#define CTX_FL_IGNORE (1<<5) /* this context belongs to ignored thread */ +#define CTX_FL_SUSPEND (1<<6) /* thread currently suspended */ +#define CTX_FL_TRACING (1<<7) /* call at_tracing method */ +#define CTX_FL_WAS_RUNNING (1<<8) /* thread was previously running */ + +/* macro functions */ +#define CTX_FL_TEST(c,f) ((c)->flags & (f)) +#define CTX_FL_SET(c,f) do { (c)->flags |= (f); } while (0) +#define CTX_FL_UNSET(c,f) do { (c)->flags &= ~(f); } while (0) + +/* types */ +typedef enum { + CTX_STOP_NONE, + CTX_STOP_STEP, + CTX_STOP_BREAKPOINT, + CTX_STOP_CATCHPOINT +} ctx_stop_reason; + +typedef struct { + int calced_stack_size; + int flags; + ctx_stop_reason stop_reason; + + VALUE thread; + int thnum; + + int dest_frame; + int lines; /* # of lines in dest_frame before stopping */ + int steps; /* # of steps before stopping */ + int after_frame; /* stop right after returning from this frame */ + int before_frame; /* stop right before returning from this frame */ + + VALUE last_file; + VALUE last_line; + + VALUE backtrace; /* [[loc, self, klass, binding], ...] */ +} debug_context_t; + +enum frame_component { LOCATION, SELF, CLASS, BINDING }; + +struct call_with_inspection_data { + debug_context_t *dc; + VALUE context_obj; + ID id; + int argc; + VALUE *argv; +}; + +typedef struct { + st_table *tbl; +} threads_table_t; + +/* functions from locker.c */ +extern int is_in_locked(VALUE thread_id); +extern void add_to_locked(VALUE thread); +extern VALUE remove_from_locked(); + +/* functions from threads.c */ +extern VALUE threads_create(void); +extern void threads_clear(VALUE table); +extern void check_thread_contexts(void); +extern void thread_context_lookup(VALUE thread, VALUE *context); +extern void halt_while_other_thread_is_active(debug_context_t *dc); + +/* global variables */ +extern VALUE locker; +extern VALUE threads; +extern VALUE cThreadsTable; + +/* functions */ +extern void Init_context(VALUE mByebug); +extern VALUE context_create(VALUE thread); +extern VALUE context_dup(debug_context_t *context); +extern void reset_stepping_stop_points(debug_context_t *context); +extern VALUE call_with_debug_inspector(struct call_with_inspection_data *data); +extern VALUE context_backtrace_set(const rb_debug_inspector_t *inspector, + void *data); + +static inline int +classname_cmp(VALUE name, VALUE klass) +{ + VALUE mod_name; + VALUE class_name = (Qnil == name) ? rb_str_new2("main") : name; + if (klass == Qnil) return(0); + mod_name = rb_mod_name(klass); + return (mod_name != Qnil && rb_str_cmp(class_name, mod_name) == 0); +} + +/* breakpoints & catchpoints */ +enum bp_type { BP_POS_TYPE, BP_METHOD_TYPE }; + +enum hit_condition { HIT_COND_NONE, HIT_COND_GE, HIT_COND_EQ, HIT_COND_MOD }; + +typedef struct { + int id; + enum bp_type type; + VALUE source; + union + { + int line; + ID mid; + } pos; + VALUE expr; + VALUE enabled; + int hit_count; + int hit_value; + enum hit_condition hit_condition; +} breakpoint_t; + +extern VALUE catchpoint_hit_count(VALUE catchpoints, VALUE exception, VALUE *exception_name); +extern VALUE find_breakpoint_by_pos(VALUE breakpoints, VALUE source, VALUE pos, + VALUE binding); +extern VALUE find_breakpoint_by_method(VALUE breakpoints, VALUE klass, + VALUE mid, VALUE binding, VALUE self); +extern void Init_breakpoint(VALUE mByebug); + +#endif diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.o b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.o new file mode 100644 index 0000000..ecd14f6 Binary files /dev/null and b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.o differ diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.so b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.so new file mode 100755 index 0000000..c19cfc8 Binary files /dev/null and b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.so differ diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.c b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.c new file mode 100644 index 0000000..4804fcd --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.c @@ -0,0 +1,660 @@ +#include + +static VALUE cContext; +static VALUE cDebugThread; +static int thnum_max = 0; + +/* "Step", "Next" and "Finish" do their work by saving information about where + * to stop next. reset_stepping_stop_points removes/resets this information. */ +extern void +reset_stepping_stop_points(debug_context_t *context) +{ + context->dest_frame = -1; + context->lines = -1; + context->steps = -1; + context->after_frame = -1; + context->before_frame = -1; +} + +/* + * call-seq: + * context.dead? -> bool + * + * Returns +true+ if context doesn't represent a live context and is created + * during post-mortem exception handling. + */ +static inline VALUE +Context_dead(VALUE self) +{ + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + return CTX_FL_TEST(context, CTX_FL_DEAD) ? Qtrue : Qfalse; +} + +static void +context_mark(void *data) +{ + debug_context_t *context = (debug_context_t *)data; + rb_gc_mark(context->backtrace); +} + +static void +context_free(void *data) +{ + +} + +static int +real_stack_size() +{ + return FIX2INT(rb_funcall(cContext, rb_intern("real_stack_size"), 0)); +} + +extern VALUE +context_create(VALUE thread) +{ + debug_context_t *context = ALLOC(debug_context_t); + + context->last_file = Qnil; + context->last_line = Qnil; + context->flags = 0; + context->calced_stack_size = real_stack_size(); + context->thnum = ++thnum_max; + context->thread = thread; + reset_stepping_stop_points(context); + context->stop_reason = CTX_STOP_NONE; + context->backtrace = Qnil; + + if (rb_obj_class(thread) == cDebugThread) CTX_FL_SET(context, CTX_FL_IGNORE); + + return Data_Wrap_Struct(cContext, context_mark, context_free, context); +} + +extern VALUE +context_dup(debug_context_t *context) +{ + debug_context_t *new_context = ALLOC(debug_context_t); + + memcpy(new_context, context, sizeof(debug_context_t)); + reset_stepping_stop_points(new_context); + new_context->backtrace = context->backtrace; + CTX_FL_SET(new_context, CTX_FL_DEAD); + + return Data_Wrap_Struct(cContext, context_mark, context_free, new_context); +} + +static VALUE +dc_backtrace(const debug_context_t *context) +{ + return context->backtrace; +} + +static VALUE +dc_frame_get(const debug_context_t *context, int frame_index, + enum frame_component type) +{ + VALUE frame; + + if (NIL_P(dc_backtrace(context))) + rb_raise(rb_eRuntimeError, "Backtrace information is not available"); + + if (frame_index >= RARRAY_LENINT(dc_backtrace(context))) + rb_raise(rb_eRuntimeError, "That frame doesn't exist!"); + + frame = rb_ary_entry(dc_backtrace(context), frame_index); + return rb_ary_entry(frame, type); +} + +static VALUE +dc_frame_location(const debug_context_t *context, int frame_index) +{ + return dc_frame_get(context, frame_index, LOCATION); +} + +static VALUE +dc_frame_self(const debug_context_t *context, int frame_index) +{ + return dc_frame_get(context, frame_index, SELF); +} + +static VALUE +dc_frame_class(const debug_context_t *context, int frame_index) +{ + return dc_frame_get(context, frame_index, CLASS); +} + +static VALUE +dc_frame_binding(const debug_context_t *context, int frame_index) +{ + return dc_frame_get(context, frame_index, BINDING); +} + +static VALUE +load_backtrace(const rb_debug_inspector_t *inspector) +{ + VALUE backtrace = rb_ary_new(); + VALUE locs = rb_debug_inspector_backtrace_locations(inspector); + int i; + + for (i=0; ibacktrace = load_backtrace(inspector); + + return Qnil; +} + +static VALUE +open_debug_inspector_i(const rb_debug_inspector_t *inspector, void *data) +{ + struct call_with_inspection_data *cwi = + (struct call_with_inspection_data *)data; + cwi->dc->backtrace = load_backtrace(inspector); + + return rb_funcall2(cwi->context_obj, cwi->id, cwi->argc, cwi->argv); +} + +static VALUE +open_debug_inspector(struct call_with_inspection_data *cwi) +{ + return rb_debug_inspector_open(open_debug_inspector_i, cwi); +} + +static VALUE +close_debug_inspector(struct call_with_inspection_data *cwi) +{ + cwi->dc->backtrace = Qnil; + return Qnil; +} + +extern VALUE +call_with_debug_inspector(struct call_with_inspection_data *data) +{ + return rb_ensure(open_debug_inspector, (VALUE)data, + close_debug_inspector, (VALUE)data); +} + +#define FRAME_SETUP \ + debug_context_t *context; \ + VALUE frame_no; \ + int frame_n, stack_size; \ + Data_Get_Struct(self, debug_context_t, context); \ + if (!rb_scan_args(argc, argv, "01", &frame_no)) \ + frame_n = 0; \ + else \ + frame_n = FIX2INT(frame_no); \ + stack_size = real_stack_size(); \ + if (frame_n < 0 || frame_n >= stack_size) \ + { \ + rb_raise(rb_eArgError, "Invalid frame number %d, stack (0...%d)", \ + frame_n, stack_size - 1); \ + } \ + +/* + * call-seq: + * context.frame_binding(frame_position=0) -> binding + * + * Returns frame's binding. + */ +static VALUE +Context_frame_binding(int argc, VALUE *argv, VALUE self) +{ + FRAME_SETUP + + return dc_frame_binding(context, frame_n); +} + +/* + * call-seq: + * context.frame_class(frame_position=0) -> binding + * + * Returns frame's defined class. + */ + static VALUE +Context_frame_class(int argc, VALUE *argv, VALUE self) +{ + FRAME_SETUP + + return dc_frame_class(context, frame_n); +} + +/* + * call-seq: + * context.frame_file(frame_position=0) -> string + * + * Returns the name of the file in the frame. + */ +static VALUE +Context_frame_file(int argc, VALUE *argv, VALUE self) +{ + VALUE loc; + + FRAME_SETUP + + loc = dc_frame_location(context, frame_n); + + return rb_funcall(loc, rb_intern("path"), 0); +} + +/* + * call-seq: + * context.frame_line(frame_position) -> int + * + * Returns the line number in the file. + */ +static VALUE +Context_frame_line(int argc, VALUE *argv, VALUE self) +{ + VALUE loc; + + FRAME_SETUP + + loc = dc_frame_location(context, frame_n); + + return rb_funcall(loc, rb_intern("lineno"), 0); +} + +/* + * call-seq: + * context.frame_method(frame_position=0) -> sym + * + * Returns the sym of the called method. + */ +static VALUE +Context_frame_method(int argc, VALUE *argv, VALUE self) +{ + VALUE loc; + + FRAME_SETUP + + loc = dc_frame_location(context, frame_n); + + return rb_str_intern(rb_funcall(loc, rb_intern("label"), 0)); +} + +/* + * call-seq: + * context.frame_self(frame_postion=0) -> obj + * + * Returns self object of the frame. + */ +static VALUE +Context_frame_self(int argc, VALUE *argv, VALUE self) +{ + FRAME_SETUP + + return dc_frame_self(context, frame_n); +} + +/* + * call-seq: + * context.ignored? -> bool + * + * Returns the ignore flag for the context, which marks whether the associated + * thread is ignored while debugging. + */ +static inline VALUE +Context_ignored(VALUE self) +{ + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + return CTX_FL_TEST(context, CTX_FL_IGNORE) ? Qtrue : Qfalse; +} + +static void +context_resume_0(debug_context_t *context) +{ + if (!CTX_FL_TEST(context, CTX_FL_SUSPEND)) return; + + CTX_FL_UNSET(context, CTX_FL_SUSPEND); + + if (CTX_FL_TEST(context, CTX_FL_WAS_RUNNING)) + rb_thread_wakeup(context->thread); +} + +/* + * call-seq: + * context.resume -> nil + * + * Resumes thread from the suspended mode. + */ +static VALUE +Context_resume(VALUE self) +{ + debug_context_t *context; + + Data_Get_Struct(self, debug_context_t, context); + + if (!CTX_FL_TEST(context, CTX_FL_SUSPEND)) + rb_raise(rb_eRuntimeError, "Thread is not suspended."); + + context_resume_0(context); + + return Qnil; +} + +/* + * call-seq: + * context.calced_stack_size-> int + * + * Returns the calculated size of the context stack. + * + * NOTE: it shouldn't be necessary to expose this, this is only done to ease + * the detection of TracePoint API bugs. + */ +static inline VALUE +Context_calced_stack_size(VALUE self) +{ + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + + return INT2FIX(context->calced_stack_size); +} + +static VALUE +Context_stop_reason(VALUE self) +{ + debug_context_t *context; + const char *symbol; + + Data_Get_Struct(self, debug_context_t, context); + + if (CTX_FL_TEST(context, CTX_FL_DEAD)) + symbol = "post-mortem"; + else switch (context->stop_reason) + { + case CTX_STOP_STEP: + symbol = "step"; + break; + case CTX_STOP_BREAKPOINT: + symbol = "breakpoint"; + break; + case CTX_STOP_CATCHPOINT: + symbol = "catchpoint"; + break; + case CTX_STOP_NONE: + default: + symbol = "none"; + } + return ID2SYM(rb_intern(symbol)); +} + +/* + * call-seq: + * context.step_into(steps, force = false) + * + * Stops the current context after a number of +steps+ are made. + * +force+ parameter (if true) ensures that the cursor moves away from the + * current line. + */ +static VALUE +Context_step_into(int argc, VALUE *argv, VALUE self) +{ + VALUE steps; + VALUE force; + debug_context_t *context; + + rb_scan_args(argc, argv, "11", &steps, &force); + if (FIX2INT(steps) < 0) + rb_raise(rb_eRuntimeError, "Steps argument can't be negative."); + + Data_Get_Struct(self, debug_context_t, context); + context->steps = FIX2INT(steps); + + if (RTEST(force)) + CTX_FL_SET(context, CTX_FL_FORCE_MOVE); + else + CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE); + + return steps; +} + +/* + * call-seq: + * context.step_out(frame) + * + * Stops after frame number +frame+ is activated. Implements +finish+ and + * +next+ commands. + */ +static VALUE +Context_step_out(VALUE self, VALUE frame) +{ + debug_context_t *context; + + Data_Get_Struct(self, debug_context_t, context); + + if (FIX2INT(frame) < 0 || FIX2INT(frame) >= context->calced_stack_size) + rb_raise(rb_eRuntimeError, "Stop frame is out of range."); + + context->after_frame = context->calced_stack_size - FIX2INT(frame); + + return frame; +} + +/* + * call-seq: + * context.step_over(lines, frame = nil, force = false) + * + * Steps over +lines+ lines. + * Make step over operation on +frame+, by default the current frame. + * +force+ parameter (if true) ensures that the cursor moves away from the + * current line. + */ +static VALUE +Context_step_over(int argc, VALUE *argv, VALUE self) +{ + VALUE lines, frame, force; + debug_context_t *context; + + Data_Get_Struct(self, debug_context_t, context); + + if (context->calced_stack_size == 0) + rb_raise(rb_eRuntimeError, "No frames collected."); + + rb_scan_args(argc, argv, "12", &lines, &frame, &force); + if (FIX2INT(frame) < 0 || FIX2INT(frame) >= context->calced_stack_size) + rb_raise(rb_eRuntimeError, "Destination frame is out of range."); + + context->lines = FIX2INT(lines); + context->dest_frame = context->calced_stack_size - FIX2INT(frame); + + if (RTEST(force)) + CTX_FL_SET(context, CTX_FL_FORCE_MOVE); + else + CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE); + + return Qnil; +} + +/* + * call-seq: + * context.stop_return(frame) + * + * Stops before frame number +frame+ is activated. Useful when you enter the + * debugger after the last statement in a method. + */ +static VALUE +Context_stop_return(VALUE self, VALUE frame) +{ + debug_context_t *context; + + Data_Get_Struct(self, debug_context_t, context); + if (FIX2INT(frame) < 0 || FIX2INT(frame) >= context->calced_stack_size) + rb_raise(rb_eRuntimeError, "Stop frame is out of range."); + + context->before_frame = context->calced_stack_size - FIX2INT(frame); + + return frame; +} + +static void +context_suspend_0(debug_context_t *context) +{ + VALUE status = rb_funcall(context->thread, rb_intern("status"), 0); + + if (rb_str_cmp(status, rb_str_new2("run")) == 0) + CTX_FL_SET(context, CTX_FL_WAS_RUNNING); + else if (rb_str_cmp(status, rb_str_new2("sleep")) == 0) + CTX_FL_UNSET(context, CTX_FL_WAS_RUNNING); + else + return; + + CTX_FL_SET(context, CTX_FL_SUSPEND); +} + +/* + * call-seq: + * context.suspend -> nil + * + * Suspends the thread when it is running. + */ +static VALUE +Context_suspend(VALUE self) +{ + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + + if (CTX_FL_TEST(context, CTX_FL_SUSPEND)) + rb_raise(rb_eRuntimeError, "Already suspended."); + + context_suspend_0(context); + return Qnil; +} + +/* + * call-seq: + * context.suspended? -> bool + * + * Returns +true+ if the thread is suspended by debugger. + */ +static VALUE +Context_is_suspended(VALUE self) +{ + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + + return CTX_FL_TEST(context, CTX_FL_SUSPEND) ? Qtrue : Qfalse; +} + +/* + * call-seq: + * context.thnum -> int + * + * Returns the context's number. + */ +static inline VALUE +Context_thnum(VALUE self) { + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + return INT2FIX(context->thnum); +} + +/* + * call-seq: + * context.thread -> thread + * + * Returns the thread this context is associated with. + */ +static inline VALUE +Context_thread(VALUE self) +{ + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + return context->thread; +} + +/* + * call-seq: + * context.tracing -> bool + * + * Returns the tracing flag for the current context. + */ +static VALUE +Context_tracing(VALUE self) +{ + debug_context_t *context; + + Data_Get_Struct(self, debug_context_t, context); + return CTX_FL_TEST(context, CTX_FL_TRACING) ? Qtrue : Qfalse; +} + +/* + * call-seq: + * context.tracing = bool + * + * Controls the tracing for this context. + */ +static VALUE +Context_set_tracing(VALUE self, VALUE value) +{ + debug_context_t *context; + + Data_Get_Struct(self, debug_context_t, context); + + if (RTEST(value)) + CTX_FL_SET(context, CTX_FL_TRACING); + else + CTX_FL_UNSET(context, CTX_FL_TRACING); + return value; +} + + +/* :nodoc: */ +static VALUE +DebugThread_inherited(VALUE klass) +{ + rb_raise(rb_eRuntimeError, "Can't inherit Byebug::DebugThread class"); +} + +/* + * Document-class: Context + * + * == Summary + * + * Byebug keeps a single instance of this class. + */ +void +Init_context(VALUE mByebug) +{ + cContext = rb_define_class_under(mByebug, "Context", rb_cObject); + + rb_define_method(cContext, "dead?" , Context_dead , 0); + rb_define_method(cContext, "frame_binding" , Context_frame_binding , -1); + rb_define_method(cContext, "frame_class" , Context_frame_class , -1); + rb_define_method(cContext, "frame_file" , Context_frame_file , -1); + rb_define_method(cContext, "frame_line" , Context_frame_line , -1); + rb_define_method(cContext, "frame_method" , Context_frame_method , -1); + rb_define_method(cContext, "frame_self" , Context_frame_self , -1); + rb_define_method(cContext, "ignored?" , Context_ignored , 0); + rb_define_method(cContext, "resume" , Context_resume , 0); + rb_define_method(cContext, "calced_stack_size", Context_calced_stack_size, 0); + rb_define_method(cContext, "step_into" , Context_step_into , -1); + rb_define_method(cContext, "step_out" , Context_step_out , 1); + rb_define_method(cContext, "step_over" , Context_step_over , -1); + rb_define_method(cContext, "stop_return" , Context_stop_return , 1); + rb_define_method(cContext, "stop_reason" , Context_stop_reason , 0); + rb_define_method(cContext, "suspend" , Context_suspend , 0); + rb_define_method(cContext, "suspended?" , Context_is_suspended , 0); + rb_define_method(cContext, "thnum" , Context_thnum , 0); + rb_define_method(cContext, "thread" , Context_thread , 0); + rb_define_method(cContext, "tracing" , Context_tracing , 0); + rb_define_method(cContext, "tracing=" , Context_set_tracing , 1); + + cDebugThread = rb_define_class_under(mByebug, "DebugThread", rb_cThread); + rb_define_singleton_method(cDebugThread, "inherited", DebugThread_inherited, 1); +} diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.o b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.o new file mode 100644 index 0000000..6d641ec Binary files /dev/null and b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.o differ diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/extconf.rb b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/extconf.rb new file mode 100644 index 0000000..2201533 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/extconf.rb @@ -0,0 +1,17 @@ +require 'mkmf' + +RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC'] + +if RUBY_VERSION < "2.0" + STDERR.print("Ruby version is too old\n") + exit(1) +end + +if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/ + $CFLAGS ||= '' + $CFLAGS += ' -Wall -Werror -Wno-unused-parameter' + $CFLAGS += ' -gdwarf-2 -g3 -O0' if ENV['debug'] +end + +dir_config("ruby") +create_makefile('byebug/byebug') diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.c b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.c new file mode 100644 index 0000000..22cd9fc --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.c @@ -0,0 +1,54 @@ +#include + +typedef struct locked_thread_t { + VALUE thread; + struct locked_thread_t *next; +} locked_thread_t; + +static locked_thread_t *locked_head = NULL; +static locked_thread_t *locked_tail = NULL; + +extern int +is_in_locked(VALUE thread) +{ + locked_thread_t *node; + + if (!locked_head) return 0; + + for (node = locked_head; node != locked_tail; node = node->next) + { + if (node->thread == thread) return 1; + } + return 0; +} + +extern void +add_to_locked(VALUE thread) +{ + locked_thread_t *node; + + if (is_in_locked(thread)) return; + + node = ALLOC(locked_thread_t); + node->thread = thread; + node->next = NULL; + if (locked_tail) locked_tail->next = node; + locked_tail = node; + if (!locked_head) locked_head = node; +} + +extern VALUE +remove_from_locked() +{ + VALUE thread; + locked_thread_t *node; + + if (locked_head == NULL) return Qnil; + + node = locked_head; + locked_head = locked_head->next; + if (locked_tail == node) locked_tail = NULL; + thread = node->thread; + xfree(node); + return thread; +} diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.o b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.o new file mode 100644 index 0000000..f6150ea Binary files /dev/null and b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.o differ diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.c b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.c new file mode 100644 index 0000000..e1732cc --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.c @@ -0,0 +1,113 @@ +#include + +static int +t_tbl_mark_keyvalue(st_data_t key, st_data_t value, st_data_t tbl) +{ + VALUE thread = (VALUE)key; + + if (!value) return ST_CONTINUE; + + rb_gc_mark((VALUE)value); + rb_gc_mark(thread); + + return ST_CONTINUE; +} + +static void +t_tbl_mark(void* data) +{ + threads_table_t *t_tbl = (threads_table_t *)data; + st_table *tbl = t_tbl->tbl; + st_foreach(tbl, t_tbl_mark_keyvalue, (st_data_t)tbl); +} + +static void +t_tbl_free(void* data) +{ + threads_table_t *t_tbl = (threads_table_t*)data; + st_free_table(t_tbl->tbl); + xfree(t_tbl); +} + +VALUE +threads_create(void) +{ + threads_table_t *t_tbl; + + t_tbl = ALLOC(threads_table_t); + t_tbl->tbl = st_init_numtable(); + return Data_Wrap_Struct(cThreadsTable, t_tbl_mark, t_tbl_free, t_tbl); +} + +void +threads_clear(VALUE table) +{ + threads_table_t *t_tbl; + + Data_Get_Struct(table, threads_table_t, t_tbl); + st_clear(t_tbl->tbl); +} + +static int +is_living_thread(VALUE thread) +{ + return rb_funcall(thread, rb_intern("alive?"), 0) == Qtrue; +} + +static int +t_tbl_check_i(st_data_t key, st_data_t value, st_data_t dummy) +{ + VALUE thread; + + if (!value) return ST_DELETE; + + thread = (VALUE)key; + + if (!is_living_thread(thread)) return ST_DELETE; + + return ST_CONTINUE; +} + +void +check_thread_contexts(void) +{ + threads_table_t *t_tbl; + + Data_Get_Struct(threads, threads_table_t, t_tbl); + st_foreach(t_tbl->tbl, t_tbl_check_i, 0); +} + +void +thread_context_lookup(VALUE thread, VALUE *context) +{ + threads_table_t *t_tbl; + + Data_Get_Struct(threads, threads_table_t, t_tbl); + if (!st_lookup(t_tbl->tbl, thread, context) || !*context) + { + *context = context_create(thread); + st_insert(t_tbl->tbl, thread, *context); + } +} + +void +halt_while_other_thread_is_active(debug_context_t *dc) +{ + while (1) + { + /* halt execution of current thread if debugger is activated in another */ + while (locker != Qnil && locker != rb_thread_current()) + { + add_to_locked(rb_thread_current()); + rb_thread_stop(); + } + + /* stop the current thread if it's marked as suspended */ + if (CTX_FL_TEST(dc, CTX_FL_SUSPEND) && locker != rb_thread_current()) + { + CTX_FL_SET(dc, CTX_FL_WAS_RUNNING); + rb_thread_stop(); + } + else break; + } +} diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.o b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.o new file mode 100644 index 0000000..095ea64 Binary files /dev/null and b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.o differ diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug.rb new file mode 100644 index 0000000..7916d88 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug.rb @@ -0,0 +1,201 @@ +require 'byebug/byebug' +require 'byebug/version' +require 'byebug/context' +require 'byebug/processor' +require 'byebug/command_processor' +require 'byebug/control_command_processor' +require 'byebug/remote' +require 'stringio' +require 'tracer' +require 'linecache19' + +module Byebug + + # List of files byebug will ignore while debugging + IGNORED_FILES = Dir.glob(File.expand_path('../**/*.rb', __FILE__)) + + # Default options to Byebug.start + DEFAULT_START_SETTINGS = { + init: true, # Set $0 and save ARGV? + post_mortem: false, # post-mortem debugging on uncaught exception? + tracing: nil # Byebug.tracing? value. true/false resets + } unless defined?(DEFAULT_START_SETTINGS) + + # Configuration file used for startup commands. Default value is .byebugrc + INITFILE = '.byebugrc' unless defined?(INITFILE) + + class << self + + # processor modules provide +handler+ object + attr_accessor :handler + Byebug.handler = CommandProcessor.new + + attr_accessor :last_exception + Byebug.last_exception = nil + + def source_reload + Object.send(:remove_const, 'SCRIPT_LINES__') if + Object.const_defined?('SCRIPT_LINES__') + Object.const_set('SCRIPT_LINES__', {}) + end + + # + # Get line +line_number+ from file named +filename+. + # + # @return "\n" if there was a problem. Leaking blanks are stripped off. + # + def line_at(filename, line_number) + source_reload + + return "\n" unless File.exist?(filename) + line = Tracer::Single.get_line(filename, line_number) + + return "#{line.gsub(/^\s+/, '').chomp}" + end + + # + # Add a new breakpoint + # + # @param [String] file + # @param [Fixnum] line + # @param [String] expr + # + def add_breakpoint(file, line, expr=nil) + breakpoint = Breakpoint.new(file, line, expr) + breakpoints << breakpoint + breakpoint + end + + # + # Remove a breakpoint + # + # @param [integer] breakpoint number + # + def remove_breakpoint(id) + breakpoints.reject! { |b| b.id == id } + end + + def interface=(value) + handler.interface = value + end + + extend Forwardable + def_delegators :"handler.interface", :print + + # + # Byebug.start(options) -> bool + # Byebug.start(options) { ... } -> obj + # + # If it's called without a block, it returns +true+ unless byebug was + # already started. + # + # If a block is given, it starts byebug and yields block. After the block is + # executed it stops byebug with Byebug.stop method. Inside the block you + # will probably want to have a call to Byebug.byebug. For example: + # + # Byebug.start { byebug; foo } # Stop inside of foo + # + # Also, byebug only allows one invocation of byebug at a time; nested + # Byebug.start's have no effect and you can't use this inside byebug itself. + # + # Note that if you want to stop byebug, you must call Byebug.stop as + # many times as you called Byebug.start method. + # + # +options+ is a hash used to set various debugging options. + # :init - true if you want to save ARGV and some other variables to + # make a byebug restart possible. Only the first time :init + # is set to true the values will get set. Since ARGV is + # saved, you should make sure it hasn't been changed before + # the (first) call. + # :post_mortem - true if you want to enter post-mortem debugging on an + # uncaught exception. Once post-mortem debugging is set, it + # can't be unset. + # + def start(options={}, &block) + options = Byebug::DEFAULT_START_SETTINGS.merge(options) + if options[:init] + Byebug.const_set('ARGV', ARGV.clone) unless defined? Byebug::ARGV + Byebug.const_set('PROG_SCRIPT', $0) unless defined? Byebug::PROG_SCRIPT + Byebug.const_set('INITIAL_DIR', Dir.pwd) unless defined? Byebug::INITIAL_DIR + end + Byebug.tracing = options[:tracing] unless options[:tracing].nil? + retval = Byebug._start(&block) + post_mortem if options[:post_mortem] + return retval + end + + # + # Runs normal byebug initialization scripts. + # + # Reads and executes the commands from init file (if any) in the current + # working directory. This is only done if the current directory is + # different from your home directory. Thus, you can have more than one init + # file, one generic in your home directory, and another, specific to the + # program you are debugging, in the directory where you invoke byebug. + # + def run_init_script(out = handler.interface) + cwd_script = File.expand_path(File.join(".", INITFILE)) + run_script(cwd_script, out) if File.exist?(cwd_script) + + home_script = File.expand_path(File.join(ENV['HOME'].to_s, INITFILE)) + if File.exist?(home_script) and cwd_script != home_script + run_script(home_script, out) + end + end + + # + # Runs a script file + # + def run_script(file, out = handler.interface, verbose=false) + interface = ScriptInterface.new(File.expand_path(file), out) + processor = ControlCommandProcessor.new(interface) + processor.process_commands(verbose) + end + + # + # Activates the post-mortem mode. + # + # By calling Byebug.post_mortem method, you install an at_exit hook that + # intercepts any exception not handled by your script and enables + # post-mortem mode. + # + def post_mortem + return if self.post_mortem? + at_exit { handle_post_mortem($!) if post_mortem? } + self.post_mortem = true + end + + def handle_post_mortem(exp) + return if !exp + Byebug.last_exception = exp + return if !exp.__bb_context || !exp.__bb_context.calced_stack_size + orig_tracing = Byebug.tracing? + Byebug.tracing = false + handler.at_line(exp.__bb_context, exp.__bb_file, exp.__bb_line) + ensure + Byebug.tracing = orig_tracing + end + private :handle_post_mortem + end +end + +class Exception + attr_reader :__bb_file, :__bb_line, :__bb_binding, :__bb_context +end + +module Kernel + # + # Enters byebug after _steps_into_ line events and _steps_out_ return events + # occur. Before entering byebug startup, the init script is read. + # + def byebug(steps_into = 1, steps_out = 2) + Byebug.start + Byebug.run_init_script(StringIO.new) + if Byebug.current_context.calced_stack_size > 2 + Byebug.current_context.stop_return steps_out if steps_out >= 1 + end + Byebug.current_context.step_into steps_into if steps_into >= 0 + end + + alias_method :debugger, :byebug +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/command.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/command.rb new file mode 100644 index 0000000..9afcda4 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/command.rb @@ -0,0 +1,229 @@ +require 'columnize' +require 'forwardable' +require_relative 'helper' + +module Byebug + + module CommandFunctions + # + # Pad a string with dots at the end to fit :width setting + # + def pad_with_dots(string) + if string.size > Command.settings[:width] + string[Command.settings[:width]-3 .. -1] = "..." + end + end + end + + class Command + Subcmd = Struct.new(:name, :min, :help) + + class << self + def commands + @commands ||= [] + end + + attr_accessor :allow_in_control, :unknown, :need_context + attr_writer :allow_in_post_mortem, :always_run + + def allow_in_post_mortem + @allow_in_post_mortem ||= !defined?(@allow_in_post_mortem) ? true : false + end + + def always_run + @always_run ||= 0 + end + + def help(args) + if args && args[1] + output = format_subcmd(args[1]) + else + output = description.gsub(/^ +/, '') + "\n" + output += format_subcmds if defined? self::Subcommands + end + output + end + + def find(subcmds, param) + param.downcase! + for try_subcmd in subcmds do + if (param.size >= try_subcmd.min) and + (try_subcmd.name[0..param.size-1] == param) + return try_subcmd + end + end + return nil + end + + def format_subcmd(subcmd_name) + subcmd = find(self::Subcommands, subcmd_name) + return "Invalid \"#{names.join("|")}\" " \ + "subcommand \"#{args[1]}\"." unless subcmd + + return "#{subcmd.help}.\n" + end + + def format_subcmds + cmd_name = names.join("|") + s = "\n" \ + "--\n" \ + "List of \"#{cmd_name}\" subcommands:\n" \ + "--\n" + w = self::Subcommands.map(&:name).max_by(&:size).size + for subcmd in self::Subcommands do + s += sprintf "%s %-#{w}s -- %s\n", cmd_name, subcmd.name, subcmd.help + end + return s + end + + def inherited(klass) + commands << klass + end + + def load_commands + Dir[File.join(File.dirname(__FILE__), 'commands', '*')].each { + |file| require file } + Byebug.constants.grep(/Functions$/).map { + |name| Byebug.const_get(name) }.each { |mod| include mod } + end + + def settings_map + @@settings_map ||= {} + end + private :settings_map + + def settings + unless defined? @settings and @settings + @settings = Object.new + map = settings_map + c = class << @settings; self end + c.send(:define_method, :[]) do |name| + raise "No such setting #{name}" unless map.has_key?(name) + map[name][:getter].call + end + c.send(:define_method, :[]=) do |name, value| + raise "No such setting #{name}" unless map.has_key?(name) + map[name][:setter].call(value) + end + end + @settings + end + + def register_setting_var(name, default) + var_name = "@@#{name}" + class_variable_set(var_name, default) + register_setting_get(name) { class_variable_get(var_name) } + register_setting_set(name) { |value| class_variable_set(var_name, value) } + end + + def register_setting_get(name, &block) + settings_map[name] ||= {} + settings_map[name][:getter] = block + end + + def register_setting_set(name, &block) + settings_map[name] ||= {} + settings_map[name][:setter] = block + end + + def command_exists?(command) + ENV['PATH'].split(File::PATH_SEPARATOR).any? { + |d| File.exist? File.join(d, command) } + end + + def terminal_width + if ENV['COLUMNS'] =~ /^\d+$/ + ENV['COLUMNS'].to_i + elsif STDIN.tty? && command_exists?('stty') + `stty size`.scan(/\d+/)[1].to_i + else + nil + end + end + end + + # Register default settings + register_setting_var(:basename, false) + register_setting_var(:callstyle, :long) + register_setting_var(:testing, false) + register_setting_var(:forcestep, false) + register_setting_var(:fullpath, true) + register_setting_var(:listsize, 10) + register_setting_var(:stack_on_error, false) + register_setting_var(:linetrace_plus, false) + cols = terminal_width || 160 + register_setting_var(:width, cols > 10 ? cols : 160) + Byebug::ARGV = ARGV.clone unless defined? Byebug::ARGV + register_setting_var(:argv, Byebug::ARGV) + + def initialize(state) + @match, @state = nil, state + end + + def match(input) + @match = regexp.match(input) + end + + protected + + extend Forwardable + def_delegators :@state, :errmsg, :print + + def confirm(msg) + @state.confirm(msg) == 'y' + end + + def bb_eval(str, b = get_binding) + begin + eval(str, b) + rescue StandardError, ScriptError => e + at = eval('Thread.current.backtrace_locations(1)', b) + print "#{at.shift}: #{e.class} Exception(#{e.message})\n" + for i in at + print "\tfrom #{i}\n" + end + nil + end + end + + def bb_warning_eval(str, b = get_binding) + begin + eval(str, b) + rescue StandardError, ScriptError => e + print "#{e.class} Exception: #{e.message}\n" + nil + end + end + + def get_binding pos = @state.frame_pos + @state.context ? @state.context.frame_binding(pos) : TOPLEVEL_BINDING + end + + def get_context(thnum) + Byebug.contexts.find {|c| c.thnum == thnum} + end + end + + Command.load_commands + + ## + # Returns ths settings object. + # Use Byebug.settings[] and Byebug.settings[]= methods to query and set + # byebug settings. These settings are available: + # + # :autoeval - evaluates input in the current binding if it's not + # recognized as a byebug command + # :autoirb - automatically calls 'irb' command on breakpoint + # :autolist - automatically calls 'list' command on breakpoint + # :autoreload - makes 'list' command always display up-to-date source + # code + # :frame_class_names - displays method's class name when showing frame stack + # :forcestep - stepping command always move to the new line + # :fullpath - displays full paths when showing frame stack + # :stack_on_error - shows full stack trace if eval command results in an + # exception + # + def self.settings + Command.settings + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/command_processor.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/command_processor.rb new file mode 100644 index 0000000..16c7c53 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/command_processor.rb @@ -0,0 +1,255 @@ +require 'forwardable' +require_relative 'interface' +require_relative 'command' + +module Byebug + + class CommandProcessor < Processor + attr_reader :display + + def initialize(interface = LocalInterface.new) + super(interface) + + @display = [] + @mutex = Mutex.new + @last_cmd = nil # To allow empty (just ) commands + @last_file = nil # Filename the last time we stopped + @last_line = nil # Line number the last time we stopped + @context_was_dead = false # Assume we haven't started. + end + + def interface=(interface) + @mutex.synchronize do + @interface.close if @interface + @interface = interface + end + end + + require 'pathname' # For cleanpath + + # + # Regularize file name. + # + # This is also used as a common funnel place if basename is desired or if we + # are working remotely and want to change the basename. Or we are eliding + # filenames. + def self.canonic_file(filename) + return filename if ['(irb)', '-e'].include?(filename) + + # For now we want resolved filenames + if Command.settings[:basename] + File.basename(filename) + else + Pathname.new(filename).cleanpath.to_s + end + end + + def self.protect(mname) + alias_method "__#{mname}", mname + module_eval <<-END, __FILE__, __LINE__+1 + def #{mname}(*args) + @mutex.synchronize do + return unless @interface + __#{mname}(*args) + end + rescue IOError, Errno::EPIPE + self.interface = nil + rescue SignalException + raise + rescue Exception + print "INTERNAL ERROR!!! #\{$!\}\n" rescue nil + print $!.backtrace.map{|l| "\t#\{l\}"}.join("\n") rescue nil + end + END + end + + def at_breakpoint(context, breakpoint) + n = Byebug.breakpoints.index(breakpoint) + 1 + file = CommandProcessor.canonic_file(breakpoint.source) + line = breakpoint.pos + print "Stopped by breakpoint #{n} at #{file}:#{line}\n" + end + protect :at_breakpoint + + def at_catchpoint(context, excpt) + file = CommandProcessor.canonic_file(context.frame_file(0)) + line = context.frame_line(0) + print "Catchpoint at %s:%d: `%s' (%s)\n", file, line, excpt, excpt.class + end + protect :at_catchpoint + + def at_tracing(context, file, line) + if file != @last_file || line != @last_line || Command.settings[:linetrace_plus] + @last_file, @last_line = file, line + print "Tracing: #{CommandProcessor.canonic_file(file)}:#{line} " \ + "#{Byebug.line_at(file,line)}\n" + end + always_run(context, file, line, 2) + end + protect :at_tracing + + def at_line(context, file, line) + Byebug.source_reload if Command.settings[:autoreload] + process_commands(context, file, line) + end + protect :at_line + + def at_return(context, file, line) + process_commands(context, file, line) + end + protect :at_return + + private + # + # Prompt shown before reading a command. + # + def prompt(context) + return "(byebug#{context.dead? ? ':post-mortem' : ''}) " + end + + # + # Run commands everytime. + # + # For example display commands or possibly the list or irb in an + # "autolist" or "autoirb". + # + # @return List of commands acceptable to run bound to the current state + # + def always_run(context, file, line, run_level) + cmds = Command.commands + + # Remove some commands in post-mortem + cmds = cmds.find_all { |cmd| cmd.allow_in_post_mortem } if context.dead? + + state = State.new(cmds, context, @display, file, @interface, line) + + # Change default when in irb or code included in command line + Command.settings[:autolist] = 0 if ['(irb)', '-e'].include?(file) + + # Bind commands to the current state. + commands = cmds.map { |cmd| cmd.new(state) } + + commands.select { |cmd| cmd.class.always_run >= run_level } + .each { |cmd| cmd.execute } + + return state, commands + end + + # + # Splits a command line of the form "cmd1 ; cmd2 ; ... ; cmdN" into an + # array of commands: [cmd1, cmd2, ..., cmdN] + # + def split_commands(cmd_line) + cmd_line.split(/;/).inject([]) do |m, v| + if m.empty? + m << v + else + if m.last[-1] == ?\\ + m.last[-1,1] = '' + m.last << ';' << v + else + m << v + end + end + m + end + end + + # + # Handle byebug commands. + # + def process_commands(context, file, line) + state, commands = always_run(context, file, line, 1) + + if Command.settings[:testing] + Thread.current.thread_variable_set('state', state) + else + Thread.current.thread_variable_set('state', nil) + end + + preloop(commands, context) + print state.location if Command.settings[:autolist] == 0 + + while !state.proceed? + input = @interface.command_queue.empty? ? + @interface.read_command(prompt(context)) : + @interface.command_queue.shift + break unless input + catch(:debug_error) do + if input == "" + next unless @last_cmd + input = @last_cmd + else + @last_cmd = input + end + split_commands(input).each do |cmd| + one_cmd(commands, context, cmd) + end + end + end + end + + # + # Executes a single byebug command + # + def one_cmd(commands, context, input) + if cmd = commands.find { |c| c.match(input) } + if context.dead? && cmd.class.need_context + print "Command is unavailable\n" + else + cmd.execute + end + else + unknown_cmd = commands.find { |c| c.class.unknown } + if unknown_cmd + unknown_cmd.execute + else + errmsg "Unknown command: \"#{input}\". Try \"help\".\n" + end + end + end + + # + # Tasks to do before processor loop + # + def preloop(commands, context) + @context_was_dead = true if context.dead? and not @context_was_dead + + if @context_was_dead + print "The program finished.\n" + @context_was_dead = false + end + end + + class State + attr_accessor :commands, :context, :display, :file, :frame_pos + attr_accessor :interface, :line, :previous_line + + def initialize(commands, context, display, file, interface, line) + @commands, @context, @display = commands, context, display + @file, @interface, @line = file, interface, line + @frame_pos, @previous_line, @proceed = 0, nil, false + end + + extend Forwardable + def_delegators :@interface, :errmsg, :print, :confirm + + def proceed? + @proceed + end + + def proceed + @proceed = true + end + + def location + loc = "#{CommandProcessor.canonic_file(@file)} @ #{@line}\n" + loc += "#{Byebug.line_at(@file, @line)}\n" unless + ['(irb)', '-e'].include? @file + loc + end + end + + end # class CommandProcessor + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/breakpoints.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/breakpoints.rb new file mode 100644 index 0000000..5a0dc9b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/breakpoints.rb @@ -0,0 +1,137 @@ +module Byebug + + # Implements byebug "break" command. + class BreakCommand < Command + self.allow_in_post_mortem = false + self.allow_in_control = true + + def regexp + /^\s* b(?:reak)? (?:\s+#{Position_regexp})? (?:\s+(.+))? \s*$/x + end + + def execute + return print BreakCommand.help(nil) if BreakCommand.names.include?(@match[0]) + + if @match[1] + line, _, _, expr = @match.captures + else + _, file, line, expr = @match.captures + end + if expr + if expr !~ /^\s*if\s+(.+)/ + if file or line + errmsg "Expecting \"if\" in breakpoint condition; got: #{expr}.\n" + else + errmsg "Invalid breakpoint location: #{expr}.\n" + end + return + else + expr = $1 + end + end + + brkpt_filename = file + if file.nil? + unless @state.context + errmsg "We are not in a state that has an associated file.\n" + return + end + brkpt_filename = @state.file + if line.nil? + # Set breakpoint at current line + line = @state.line.to_s + end + elsif line !~ /^\d+$/ + # See if "line" is a method/function name + klass = bb_warning_eval(file) + if klass && klass.kind_of?(Module) + class_name = klass.name if klass + else + errmsg "Unknown class #{file}.\n" + throw :debug_error + end + end + + if line =~ /^\d+$/ + line = line.to_i + if LineCache.cache(brkpt_filename, Command.settings[:autoreload]) + last_line = LineCache.size(brkpt_filename) + return errmsg "There are only #{last_line} lines in file " \ + "#{brkpt_filename}\n" if line > last_line + + return errmsg "Line #{line} is not a stopping point in file " \ + "#{brkpt_filename}\n" unless + LineCache.trace_line_numbers(brkpt_filename).member?(line) + else + errmsg "No source file named #{brkpt_filename}\n" + return unless confirm("Set breakpoint anyway? (y/n) ") + end + + b = Byebug.add_breakpoint brkpt_filename, line, expr + print "Created breakpoint #{b.id} at " \ + "#{CommandProcessor.canonic_file(brkpt_filename)}:#{line.to_s}\n" + unless syntax_valid?(expr) + errmsg "Expression \"#{expr}\" syntactically incorrect; breakpoint" \ + " disabled.\n" + b.enabled = false + end + else + method = line.intern + b = Byebug.add_breakpoint class_name, method, expr + print "Created breakpoint #{b.id} at #{class_name}::#{method.to_s}\n" + end + end + + class << self + def names + %w(break) + end + + def description + %{b[reak] file:line [if expr] + b[reak] class(.|#)method [if expr] + + Set breakpoint to some position, (optionally) if expr == true} + end + end + end + + # Implements byebug "delete" command. + class DeleteCommand < Command + self.allow_in_post_mortem = false + self.allow_in_control = true + + def regexp + /^\s* del(?:ete)? (?:\s+(.*))?$/x + end + + def execute + return errmsg "We are not in a state we can delete breakpoints.\n" unless + @state.context + + if not @match[1] + Byebug.breakpoints.clear if confirm("Delete all breakpoints? (y or n) ") + else + @match[1].split(/[ \t]+/).each do |pos| + return unless pos = get_int(pos, "Delete", 1) + errmsg "No breakpoint number %d\n", pos unless + Byebug.remove_breakpoint(pos) + end + end + end + + class << self + def names + %w(delete) + end + + def description + %{del[ete][ nnn...] + + Without and argument, deletes all breakpoints. With integer arguments, + it deletes specific breakpoints.} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/catchpoint.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/catchpoint.rb new file mode 100644 index 0000000..a44c815 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/catchpoint.rb @@ -0,0 +1,46 @@ +module Byebug + + class CatchCommand < Command + self.allow_in_control = true + + def regexp + /^\s* cat(?:ch)? (?:\s+(\S+))? (?:\s+(off))? \s*$/x + end + + def execute + excn = @match[1] + return info_catch unless excn + + if not @match[2] + if 'off' == @match[1] + Byebug.catchpoints.clear if + confirm("Delete all catchpoints? (y or n) ") + else + print "Warning #{@match[1]} is not known to be a Class\n" unless + bb_eval "#{@match[1]}.is_a?(Class)", get_binding + Byebug.add_catchpoint @match[1] + print "Catching exception #{@match[1]}.\n" + end + elsif @match[2] != 'off' + errmsg "Off expected. Got #{@match[2]}\n" + elsif Byebug.catchpoints.member?(@match[1]) + Byebug.catchpoints.delete @match[1] + print "Catch for exception #{match[1]} removed.\n" + else + return errmsg "Catch for exception #{@match[1]} not found\n" + end + end + + class << self + def names + %w(catch) + end + + def description + %{cat[ch]\t\t\t\tLists catchpoints + cat[ch] off\t\t\tDeletes all catchpoints + cat[ch] [off]\tEnable/disable handling .} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/condition.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/condition.rb new file mode 100644 index 0000000..51004ed --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/condition.rb @@ -0,0 +1,41 @@ +module Byebug + + class ConditionCommand < Command + self.allow_in_post_mortem = false + + def regexp + /^\s* cond(?:ition)? (?:\s+(\d+)(?:\s+(.*))?)? \s*$/x + end + + def execute + return print ConditionCommand.help(nil) unless @match[1] + + breakpoints = Byebug.breakpoints.sort_by{|b| b.id } + largest = breakpoints.inject(0) do |tally, b| + tally = b.id if b.id > tally + end + + return print "No breakpoints have been set.\n" if 0 == largest + return unless pos = get_int(@match[1], "Condition", 1, largest) + + breakpoint = breakpoints.select{ |b| b.id == pos }.first + breakpoint.expr = @match[2] if breakpoint + end + + class << self + def names + %w(condition) + end + + def description + %{cond[ition] nnn[ expr] + + Specify breakpoint number nnn to break only if expr is true. nnn is an + integer and expr is an expression to be evaluated whenever breakpoint + nnn is reached. If no expression is specified, the condition is + removed.} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/continue.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/continue.rb new file mode 100644 index 0000000..9d5a27e --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/continue.rb @@ -0,0 +1,37 @@ +module Byebug + + # Implements byebug "continue" command. + class ContinueCommand < Command + self.allow_in_post_mortem = true + self.need_context = false + + def regexp + /^\s* c(?:ont(?:inue)?)? (?:\s+(\S+))? \s*$/x + end + + def execute + if @match[1] && !@state.context.dead? + filename = File.expand_path(@state.file) + return unless line_number = get_int(@match[1], "Continue", 0, nil, 0) + return errmsg "Line #{line_number} is not a stopping point in file " \ + "\"#{filename}\"\n" unless + LineCache.trace_line_numbers(filename).member?(line_number) + + Byebug.add_breakpoint filename, line_number + end + @state.proceed + end + + class << self + def names + %w(continue) + end + + def description + %{c[ont[inue]][ nnn] + + Run until program ends, hits a breakpoint or reaches line nnn} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/control.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/control.rb new file mode 100644 index 0000000..dc3dab3 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/control.rb @@ -0,0 +1,90 @@ +module Byebug + + class RestartCommand < Command + self.allow_in_control = true + + def regexp + /^\s* (?:restart|R) (?:\s+(.+))? \s*$/x + end + + def execute + return errmsg "Don't know name of debugged program\n" unless + defined? Byebug::PROG_SCRIPT + + return errmsg "Ruby program #{Byebug::PROG_SCRIPT} doesn't exist\n" unless + File.exist?(File.expand_path(Byebug::PROG_SCRIPT)) + + if not defined? Byebug::BYEBUG_SCRIPT + print "Byebug was not called from the outset...\n" + if not File.executable?(Byebug::PROG_SCRIPT) + print "Ruby program #{Byebug::PROG_SCRIPT} not executable... " \ + "We'll add a call to Ruby.\n" + cmd = "ruby -rbyebug -I#{$:.join(' -I')} #{Byebug::PROG_SCRIPT}" + else + cmd = Byebug::PROG_SCRIPT + end + else + cmd = "#{Byebug::BYEBUG_SCRIPT} #{Byebug::PROG_SCRIPT}" + end + + begin + Dir.chdir(Byebug::INITIAL_DIR) + rescue + print "Failed to change initial directory #{Byebug::INITIAL_DIR}" + end + + if @match[1] + cmd += " #{@match[1]}" + elsif not defined? Command.settings[:argv] + return errmsg "Arguments not set. Use 'set args' to set them.\n" + else + require 'shellwords' + cmd += " #{Command.settings[:argv].compact.shelljoin}" + end + + # An execv would be preferable to the "exec" below. + print "Re exec'ing:\n\t#{cmd}\n" + exec cmd + rescue Errno::EOPNOTSUPP + print "Restart command is not available at this time.\n" + end + + class << self + def names + %w(restart) + end + + def description + %{restart|R [args] + + Restart the program. This is a re-exec - all byebug state + is lost. If command arguments are passed those are used.} + end + end + end + + class InterruptCommand < Command + self.allow_in_control = true + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s*i(?:nterrupt)?\s*$/ + end + + def execute + context = Byebug.thread_context(Thread.main) + context.interrupt + end + + class << self + def names + %w(interrupt) + end + + def description + %{i|nterrupt\t interrupt the program} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/display.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/display.rb new file mode 100644 index 0000000..a36b526 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/display.rb @@ -0,0 +1,116 @@ +module Byebug + + module DisplayFunctions + def display_expression(exp) + print "#{exp} = #{bb_warning_eval(exp).inspect}\n" + end + + def active_display_expressions? + @state.display.select{|d| d[0]}.size > 0 + end + + def print_display_expressions + n = 1 + for d in @state.display + if d[0] + print "#{n}: " + display_expression(d[1]) + end + n += 1 + end + end + end + + class AddDisplayCommand < Command + self.allow_in_post_mortem = false + + def regexp + /^\s* disp(?:lay)? \s+ (.+) \s*$/x + end + + def execute + exp = @match[1] + @state.display.push [true, exp] + print "#{@state.display.size}: " + display_expression(exp) + end + + class << self + def names + %w(display) + end + + def description + %{disp[lay] \tadd expression into display expression list} + end + end + end + + class DisplayCommand < Command + self.allow_in_post_mortem = false + + def self.always_run + 2 + end + + def regexp + /^\s* disp(?:lay)? \s*$/x + end + + def execute + print_display_expressions + end + + class << self + def names + %w(display) + end + + def description + %{disp[lay]\t\tdisplay expression list} + end + end + end + + class DeleteDisplayCommand < Command + self.allow_in_post_mortem = false + + def regexp + /^\s* undisp(?:lay)? (?:\s+(\S+))? \s*$/x + end + + def execute + unless pos = @match[1] + if confirm("Clear all expressions? (y/n) ") + for d in @state.display + d[0] = false + end + end + else + pos = get_int(pos, "Undisplay") + return unless pos + if @state.display[pos-1] + @state.display[pos-1][0] = nil + else + errmsg "Display expression %d is not defined.\n", pos + end + end + end + + class << self + def names + %w(undisplay) + end + + def description + %{undisp[lay][ nnn] + + Cancel some expressions to be displayed when program stops. Arguments + are the code numbers of the expressions to stop displaying. No + argument means cancel all automatic-display expressions. "delete + display" has the same effect as this command. Do "info display" to see + the current list of code numbers.} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/edit.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/edit.rb new file mode 100644 index 0000000..a09354e --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/edit.rb @@ -0,0 +1,50 @@ +module Byebug + + class Edit < Command + self.allow_in_control = true + + def regexp + /^\s* ed(?:it)? (?:\s+(\S+))? \s*$/x + end + + def execute + if not @match[1] + unless @state.file + return errmsg "We are not in a state that has an associated file.\n" + end + file = @state.file + line = @state.line if @state.line + elsif @pos_match = /([^:]+)[:]([0-9]+)/.match(@match[1]) + file, line = @pos_match.captures + elsif File.exist?(@match[1]) + file = @match[1] + else + return errmsg "Invalid file[:line] number specification: #{@match[1]}\n" + end + + editor = ENV['EDITOR'] || 'vim' + + if File.readable?(file) + system("#{editor} +#{line} #{file}") if line + system("#{editor} #{file}") unless line + else + errmsg "File \"#{file}\" is not readable.\n" + end + end + + class << self + def names + %w(edit) + end + + def description + %{edit[ file:lineno]\tEdit specified file. + + With no argument, edits file containing most recent line listed. + Editing targets can also be specified to start editing at a specific + line in a specific file.} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/enable.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/enable.rb new file mode 100644 index 0000000..bc5a2e2 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/enable.rb @@ -0,0 +1,155 @@ +module Byebug + + # Mix-in module to assist in command parsing. + module EnableDisableFunctions + def enable_disable_breakpoints(is_enable, args) + return errmsg "No breakpoints have been set." if Byebug.breakpoints.empty? + + all_breakpoints = Byebug.breakpoints.sort_by {|b| b.id } + if args.empty? + selected_breakpoints = all_breakpoints + else + selected_ids = [] + args.each do |pos| + pos = get_int(pos, "#{is_enable} breakpoints", 1, all_breakpoints.last.id) + return nil unless pos + selected_ids << pos + end + selected_breakpoints = all_breakpoints.select { + |b| selected_ids.include?(b.id) } + end + + selected_breakpoints.each do |b| + enabled = ('enable' == is_enable) + if enabled && !syntax_valid?(b.expr) + errmsg "Expression \"#{b.expr}\" syntactically incorrect; " \ + "breakpoint remains disabled.\n" + else + b.enabled = enabled + end + end + end + + def enable_disable_display(is_enable, args) + if 0 == @state.display.size + errmsg "No display expressions have been set.\n" + return + end + args.each do |pos| + pos = get_int(pos, "#{is_enable} display", 1, @state.display.size) + return nil unless pos + @state.display[pos-1][0] = ('enable' == is_enable) + end + end + end + + class EnableCommand < Command + Subcommands = [ + ['breakpoints', 2, 'Enable breakpoints. This is used to cancel the ' \ + 'effect of the "disable" command. Give breakpoint' \ + ' numbers (separated by spaces) as arguments or ' \ + 'no argument at all if you want to reenable ' \ + 'every breakpoint' ], + ['display' , 2, 'Enable some expressions to be displayed when ' \ + 'program stops. Arguments are the code numbers of' \ + ' the expressions to resume displaying. Do "info ' \ + 'display" to see the current list of code numbers' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(Subcommands) + + def regexp + /^\s* en(?:able)? (?:\s+(.+))? \s*$/x + end + + def execute + return errmsg "\"enable\" must be followed by \"display\", " \ + "\"breakpoints\" or breakpoint numbers.\n" unless @match[1] + + args = @match[1].split(/[ \t]+/) + param = args.shift + subcmd = Command.find(Subcommands, param) + if subcmd + send("enable_#{subcmd.name}", args) + else + send('enable_breakpoints', args.unshift(param)) + end + end + + def enable_breakpoints(args) + enable_disable_breakpoints('enable', args) + end + + def enable_display(args) + enable_disable_display('enable', args) + end + + class << self + def names + %w(enable) + end + + def description + %{Enable breakpoints or displays. + + This is used to cancel the effect of the "disable" command.} + end + end + end + + class DisableCommand < Command + Subcommands = [ + ['breakpoints', 1, 'Disable breakpoints. A disabled breakpoint is ' \ + 'not forgotten, but has no effect until ' \ + 'reenabled. Give breakpoint numbers (separated by' \ + 'spaces) as arguments or no argument at all if ' \ + 'you want to disable every breakpoint' ], + ['display' , 1, 'Disable some display expressions when program ' \ + 'stops. Arguments are the code numbers of the ' \ + 'expressions to stop displaying. Do "info ' \ + 'display" to see the current list of code numbers.' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(Subcommands) + + def regexp + /^\s* dis(?:able)? (?:\s+(.+))? \s*$/x + end + + def execute + return errmsg "\"disable\" must be followed by \"display\", " \ + "\"breakpoints\" or breakpoint numbers.\n" unless @match[1] + + args = @match[1].split(/[ \t]+/) + param = args.shift + subcmd = Command.find(Subcommands, param) + if subcmd + send("disable_#{subcmd.name}", args) + else + send('disable_breakpoints', args.unshift(param)) + end + end + + def disable_breakpoints(args) + enable_disable_breakpoints('disable', args) + end + + def disable_display(args) + enable_disable_display('disable', args) + end + + class << self + def names + %w(disable) + end + + def description + %{Disable breakpoints or displays. + + A disabled item is not forgotten, but has no effect until reenabled. + Use the "enable" command to have it take effect again.} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/eval.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/eval.rb new file mode 100644 index 0000000..c1baeec --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/eval.rb @@ -0,0 +1,175 @@ +require 'pp' + +module Byebug + module EvalFunctions + def run_with_binding + binding = get_binding + yield binding + end + end + + class EvalCommand < Command + self.allow_in_control = true + + register_setting_get(:autoeval) do + EvalCommand.unknown + end + register_setting_set(:autoeval) do |value| + EvalCommand.unknown = value + end + + # Set default value + Command.settings[:autoeval] = true + + def match(input) + @input = input + super + end + + def regexp + /^\s* (p|e(?:val)?)\s+/x + end + + def execute + expr = @match ? @match.post_match : @input + run_with_binding do |b| + if Command.settings[:stack_on_error] + print "#{bb_eval(expr, b).inspect}\n" + else + print "#{bb_warning_eval(expr, b).inspect}\n" + end + end + rescue + print "#{$!.class} Exception: #{$!.message}\n" + end + + class << self + def names + %w(p eval) + end + + def description + %{(p|e[val]) expression + + Evaluate expression and print its value + * NOTE - unknown input is automatically evaluated, to turn this off + use 'set noautoeval'} + end + end + end + + class PPCommand < Command + self.allow_in_control = true + + def regexp + /^\s* pp \s+/x + end + + def execute + out = StringIO.new + run_with_binding do |b| + if Command.settings[:stack_on_error] + PP.pp(bb_eval(@match.post_match, b), out) + else + PP.pp(bb_warning_eval(@match.post_match, b), out) + end + end + print out.string + rescue + out.puts $!.message + end + + class << self + def names + %w(pp) + end + + def description + %{pp expression\tevaluate expression and pretty-print its value} + end + end + end + + class PutLCommand < Command + include Columnize + self.allow_in_control = true + + def regexp + /^\s* putl\s+/x + end + + def execute + out = StringIO.new + run_with_binding do |b| + if Command.settings[:stack_on_error] + vals = bb_eval(@match.post_match, b) + else + vals = bb_warning_eval(@match.post_match, b) + end + if vals.is_a?(Array) + vals = vals.map{|item| item.to_s} + print "#{columnize(vals, Command.settings[:width])}\n" + else + PP.pp(vals, out) + print out.string + end + end + rescue + out.puts $!.message + end + + class << self + def names + %w(putl) + end + + def description + %{putl expression + + Evaluate expression, an array, and columnize its value} + end + end + end + + class PSCommand < Command + include Columnize + self.allow_in_control = true + + def regexp + /^\s* ps\s+/x + end + + def execute + out = StringIO.new + run_with_binding do |b| + if Command.settings[:stack_on_error] + vals = bb_eval(@match.post_match, b) + else + vals = bb_warning_eval(@match.post_match, b) + end + if vals.is_a?(Array) + vals = vals.map{|item| item.to_s} + print "#{columnize(vals.sort!, Command.settings[:width])}\n" + else + PP.pp(vals, out) + print out.string + end + end + rescue + out.puts $!.message + end + + class << self + def names + %w(ps) + end + + def description + %{ps expression + + Evaluate expression, an array, sort and columnize its value} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/finish.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/finish.rb new file mode 100644 index 0000000..94c8ec9 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/finish.rb @@ -0,0 +1,42 @@ +module Byebug + + # Implements byebug's 'finish' command. + class FinishCommand < Command + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s* fin(?:ish)? (?:\s+(\S+))? \s*$/x + end + + def execute + if not @match[1] + frame_pos = @state.frame_pos + else + max_frame = Context.stack_size - @state.frame_pos + frame_pos = get_int(@match[1], "finish", 0, max_frame-1, 0) + return nil unless frame_pos + end + @state.context.step_out frame_pos + @state.frame_pos = 0 + @state.proceed + end + + class << self + def names + %w(finish) + end + + def description + %{fin[ish][ frame-number]\tExecute until selected stack frame returns. + + If no frame number is given, we run until the currently selected frame + returns. The currently selected frame starts out the most-recent frame + or 0 if no frame positioning (e.g "up", "down" or "frame") has been + performed. + + If a frame number is given we run until that frame returns.} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/frame.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/frame.rb new file mode 100644 index 0000000..40c6125 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/frame.rb @@ -0,0 +1,256 @@ +# encoding: utf-8 +module Byebug + + # Mix-in module to assist in command parsing. + module FrameFunctions + def c_frame?(frame_no) + @state.context.frame_binding(frame_no).nil? + end + + def switch_to_frame(frame_no) + if frame_no < 0 + abs_frame_no = Context.stack_size + frame_no + else + abs_frame_no = frame_no + end + end + + def navigate_to_frame(jump_no) + return if jump_no == 0 + total_jumps, current_jumps, new_pos = jump_no.abs, 0, @state.frame_pos + step = jump_no/total_jumps + loop do + new_pos += step + return new_pos if new_pos < 0 || new_pos >= Context.stack_size + + next if c_frame?(new_pos) + + current_jumps += 1 + break if current_jumps == total_jumps + end + return new_pos + end + + def adjust_frame(frame_pos, absolute) + if absolute + abs_frame_pos = switch_to_frame(frame_pos) + return errmsg "Can't navigate to c-frame\n" if c_frame?(abs_frame_pos) + else + abs_frame_pos = navigate_to_frame(frame_pos) + end + + return errmsg "Can't navigate beyond the oldest frame\n" if + abs_frame_pos >= Context.stack_size + return errmsg "Can't navigate beyond the newest frame\n" if + abs_frame_pos < 0 + + @state.frame_pos = abs_frame_pos + @state.file = @state.context.frame_file @state.frame_pos + @state.line = @state.context.frame_line @state.frame_pos + @state.previous_line = nil + ListCommand.new(@state).execute + end + + def get_frame_class(style, pos) + frame_class = style == :short ? '' : "#{@state.context.frame_class pos}" + return frame_class == '' ? '' : "#{frame_class}." + end + + def get_frame_block_and_method(pos) + frame_deco_regexp = /((?:block(?: \(\d+ levels\))?|rescue) in )?(.+)/ + frame_deco_method = "#{@state.context.frame_method pos}" + frame_block_and_method = frame_deco_regexp.match(frame_deco_method)[1..2] + return frame_block_and_method.map{ |x| x.nil? ? '' : x } + end + + def get_frame_args(style, pos) + args = @state.context.frame_args pos + return '' if args.empty? + + locals = @state.context.frame_locals pos if style == :long + my_args = args.map do |arg| + case arg[0] + when :block + prefix, default = '&', 'block' + when :rest + prefix, default = '*', 'args' + else + prefix, default = '', nil + end + klass = style == :long && arg[1] ? "##{locals[arg[1]].class}" : '' + "#{prefix}#{arg[1] || default}#{klass}" + end + + return "(#{my_args.join(', ')})" + end + + def get_frame_call(prefix, pos) + frame_block, frame_method = get_frame_block_and_method(pos) + frame_class = get_frame_class(Command.settings[:callstyle], pos) + frame_args = get_frame_args(Command.settings[:callstyle], pos) + + call_str = frame_block + frame_class + frame_method + frame_args + + max_call_str_size = Command.settings[:width] - prefix.size + if call_str.size > max_call_str_size + call_str = call_str[0..max_call_str_size - 5] + "...)" + end + + return call_str + end + + def print_backtrace + realsize = Context.stack_size + calcedsize = @state.context.calced_stack_size + if calcedsize != realsize + if Byebug.post_mortem? + stacksize = calcedsize + else + errmsg "Byebug's stacksize (#{calcedsize}) should be #{realsize}. " \ + "This might be a bug in byebug or ruby's debugging API's\n" + stacksize = realsize + end + else + stacksize = calcedsize + end + (0...stacksize).each do |idx| + print_frame(idx) + end + end + + def print_frame(pos, mark_current = true) + file = @state.context.frame_file pos + line = @state.context.frame_line pos + + unless Command.settings[:fullpath] + path_components = file.split(/[\\\/]/) + if path_components.size > 3 + path_components[0...-3] = '...' + file = path_components.join(File::ALT_SEPARATOR || File::SEPARATOR) + end + end + + if mark_current + frame_str = (pos == @state.frame_pos) ? '--> ' : ' ' + else + frame_str = "" + end + frame_str += c_frame?(pos) ? ' ͱ-- ' : '' + + frame_str += sprintf "#%-2d ", pos + frame_str += get_frame_call frame_str, pos + file_line = "at #{CommandProcessor.canonic_file(file)}:#{line}" + if frame_str.size + file_line.size + 1 > Command.settings[:width] + frame_str += "\n #{file_line}\n" + else + frame_str += " #{file_line}\n" + end + + print frame_str + end + end + + # Implements byebug "where" or "backtrace" command. + class WhereCommand < Command + def regexp + /^\s* (?:w(?:here)?|bt|backtrace) \s*$/x + end + + def execute + print_backtrace + end + + class << self + def names + %w(where backtrace) + end + + def description + %{w[here]|bt|backtrace\tdisplay stack frames + + Print the entire stack frame. Each frame is numbered; the most recent + frame is 0. A frame number can be referred to in the "frame" command; + "up" and "down" add or subtract respectively to frame numbers shown. + The position of the current frame is marked with -->. C-frames hang + from their most immediate Ruby frame to indicate that they are not + navigable} + end + end + end + + class UpCommand < Command + def regexp + /^\s* u(?:p)? (?:\s+(\S+))? \s*$/x + end + + def execute + pos = get_int(@match[1], "Up") + return unless pos + adjust_frame(pos, false) + end + + class << self + def names + %w(up) + end + + def description + %{up[ count]\tmove to higher frame} + end + end + end + + class DownCommand < Command + def regexp + /^\s* down (?:\s+(\S+))? \s*$/x + end + + def execute + pos = get_int(@match[1], "Down") + return unless pos + adjust_frame(-pos, false) + end + + class << self + def names + %w(down) + end + + def description + %{down[ count]\tmove to lower frame} + end + end + end + + class FrameCommand < Command + def regexp + /^\s* f(?:rame)? (?:\s+(\S+))? \s*$/x + end + + def execute + return print_frame @state.frame_pos unless @match[1] + return unless pos = get_int(@match[1], "Frame") + adjust_frame(pos, true) + end + + class << self + def names + %w(frame) + end + + def description + %{f[rame][ frame-number] + + Move the current frame to the specified frame number, or the 0 if no + frame-number has been given. + + A negative number indicates position from the other end, so "frame -1" + moves to the oldest frame, and "frame 0" moves to the newest frame. + + Without an argument, the command prints the current stack frame. Since + the current position is redisplayed, it may trigger a resyncronization + if there is a front end also watching over things.} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/help.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/help.rb new file mode 100644 index 0000000..ff4f96f --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/help.rb @@ -0,0 +1,50 @@ +module Byebug + + # Implements byebug "help" command. + class HelpCommand < Command + include Columnize + + self.allow_in_control = true + + def regexp + /^\s* h(?:elp)? (?:\s+(.+))? \s*$/x + end + + def execute + if @match[1] + args = @match[1].split + cmds = @state.commands.select { |cmd| cmd.names.include?(args[0]) } + unless cmds.empty? + help = cmds.map{ |cmd| cmd.help(args) }.join("\n") + help = help.split("\n").map{|l| l.gsub(/^ +/, '')} + help.shift if help.first && help.first.empty? + help.pop if help.last && help.last.empty? + return print help.join("\n") + "\n" + else + return errmsg "Undefined command: \"#{args[0]}\". Try \"help\".\n" if + args[0] + end + end + + print "byebug help v#{Byebug::VERSION}\n" unless + Command.settings[:testing] + + print "Type \"help \" for help on a specific command\n\n" + print "Available commands:\n" + cmds = @state.commands.map{ |cmd| cmd.names }.flatten.uniq.sort + print columnize(cmds, Command.settings[:width]) + end + + class << self + def names + %w(help) + end + + def description + %{h[elp]\t\tprint this help + h[elp] command\tprint help on command + h[elp] command subcommand\tprint help on subcommand} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/info.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/info.rb new file mode 100644 index 0000000..19d5d1e --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/info.rb @@ -0,0 +1,301 @@ +module Byebug + + module InfoFunctions + def info_catch(*args) + return print "No frame selected.\n" unless @state.context + + if Byebug.catchpoints and not Byebug.catchpoints.empty? + Byebug.catchpoints.each do |exception, hits| + print "#{exception}: #{exception.is_a?(Class)}\n" + end + else + print "No exceptions set to be caught.\n" + end + end + end + + # Implements byebug "info" command. + class InfoCommand < Command + include Columnize + self.allow_in_control = true + + Subcommands = [ + ['args' , 1, 'Argument variables of current stack frame' ], + ['breakpoints' , 1, 'Status of user-settable breakpoints', + 'Without argument, list info about all ' \ + 'breakpoints. With an integer argument, ' \ + 'list info on that breakpoint.' ], + ['catch' , 3, 'Exceptions that can be caught in the ' \ + 'current stack frame' ], + ['display' , 2, 'Expressions to display when program stops' ], + ['file' , 4, 'Info about a particular file read in', + 'After the file name is supplied, you can' \ + 'list file attributes that you wish to ' \ + 'see. Attributes include: "all", "basic",' \ + ' "breakpoint", "lines", "mtime", "path" ' \ + 'and "sha1".' ], + ['files' , 5, 'File names and timestamps of files read in' ], + ['global_variables' , 2, 'Global variables' ], + ['instance_variables', 2, 'Instance variables in current stack frame' ], + ['line' , 2, 'Line number and file name of current ' \ + 'position in source file' ], + ['locals' , 2, 'Local variables of the current stack frame' ], + ['program' , 2, 'Execution status of the program' ], + ['stack' , 2, 'Backtrace of the stack' ], + ['variables' , 1, 'Local and instance variables of the ' \ + 'current stack frame' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(Subcommands) + + InfoFileSubcommands = [ + ['all' , 1, 'All file information available - breakpoints, ' \ + 'lines, mtime, path and sha1' ], + ['basic' , 2, 'basic information - path, number of lines' ], + ['breakpoints', 2, 'Show trace line numbers', + 'These are the line number where a breakpoint ' \ + 'can be set.' ], + ['lines' , 1, 'Show number of lines in the file' ], + ['mtime' , 1, 'Show modification time of file' ], + ['path' , 4, 'Show full file path name for file' ], + ['sha1' , 1, 'Show SHA1 hash of contents of the file' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(InfoFileSubcommands) + + def regexp + /^\s* i(?:nfo)? (?:\s+(.+))? \s*$/x + end + + def execute + return print InfoCommand.help(nil) unless @match[1] + + args = @match[1].split(/[ \t]+/) + param = args.shift + subcmd = Command.find(Subcommands, param) + return errmsg "Unknown info command #{param}\n" unless subcmd + + if @state.context + send("info_#{subcmd.name}", *args) + else + errmsg "info_#{subcmd.name} not available without a context.\n" + end + end + + def info_args(*args) + locals = @state.context.frame_locals + args = @state.context.frame_args + return if args == [[:rest]] + + args.map do |_, name| + s = "#{name} = #{locals[name].inspect}" + pad_with_dots(s) + print "#{s}\n" + end + end + + def info_breakpoint(brkpt) + expr = brkpt.expr.nil? ? '' : " if #{brkpt.expr}" + print "%-3d %-3s at %s:%s%s\n" % + [brkpt.id, brkpt.enabled? ? 'y' : 'n', brkpt.source, brkpt.pos, expr] + hits = brkpt.hit_count + if hits > 0 + s = (hits > 1) ? 's' : '' + print "\tbreakpoint already hit #{hits} time#{s}\n" + end + end + private :info_breakpoint + + def info_breakpoints(*args) + return print "No breakpoints.\n" if Byebug.breakpoints.empty? + + brkpts = Byebug.breakpoints.sort_by{|b| b.id} + unless args.empty? + indices = args.map{|a| a.to_i} + brkpts = brkpts.select{|b| indices.member?(b.id)} + return errmsg "No breakpoints found among list given.\n" if + brkpts.empty? + end + print "Num Enb What\n" + brkpts.each { |b| info_breakpoint(b) } + end + + def info_display(*args) + return print "There are no auto-display expressions now.\n" unless + @state.display.find{|d| d[0]} + + print "Auto-display expressions now in effect:\n" \ + "Num Enb Expression\n" + n = 1 + for d in @state.display + print "%3d: %s %s\n" % [n, (d[0] ? 'y' : 'n'), d[1]] + n += 1 + end + end + + def info_file_path(file) + print "File #{file}" + path = File.expand_path(file) + print " - #{path}\n" if path and path != file + end + private :info_file_path + + def info_file_lines(file) + lines = LineCache.size(file) + print "\t #{lines} lines\n" if lines + end + private :info_file_lines + + def info_file_breakpoints(file) + breakpoints = LineCache.trace_line_numbers(file) + if breakpoints + print "\tbreakpoint line numbers:\n" + print columnize(breakpoints.to_a.sort, Command.settings[:width]) + end + end + private :info_file_breakpoints + + def info_file_mtime(file) + stat = LineCache.stat(file) + print "\t#{stat.mtime}\n" if stat + end + private :info_file_mtime + + def info_file_sha1(file) + print "\t#{LineCache.sha1(file)}\n" + end + private :info_file_sha1 + + def info_file(*args) + return info_files unless args[0] + + subcmd = Command.find(InfoFileSubcommands, args[1] || 'basic') + return errmsg "Invalid parameter #{args[1]}\n" unless subcmd + + if %w(all basic).member?(subcmd.name) + info_file_path(args[0]) + info_file_lines(args[0]) + if subcmd.name == 'all' + info_file_breakpoints(args[0]) + info_file_mtime(args[0]) + info_file_sha1(args[0]) + end + else + print "File #{args[0]}\n" if subcmd.name != 'path' + send("info_file_#{subcmd.name}", args[0]) + end + end + + def info_files(*args) + files = SCRIPT_LINES__.keys + files.uniq.sort.each do |file| + info_file_path(file) + info_file_mtime(file) + end + end + + def info_instance_variables(*args) + obj = bb_eval('self') + var_list(obj.instance_variables) + end + + def info_line(*args) + print "Line #{@state.line} of \"#{@state.file}\"\n" + end + + def info_locals(*args) + locals = @state.context.frame_locals + print_hash(locals) + end + + def print_hash(vars) + vars.keys.sort.each do |name| + begin + s = "#{name} = #{vars[name].inspect}" + rescue + begin + s = "#{name} = #{vars[name].to_s}" + rescue + s = "#{name} = *Error in evaluation*" + end + end + pad_with_dots(s) + print "#{s}\n" + end + end + private :print_hash + + def info_stop_reason(stop_reason) + case stop_reason + when :step + print "It stopped after stepping, next'ing or initial start.\n" + when :breakpoint + print("It stopped at a breakpoint.\n") + when :catchpoint + print("It stopped at a catchpoint.\n") + else + print "unknown reason: %s\n" % @state.context.stop_reason.to_s + end + end + private :info_stop_reason + + def info_program(*args) + if @state.context.dead? + print "The program crashed.\n" + print "Exception: #{Byebug.last_exception.inspect}\n" if Byebug.last_exception + return + end + + print "Program stopped. " + info_stop_reason @state.context.stop_reason + end + + def info_stack(*args) + print_backtrace + end + + def info_global_variables(*args) + var_global + end + + def info_variables(*args) + locals = @state.context.frame_locals + locals[:self] = @state.context.frame_self(@state.frame_pos) + print_hash(locals) + + obj = bb_eval('self') + var_list(obj.instance_variables, obj.instance_eval{binding()}) + var_class_self + end + + class << self + def names + %w(info) + end + + def description + %{info[ subcommand] + + Generic command for showing things about the program being debugged.} + end + + def help(args) + return description + format_subcmds unless args and args[1] + + return format_subcmd(args[1]) unless 'file' == args[1] and args[2] + + str = subcmd.short_help + '.' + subsubcmd = Command.find(InfoFileSubcommands, args[2]) + if subsubcmd + str += "\nInvalid \"file\" attribute \"#{args[2]}\"." + else + str += "\n" + subsubcmd.short_help + '.' + end + + return str + end + end + + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/kill.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/kill.rb new file mode 100644 index 0000000..90dedb6 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/kill.rb @@ -0,0 +1,44 @@ +module Byebug + + # Implements byebug "kill" command + class KillCommand < Command + self.allow_in_control = true + + def regexp + /^\s* (?:kill) \s* (?:\s+(\S+))? \s*$/x + end + + def execute + if @match[1] + signame = @match[1] + unless Signal.list.member?(signame) + errmsg("signal name #{signame} is not a signal I know about\n") + return false + end + if 'KILL' == signame + @state.interface.finalize + end + else + if not confirm("Really kill? (y/n) ") + return + else + signame = 'KILL' + end + end + Process.kill(signame, Process.pid) + end + + class << self + def names + %w(kill) + end + + def description + %{kill[ SIGNAL] + + Send [signal] to Process.pid + Equivalent of Process.kill(Process.pid)} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/list.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/list.rb new file mode 100644 index 0000000..6806316 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/list.rb @@ -0,0 +1,121 @@ +module Byebug + + # Implements byebug "list" command. + class ListCommand < Command + + register_setting_get(:autolist) do + ListCommand.always_run + end + register_setting_set(:autolist) do |value| + ListCommand.always_run = value + end + + # Set default value + Command.settings[:autolist] = 1 + + def regexp + /^\s* l(?:ist)? (?:\s*([-=])|\s+(\S+))? \s*$/x + end + + def execute + Byebug.source_reload if Command.settings[:autoreload] + lines = getlines(@state.file, @state.line) + if !lines + errmsg "No sourcefile available for #{@state.file}\n" + return @state.previous_line + end + + b, e = set_line_range(Command.settings[:listsize], lines.size) + return @state.previous_line if b < 0 + + print "\n[#{b}, #{e}] in #{@state.file}\n" + @state.previous_line = display_list(b, e, lines, @state.line) + end + + class << self + def names + %w(list) + end + + def description + %{l[ist]\t\tlist forward + l[ist] -\tlist backward + l[ist] =\tlist current line + l[ist] nn-mm\tlist given lines + * NOTE - to turn on autolist, use 'set autolist'} + end + end + + private + + ## + # Set line range to be printed by list + # + # @param listsize - number of lines to be printed + # @param maxline - max line number that can be printed + # + def set_line_range(listsize, maxline) + if !@match || !(@match[1] || @match[2]) + b = @state.previous_line ? + @state.previous_line + listsize : @state.line - (listsize/2) + elsif @match[1] == '-' + b = if @state.previous_line + if @state.previous_line > 0 + @state.previous_line - listsize + else + @state.previous_line + end + else + @state.line - (listsize/2) + end + elsif @match[1] == '=' + @state.previous_line = nil + b = @state.line - (listsize/2) + else + b, e = @match[2].split(/[-,]/) + if e + b = b.to_i + e = e.to_i + else + b = b.to_i - (listsize/2) + end + end + + if b > maxline + errmsg "Invalid line range" + return [ -1, -1 ] + end + + b = [1, b].max + e ||= b + listsize - 1 + + if e > maxline + e = maxline + b = e - listsize + 1 + b = [1, b].max + end + + return [ b, e ] + end + + ## + # Show file lines in LINES from line B to line E where CURRENT is the + # current line number. If we can show from B to E then we return B, + # otherwise we return the previous line @state.previous_line. + # + def display_list(b, e, lines, current) + width = e.to_s.size + b.upto(e) do |n| + if n > 0 && lines[n-1] + if n == current + print "=> %#{width}d: %s\n", n, lines[n-1].chomp + else + print " %#{width}d: %s\n", n, lines[n-1].chomp + end + end + end + print "\n" + return e == lines.size ? @state.previous_line : b + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/method.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/method.rb new file mode 100644 index 0000000..0149ad7 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/method.rb @@ -0,0 +1,77 @@ +module Byebug + + begin + require 'methodsig' + have_methodsig = true + rescue LoadError + have_methodsig = false + end + + # Implements byebug's 'method sig' command. + class MethodSigCommand < Command + def regexp + /^\s* m(?:ethod)? \s+ sig(?:nature)? \s+ (\S+) \s*$/x + end + + def execute + obj = bb_eval('method(:%s)' % @match[1]) + if obj.is_a?(Method) + begin + print "%s\n", obj.signature.to_s + rescue + errmsg("Can't get signature for '#{@match[1]}'\n") + end + else + errmsg("Can't make method out of '#{@match[1]}'\n") + end + end + + class << self + def names + %w(method) + end + + def description + %{m[ethod] sig[nature] \tshow the signature of a method} + end + end + end if have_methodsig + + # Implements byebug's 'method' command. + class MethodCommand < Command + include Columnize + + def regexp + /^\s* m(?:ethod)? \s+ ((iv)|(i(:?nstance)?)\s+)?/x + end + + def execute + obj = bb_eval(@match.post_match) + if @match[1] == "iv" + obj.instance_variables.sort.each do |v| + print "#{v} = #{obj.instance_variable_get(v).inspect}\n" + end + elsif @match[1] + print "#{columnize(obj.methods.sort(), Command.settings[:width])}\n" + else + return print "Should be Class/Module: #{@match.post_match}\n" unless + obj.kind_of? Module + print "#{columnize(obj.instance_methods(false).sort(), + Command.settings[:width])}\n" + end + end + + class << self + def names + %w(method) + end + + def description + %{m[ethod] i[nstance] \tshow methods of object + m[ethod] iv \t\tshow instance variables of object + m[ethod] \t\tshow instance methods of class or module} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/quit.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/quit.rb new file mode 100644 index 0000000..388c71e --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/quit.rb @@ -0,0 +1,32 @@ +module Byebug + + # Implements byebug "quit" command + class QuitCommand < Command + self.allow_in_control = true + + def regexp + /^\s* (?:q(?:uit)?|exit) \s* (!|\s+unconditionally)? \s*$/x + end + + def execute + if @match[1] or confirm("Really quit? (y/n) ") + @state.interface.finalize + exit! # exit -> exit!: No graceful way to stop... + end + end + + class << self + def names + %w(quit exit) + end + + def description + %{q[uit]|exit [!|unconditionally]\tExits from byebug. + + Normally we prompt before exiting. However if the parameter + "unconditionally" is given or command is suffixed with !, we exit + without asking further questions.} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/reload.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/reload.rb new file mode 100644 index 0000000..587aa63 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/reload.rb @@ -0,0 +1,50 @@ +module Byebug + + module ReloadFunctions + def getlines(file, line) + unless (lines = SCRIPT_LINES__[file]) and lines != true + Tracer::Single.get_line(file, line) if File.exist?(file) + lines = SCRIPT_LINES__[file] + lines = nil if lines == true + end + lines + end + end + + # Implements byebug "reload" command. + class ReloadCommand < Command + self.allow_in_control = true + self.allow_in_post_mortem = false + + register_setting_get(:autoreload) do + Byebug.class_variable_get(:@@autoreload) + end + + register_setting_set(:autoreload) do |value| + Byebug.class_variable_set(:@@autoreload, value) + end + Command.settings[:autoreload] = true + + def regexp + /^\s* r(?:eload)? \s*$/x + end + + def execute + Byebug.source_reload + print "Source code is reloaded. Automatic reloading is " \ + "#{Command.settings[:autoreload] ? 'on' : 'off'}.\n" + end + + private + + class << self + def names + %w(reload) + end + + def description + %{r[eload]\tforces source code reloading} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/repl.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/repl.rb new file mode 100644 index 0000000..17a8ef5 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/repl.rb @@ -0,0 +1,138 @@ +module IRB + module ExtendCommand + class Continue + def self.execute(conf) + throw :IRB_EXIT, :cont + end + end + class Next + def self.execute(conf) + throw :IRB_EXIT, :next + end + end + class Step + def self.execute(conf) + throw :IRB_EXIT, :step + end + end + end + + require 'irb' + ExtendCommandBundle.def_extend_command "cont", :Continue + ExtendCommandBundle.def_extend_command "n", :Next + ExtendCommandBundle.def_extend_command "step", :Step + + def self.start_session(binding) + unless @__initialized ||= false + args = ARGV.dup + ARGV.replace([]) + IRB.setup(nil) + ARGV.replace(args) + @__initialized = true + end + + workspace = WorkSpace.new(binding) + irb = Irb.new(workspace) + + @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] + @CONF[:MAIN_CONTEXT] = irb.context + + trap("SIGINT") do + irb.signal_handle + end + + catch(:IRB_EXIT) do + irb.eval_input + end + end +end + +module Byebug + + # Implements byebug's "irb" command. + class IRBCommand < Command + register_setting_get(:autoirb) do + IRBCommand.always_run + end + register_setting_set(:autoirb) do |value| + IRBCommand.always_run = value + end + + def regexp + /^\s* irb \s*$/x + end + + def execute + unless @state.interface.kind_of?(LocalInterface) + print "Command is available only in local mode.\n" + throw :debug_error + end + + cont = IRB.start_session(get_binding) + case cont + when :cont + @state.proceed + when :step + force = Command.settings[:forcestep] + @state.context.step_into 1, force + @state.proceed + when :next + force = Command.settings[:forcestep] + @state.context.step_over 1, @state.frame_pos, force + @state.proceed + else + print @state.location + @state.previous_line = nil + end + end + + + class << self + def names + %w(irb) + end + + def description + %{irb\tstarts an Interactive Ruby (IRB) session. + + IRB is extended with methods "cont", "n" and "step" which run the + corresponding byebug commands. In contrast to the real byebug commands + these commands don't allow arguments.} + end + end + end + + begin + require 'pry' + has_pry = true + rescue LoadError + has_pry = false + end + + # Implements byebug's "pry" command + class PryCommand < Command + def regexp + /^\s* pry \s*$/x + end + + def execute + unless @state.interface.kind_of?(LocalInterface) + print "Command is available only in local mode.\n" + throw :debug_error + end + + get_binding.pry + end + + class << self + def names + %w(pry) + end + + def description + %{pry\tstarts a Pry session.} + end + end + end if has_pry + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/save.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/save.rb new file mode 100644 index 0000000..749d77b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/save.rb @@ -0,0 +1,87 @@ +module Byebug + + module SaveFunctions + # Create a temporary file to write in if file is nil + def open_save + require "tempfile" + file = Tempfile.new("byebug-save") + # We want close to not unlink, so redefine. + def file.close + @tmpfile.close if @tmpfile + end + return file + end + end + + class SaveCommand < Command + self.allow_in_control = true + + def save_breakpoints(file) + Byebug.breakpoints.each do |b| + file.puts "break #{b.source}:#{b.pos}#{" if #{b.expr}" if b.expr}" + end + end + + def save_catchpoints(file) + Byebug.catchpoints.keys.each do |c| + file.puts "catch #{c}" + end + end + + def save_displays(file) + for d in @state.display + if d[0] + file.puts "display #{d[1]}" + end + end + end + + def save_settings(file) + # FIXME put routine in set + %w(autoeval basename testing).each do |setting| + on_off = show_onoff(Command.settings[setting.to_sym]) + file.puts "set #{setting} #{on_off}" + end + %w(autolist autoirb).each do |setting| + on_off = show_onoff(Command.settings[setting.to_sym] > 0) + file.puts "set #{setting} #{on_off}" + end + end + + def regexp + /^\s* sa(?:ve)? (?:\s+(\S+))? \s*$/x + end + + def execute + if not @match[1] + file = open_save() + else + file = open(@match[1], 'w') + end + save_breakpoints(file) + save_catchpoints(file) + save_displays(file) + save_settings(file) + print "Saved to '#{file.path}'\n" + if @state and @state.interface + @state.interface.restart_file = file.path + end + file.close + end + + class << self + def names + %w(save) + end + + def description + %{save[ FILE] + + Saves current byebug state to FILE as a script file. This includes + breakpoints, catchpoints, display expressions and some settings. If + no filename is given, we will fabricate one. + Use the "source" command in another debug session to restore them.} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/set.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/set.rb new file mode 100644 index 0000000..b6ddeb9 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/set.rb @@ -0,0 +1,159 @@ +module Byebug + + # Mix-in module to setting settings + module SetFunctions + + def set_setting(setting_name, setting_value, setting_args) + case setting_name + when /^args$/ + if defined?(Byebug::BYEBUG_SCRIPT) + Command.settings[:argv][1..-1] = setting_args + else + Command.settings[:argv] = setting_args + end + when /^autoirb$/ + Command.settings[:autoirb] = (setting_value ? 1 : 0) + when /^autolist$/ + Command.settings[:autolist] = (setting_value ? 1 : 0) + when /^callstyle$/ + if setting_args[0] and ['short', 'long'].include?(setting_args[0]) + Command.settings[:callstyle] = setting_args[0].to_sym + else + print "Invalid callstyle. Should be one of: \"short\" or \"long\"\n" + end + when /^verbose$/ + Byebug.verbose = setting_value + when /^history$/ + try_subcmd = setting_args[0] + subcmd = Command.find(SetCommand::SetHistorySubcommands, try_subcmd) + return print "Invalid history parameter #{try_subcmd}. Should be" \ + ' "filename", "save" or "size"' unless subcmd + + sub_sub_cmd = setting_args[1] + iface = @state.interface + case subcmd.name + when /^save$/ + iface.history_save = sub_sub_cmd ? get_onoff(sub_sub_cmd) : true + when /^size$/ + return print 'You need to specify the history size' unless sub_sub_cmd + iface.history_length = get_int(sub_sub_cmd, "Set history size") + when /^filename$/ + return print 'You need to specify a filename' unless sub_sub_cmd + iface.histfile = File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", sub_sub_cmd) + end + when /^linetrace$/ + Byebug.tracing = setting_value + when /^listsize$/ + listsize = get_int(setting_args[0], "Set listsize", 1, nil, 10) + return unless listsize + Command.settings[:listsize] = listsize + when /^width$/ + return unless width = get_int(setting_args[0], "Set width", 10, nil, 80) + Command.settings[:width] = width + when /^post_mortem$/ + if setting_value == true + Byebug.post_mortem + else + return print 'Sorry... not implemented yet. Restart byebug' + end + when /^autoeval|autoreload|basename|forcestep|fullpath|linetrace_plus| + testing|stack_on_error$/x + Command.settings[setting_name.to_sym] = setting_value + else + return print "Unknown setting #{@match[1]}.\n" + end + end + end + + # Implements byebug "set" command. + class SetCommand < Command + Subcmd2 = Struct.new(:name, :min, :is_bool, :help) unless defined?(Subcmd2) + + Subcommands = [ + ['args' , 2 , false, 'Set argument list to the program ' \ + 'being debugged when it is started' ], + ['autoeval' , 4 , true , 'Evaluate every unrecognized command' ], + ['autolist' , 4 , true , 'Execute "list" command on every ' \ + 'breakpoint' ], + ['autoirb' , 4 , true , 'Invoke IRB on every stop' ], + ['autoreload' , 4 , true , 'Reload source code when changed' ], + ['basename' , 1 , true , 'Set filename display style' ], + ['callstyle' , 2 , false, 'Set how you want call parameters ' \ + 'displayed' ], + ['testing' , 2 , false, 'Used when testing byebug' ], + ['forcestep' , 2 , true , 'Make sure "next/step" commands always' \ + 'move to a new line' ], + ['fullpath' , 2 , true , 'Display full file names in frames' ], + ['history' , 2 , false, 'Command for setting command history ' \ + 'parameters, namely, "filename", ' \ + '"save" and "size"' ], + ['linetrace' , 3 , true , 'Enable line execution tracing' ], + ['linetrace_plus', 10, true , 'Set line execution tracing to show' \ + 'different lines' ], + ['listsize' , 3 , false, 'Set number of source lines to list by' \ + 'default' ], + ['post_mortem' , 2 , true , 'Enable post-mortem mode' ], + ['stack_on_error', 1 , true , 'Display stack trace when "eval" ' \ + 'raises exception' ], + ['verbose' , 1 , true , 'Enable verbose output of TracePoint ' \ + 'API events is enabled' ], + ['width' , 1 , false, 'Number of characters per line for ' \ + 'byebug\'s output' ] + ].map do |name, min, is_bool, help| + Subcmd2.new(name, min, is_bool, help) + end unless defined?(Subcommands) + + SetHistorySubcommands = [ + ['filename', 1, 'Set the filename in which to record command history'], + ['save' , 1, 'Set saving of the history record on exit' ], + ['size' , 1, 'Set the size of the command history' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(SetHistorySubcommands) + + self.allow_in_control = true + + def regexp + /^\s* set (?:\s+(.*))? \s*$/x + end + + def execute + return print SetCommand.help(nil) if SetCommand.names.include?(@match[0]) + + args = @match[1].split(/[ \t]+/) + try_subcmd = args.shift + try_subcmd.downcase! + if try_subcmd =~ /^no/i + set_on = false + try_subcmd = try_subcmd[2..-1] + else + set_on = true + end + + subcmd = Command.find(Subcommands, try_subcmd) + return print "Unknown set command \"#{try_subcmd}\"\n" unless subcmd + + begin + set_on = get_onoff(args[0]) if subcmd.is_bool and args.size > 0 + rescue RuntimeError + return + end + + set_setting(subcmd.name, set_on, args) + + return print "#{show_setting(subcmd.name)}\n" + end + + class << self + def names + %w(set) + end + + def description + %{Modifies parts of byebug environment. Boolean values take on, off, 1 + or 0. You can see these environment settings with the "show" command.} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/show.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/show.rb new file mode 100644 index 0000000..58ef987 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/show.rb @@ -0,0 +1,224 @@ +module Byebug + + # Mix-in module to showing settings + module ShowFunctions + + def show_setting(setting_name) + case setting_name + when /^args$/ + if Command.settings[:argv] and Command.settings[:argv].size > 0 + if defined?(Byebug::BYEBUG_SCRIPT) + # byebug was called initially. 1st arg is script name. + args = Command.settings[:argv][1..-1].join(' ') + else + # byebug wasn't called initially. 1st arg is not script name. + args = Command.settings[:argv].join(' ') + end + else + args = '' + end + return "Argument list to give program being debugged when it is started is \"#{args}\"." + when /^autolist$/ + on_off = Command.settings[:autolist] > 0 + return "autolist is #{show_onoff(on_off)}." + when /^autoeval$/ + on_off = Command.settings[:autoeval] + return "autoeval is #{show_onoff(on_off)}." + when /^autoreload$/ + on_off = Command.settings[:autoreload] + return "autoreload is #{show_onoff(on_off)}." + when /^autoirb$/ + on_off = Command.settings[:autoirb] > 0 + return "autoirb is #{show_onoff(on_off)}." + when /^basename$/ + on_off = Command.settings[:basename] + return "basename is #{show_onoff(on_off)}." + when /^callstyle$/ + style = Command.settings[:callstyle] + return "Frame call-display style is #{style}." + when /^commands(:?\s+(\d+))?$/ + if @state.interface.readline_support? + s = ''; + args = @match[1].split + if args[1] + first_line = args[1].to_i - 4 + last_line = first_line + 10 - 1 + if first_line > Readline::HISTORY.length + first_line = last_line = Readline::HISTORY.length + elsif first_line <= 0 + first_line = 1 + end + if last_line > Readline::HISTORY.length + last_line = Readline::HISTORY.length + end + i = first_line + commands = Readline::HISTORY.to_a[first_line..last_line] + else + if Readline::HISTORY.length > 10 + commands = Readline::HISTORY.to_a[-10..-1] + i = Readline::HISTORY.length - 10 + else + commands = Readline::HISTORY.to_a + i = 1 + end + end + commands.each do |cmd| + s += ("%5d %s\n" % [i, cmd]) + i += 1 + end + else + s='No readline support' + end + return s + when /^testing$/ + on_off = Command.settings[:testing] + return "Currently testing byebug is #{show_onoff(on_off)}." + when /^forcestep$/ + on_off = Command.settings[:forcestep] + return "force-stepping is #{show_onoff(on_off)}." + when /^fullpath$/ + on_off = Command.settings[:fullpath] + return "Displaying frame's full file names is #{show_onoff(on_off)}." + when /^history(:?\s+(filename|save|size))?$/ + args = @match[1].split + interface = @state.interface + if args[1] + show_save = show_size = show_filename = false + prefix = false + if args[1] == "save" + show_save = true + elsif args[1] == "size" + show_size = true + elsif args[1] == "filename" + show_filename = true + end + else + show_save = show_size = show_filename = true + prefix = true + end + s = [] + if show_filename + msg = "#{prefix ? 'filename:' : ''} The command history file is " \ + "#{interface.histfile.inspect}" + s << msg + end + if show_save + msg = (prefix ? "save: " : "") + + "Saving of history save is #{show_onoff(interface.history_save)}." + s << msg + end + if show_size + msg = (prefix ? "size: " : "") + + "Byebug history size is #{interface.history_length}" + s << msg + end + return s.join("\n") + when /^linetrace$/ + on_off = Byebug.tracing? + return "line tracing is #{show_onoff(on_off)}." + when /^linetrace_plus$/ + if Command.settings[:linetrace_plus] + return "line tracing style is every line." + else + return "line tracing style is different consecutive lines." + end + when /^listsize$/ + listlines = Command.settings[:listsize] + return "Number of source lines to list is #{listlines}." + when /^post_mortem$/ + on_off = Byebug.post_mortem? + return "post-mortem mode is #{show_onoff(on_off)}" + when /^stack_on_error$/ + on_off = Command.settings[:stack_on_error] + return "Displaying stack trace is #{show_onoff(on_off)}." + when /^verbose$/ + on_off = Byebug.verbose + return "Verbose output of TracePoint API events is #{show_onoff(on_off)}." + when /^version$/ + return "Byebug #{Byebug::VERSION}" + when /^width$/ + return "width is #{Command.settings[:width]}." + else + return "Unknown show subcommand #{setting_name}." + end + end + end + + # Implements byebug "show" command. + class ShowCommand < Command + + Subcommands = [ + ['args' , 2 , 'Show argument list to the program being ' \ + 'debugged when it is started' ], + ['autoeval' , 4 , 'Show whether unrecognized commands are ' \ + 'evaluated' ], + ['autolist' , 4 , 'Show whether "list" command is run on stopping' ], + ['autoirb' , 4 , 'Show whether IRB is invoked on stopping' ], + ['autoreload' , 4 , 'Show whether source code is reloaded when ' \ + 'changed' ], + ['basename' , 1 , 'Show whether basename is used when reporting' \ + ' files' ], + ['callstyle' , 2 , 'Show parameter style used when showing call' \ + ' frames' ], + ['commands' , 2 , 'Show the history of commands you typed. You ' \ + 'can supply a command number to start with' ], + ['forcestep' , 1 , 'Show whether "next/step" commands are set to' \ + ' always move to a line' ], + ['fullpath' , 2 , 'Show whether full paths are displayed in frames'], + ['history' , 2 , 'Show command history configurations. ' ], + ['linetrace' , 3 , 'Show line execution tracing status' ], + ['linetrace_plus', 10, 'Show whether different consecutive lines are' \ + ' shown in tracing' ], + ['listsize' , 3 , 'Show number of source lines to list by default' ], + ['post_mortem' , 3 , 'Show whether we should go into post-mortem ' \ + 'debugging on an uncaught exception' ], + ['stack_on_error', 1 , 'Show whether a stack trace is displayed when' \ + ' "eval" raises an exception' ], + ['verbose' , 4 , 'Show whether verbose output for debugging ' \ + 'byebug itself is enabled' ], + ['version' , 1 , 'Show byebug\'s version' ], + ['width' , 1 , 'Show the number of characters per line for ' \ + 'byebug' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(Subcommands) + + ShowHistorySubcommands = [ + ['filename', 1, 'Show the filename in which to record command history' ], + ['save' , 1, 'Show whether history record should be saved on exit' ], + ['size' , 1, 'Show the size of the command history' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(SetHistorySubcommands) + + self.allow_in_control = true + + def regexp + /^\s* show (?:\s+(.+))? \s*$/x + end + + def execute + return print ShowCommand.help(nil) unless @match[1] + + args = @match[1].split(/[ \t]+/) + param = args.shift + subcmd = Command.find(Subcommands, param) + if subcmd + print "%s\n" % show_setting(subcmd.name) + else + print "Unknown show command #{param}\n" + end + end + + class << self + def names + %w(show) + end + + def description + %{Generic command for showing things about byebug.} + end + end + + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/skip.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/skip.rb new file mode 100644 index 0000000..d3bd829 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/skip.rb @@ -0,0 +1,30 @@ +module Byebug + + # Implements byebug "skip" command + class SkipCommand < Command + self.allow_in_control = true + + def regexp + /^\s* sk(?:ip)? \s*$/x + end + + def execute + Byebug::skip_next_exception + print "ok\n" + end + + class << self + def names + %w(skip) + end + + def description + %{sk[ip]\tskip the next thrown exception + + This is useful if you've explicitly caught an exception through the + "catch" command, and wish to pass the exception on to the code that + you're debugging.} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/source.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/source.rb new file mode 100644 index 0000000..a353dc0 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/source.rb @@ -0,0 +1,36 @@ +module Byebug + + # Implements byebug "source" command. + class SourceCommand < Command + self.allow_in_control = true + + def regexp + /^\s* so(?:urce)? (?:\s+(\S+))? \s*$/x + end + + def execute + return print SourceCommand.help(nil) if + SourceCommand.names.include?(@match[0]) + + file = File.expand_path(@match[1]).strip + return errmsg "File \"#{file}\" not found\n" unless File.exist?(file) + + if @state and @state.interface + @state.interface.command_queue += File.open(file).readlines + else + Byebug.run_script(file, @state) + end + end + + class << self + def names + %w(source) + end + + def description + %{source FILE\texecutes a file containing byebug commands} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/stepping.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/stepping.rb new file mode 100644 index 0000000..886c281 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/stepping.rb @@ -0,0 +1,78 @@ +module Byebug + + # Mix-in module to assist in command parsing. + module SteppingFunctions + def parse_stepping_args(command_name, match) + if match[1].nil? + force = Command.settings[:forcestep] + elsif match[1] == '+' + force = true + elsif match[1] == '-' + force = false + end + steps = get_int(match[2], command_name, 1) + return [steps, force] + end + end + + # Implements byebug "next" command. + class NextCommand < Command + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s* n(?:ext)?([+-])? (?:\s+(\S+))? \s*$/x + end + + def execute + steps, force = parse_stepping_args("Next", @match) + return unless steps + @state.context.step_over steps, @state.frame_pos, force + @state.proceed + end + + class << self + def names + %w(next) + end + + def description + %{n[ext][+-]?[ nnn]\tstep over once or nnn times, + \t\t'+' forces to move to another line. + \t\t'-' is the opposite of '+' and disables the :forcestep setting. + } + end + end + end + + # Implements byebug "step" command. + class StepCommand < Command + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s* s(?:tep)?([+-]) ?(?:\s+(\S+))? \s*$/x + end + + def execute + steps, force = parse_stepping_args("Step", @match) + return unless steps + @state.context.step_into steps, force + @state.proceed + end + + class << self + def names + %w(step) + end + + def description + %{ + s[tep][+-]?[ nnn]\tstep (into methods) once or nnn times + \t\t'+' forces to move to another line. + \t\t'-' is the opposite of '+' and disables the :forcestep setting. + } + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/threads.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/threads.rb new file mode 100644 index 0000000..6910cc6 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/threads.rb @@ -0,0 +1,204 @@ +module Byebug + module ThreadFunctions + def display_context(context, should_show_top_frame = true) + args = thread_arguments(context, should_show_top_frame) + print "%s%s%d %s\t%s\n", args[:status_flag], args[:debug_flag], args[:id], + args[:thread], args[:file_line] + end + + def thread_arguments(context, should_show_top_frame = true) + status_flag = if context.suspended? + "$" + else + context.thread == Thread.current ? '+' : ' ' + end + debug_flag = context.ignored? ? '!' : ' ' + if should_show_top_frame + if context.thread == Thread.current && !context.dead? + file = context.frame_file(0) + line = context.frame_line(0) + else + if context.thread.backtrace_locations && + context.thread.backtrace_locations[0] + file = context.thread.backtrace_locations[0].path + line = context.thread.backtrace_locations[0].lineno + end + end + file_line = "#{file}:#{line}" + end + { + status_flag: status_flag, + debug_flag: debug_flag, + id: context.thnum, + thread: context.thread.inspect, + file_line: file_line ? file_line : '' + } + end + + def parse_thread_num(subcmd, arg) + if '' == arg + errmsg "\"#{subcmd}\" needs a thread number" + nil + else + thread_num = get_int(arg, subcmd, 1) + return nil unless thread_num + get_context(thread_num) + end + end + + def parse_thread_num_for_cmd(subcmd, arg) + c = parse_thread_num(subcmd, arg) + return nil unless c + case + when nil == c + errmsg 'No such thread' + when @state.context == c + errmsg "It's the current thread" + when c.ignored? + errmsg "Can't #{subcmd} thread #{arg}" + else + return c + end + return nil + end + + end + + class ThreadListCommand < Command + self.allow_in_control = true + + def regexp + /^\s* th(?:read)? \s+ l(?:ist)? \s*$/x + end + + def execute + Byebug.contexts.select { |c| Thread.list.include?(c.thread) } + .sort_by(&:thnum).each { |c| display_context(c) } + end + + class << self + def names + %w(thread) + end + + def description + %{ + th[read] l[ist]\t\t\tlist all threads + } + end + end + end + + class ThreadCurrentCommand < Command + self.need_context = true + + def regexp + /^\s* th(?:read)? \s+ (?:cur(?:rent)?)? \s*$/x + end + + def execute + display_context(@state.context) + end + + class << self + def names + %w(thread) + end + + def description + %{th[read] [cur[rent]]\t\tshow current thread} + end + end + end + + class ThreadStopCommand < Command + self.allow_in_control = true + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s* th(?:read)? \s+ stop \s* (\S*) \s*$/x + end + + def execute + c = parse_thread_num_for_cmd('thread stop', @match[1]) + return unless c + c.suspend + display_context(c) + end + + class << self + def names + %w(thread) + end + + def description + %{th[read] stop \t\tstop thread nnn} + end + end + end + + class ThreadResumeCommand < Command + self.allow_in_control = true + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s* th(?:read)? \s+ resume \s* (\S*) \s*$/x + end + + def execute + c = parse_thread_num_for_cmd('thread resume', @match[1]) + return unless c + if !c.suspended? + errmsg 'Already running' + return + end + c.resume + display_context(c) + end + + class << self + def names + %w(thread) + end + + def description + %{th[read] resume \t\tresume thread nnn} + end + end + end + + class ThreadSwitchCommand < Command + self.allow_in_control = true + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s* th(?:read)? \s+ (?:sw(?:itch)?\s+)? (\S+) \s*$/x + end + + def execute + if @match[1] =~ /switch/ + errmsg '"thread switch" needs a thread number' + return + end + c = parse_thread_num_for_cmd('thread switch', @match[1]) + return unless c + display_context(c) + c.step_into 1 + c.thread.run + @state.proceed + end + + class << self + def names + %w(thread) + end + + def description + %{th[read] [sw[itch]] \tswitch thread context to nnn} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/trace.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/trace.rb new file mode 100644 index 0000000..547b9be --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/trace.rb @@ -0,0 +1,49 @@ +module Byebug + + class TraceCommand < Command + def regexp + /^\s* tr(?:ace)? (?: \s+ (\S+)) # on | off | var(iable) + (?: \s+ (\S+))? # (variable-name)? + (?: \s+ (\S+))? # (stop | nostop)? + \s*$/x + end + + def execute + if @match[1] =~ /on|off/ + onoff = 'on' == @match[1] + Byebug.tracing = onoff + print "#{show_setting('linetrace')}\n" + elsif @match[1] =~ /var(?:iable)?/ + varname = @match[2] + if global_variables.include?("$#{varname}".to_sym) + if @match[3] && @match[3] !~ /(:?no)?stop/ + errmsg "expecting \"stop\" or \"nostop\"; got \"#{@match[3]}\"\n" + else + dbg_cmd = (@match[3] && @match[3] !~ /nostop/) ? 'byebug(1,0)' : '' + end + eval("trace_var(:\"\$#{varname}\") do |val| + print \"traced global variable '#{varname}' has value '\#{val}'\"\n + #{dbg_cmd} + end") + print "Tracing global variable \"#{varname}\".\n" + else + errmsg "'#{varname}' is not a global variable.\n" + end + else + errmsg "expecting \"on\", \"off\", \"var\" or \"variable\"; got: " \ + "\"#{@match[1]}\"\n" + end + end + + class << self + def names + %w(trace) + end + + def description + %{tr[ace] (on|off)\tset trace mode + tr[ace] var(iable) VARNAME [stop|nostop]\tset trace variable on VARNAME} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/variables.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/variables.rb new file mode 100644 index 0000000..d229d4d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/variables.rb @@ -0,0 +1,189 @@ +module Byebug + + module VarFunctions + def var_list(ary, b = get_binding) + ary.sort! + for v in ary + begin + s = bb_eval(v.to_s, b).inspect + rescue + begin + s = bb_eval(v.to_s, b).to_s + rescue + s = "*Error in evaluation*" + end + end + pad_with_dots(s) + print "#{v} = #{s}\n" + end + end + def var_class_self + obj = bb_eval('self') + var_list(obj.class.class_variables, get_binding) + end + def var_global + var_list(global_variables.reject { |v| [:$=, :$KCODE, :$-K].include?(v) }) + end + end + + # Implements byebug's 'var class' command + class VarClassVarCommand < Command + def regexp + /^\s* v(?:ar)? \s+ cl(?:ass)? \s*/x + end + + def execute + unless @state.context + errmsg "can't get class variables here.\n" + return + end + var_class_self + end + + class << self + def names + %w(var) + end + + def description + %{v[ar] cl[ass] \t\t\tshow class variables of self} + end + end + end + + class VarConstantCommand < Command + def regexp + /^\s* v(?:ar)? \s+ co(?:nst(?:ant)?)? \s+/x + end + + def execute + obj = bb_eval(@match.post_match) + if obj.kind_of? Module + constants = bb_eval("#{@match.post_match}.constants") + constants.sort! + for c in constants + next if c =~ /SCRIPT/ + value = obj.const_get(c) rescue "ERROR: #{$!}" + print " %s => %p\n", c, value + end + else + print "Should be Class/Module: #{@match.post_match}\n" + end + end + + class << self + def names + %w(var) + end + + def description + %{v[ar] co[nst] \t\tshow constants of object} + end + end + end + + class VarGlobalCommand < Command + def regexp + /^\s* v(?:ar)? \s+ g(?:lobal)? \s*$/x + end + + def execute + var_global + end + + class << self + def names + %w(var) + end + + def description + %{v[ar] g[lobal]\t\t\tshow global variables} + end + end + end + + class VarInstanceCommand < Command + def regexp + /^\s* v(?:ar)? \s+ ins(?:tance)? \s*/x + end + + def execute + obj = bb_eval(@match.post_match.empty? ? 'self' : @match.post_match) + var_list(obj.instance_variables, obj.instance_eval{binding()}) + end + + class << self + def names + %w(var) + end + + def description + %{v[ar] i[nstance] \tshow instance variables of object} + end + end + end + + # Implements byebug's 'var local' command + class VarLocalCommand < Command + def regexp + /^\s* v(?:ar)? \s+ l(?:ocal)? \s*$/x + end + + def execute + _self = @state.context.frame_self(@state.frame_pos) + locals = @state.context.frame_locals + locals.keys.sort.each do |name| + print " %s => %p\n", name, locals[name] + end + end + + class << self + def names + %w(var) + end + + def description + %{v[ar] l[ocal]\t\t\tshow local variables} + end + end + end + + begin + require 'classtree' + have_classtree = true + rescue LoadError + have_classtree = false + end + + # Implements byebug's 'var inherit' command + class VarInheritCommand < Command + def regexp + /^\s* v(?:ar)? \s+ ct \s*$/x + end + + def execute + unless @state.context + errmsg "can't get object inheritance.\n" + return + end + puts @match.post_match + obj = bb_eval("#{@match.post_match}.classtree") + if obj + print obj + else + errmsg "Trouble getting object #{@match.post_match}\n" + end + end + + class << self + def names + %w(var) + end + + def description + %{v[ar] ct\t\t\tshow class heirarchy of object} + end + end + end if have_classtree + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/context.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/context.rb new file mode 100644 index 0000000..376991b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/context.rb @@ -0,0 +1,89 @@ +module Byebug + + class Context + + class << self + def stack_size + if backtrace = Thread.current.backtrace_locations(0) + backtrace.drop_while { |l| !ignored(l.path) } + .drop_while { |l| ignored(l.path) } + .take_while { |l| !ignored(l.path) } + .size + else + print 'No backtrace available!!' + 0 + end + end + + def real_stack_size + if backtrace = Thread.current.backtrace_locations(0) + backtrace.size + end + end + + def ignored(path) + IGNORED_FILES.include?(path) + end + private :ignored + end + + def interrupt + self.step_into 1 + end + + def frame_locals frame_no = 0 + bind = frame_binding frame_no + eval "local_variables.inject({}){|h, v| h[v] = eval(v.to_s); h}", bind + end + + def c_frame_args frame_no + myself = frame_self frame_no + return [] unless myself.to_s != 'main' + myself.send(:method, frame_method(frame_no)).parameters + end + + def ruby_frame_args bind + return [] unless eval '__method__', bind + begin + eval "self.method(__method__).parameters", bind + rescue NameError => e + print "WARNING: Got exception #{e.class}: \"#{e.message}\" " \ + "while retreving parameters from frame\n" + return [] + end + end + + def frame_args frame_no = 0 + bind = frame_binding frame_no + if bind.nil? + c_frame_args frame_no + else + ruby_frame_args bind + end + end + + def handler + Byebug.handler or raise 'No interface loaded' + end + + def at_breakpoint(brkpnt) + handler.at_breakpoint(self, brkpnt) + end + + def at_catchpoint(excpt) + handler.at_catchpoint(self, excpt) + end + + def at_tracing(file, line) + handler.at_tracing(self, file, line) + end + + def at_line(file, line) + handler.at_line(self, file, line) + end + + def at_return(file, line) + handler.at_return(self, file, line) + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/control_command_processor.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/control_command_processor.rb new file mode 100644 index 0000000..e3654d2 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/control_command_processor.rb @@ -0,0 +1,79 @@ +require 'forwardable' +require_relative 'interface' +require_relative 'command' + +module Byebug + + class ControlCommandProcessor < Processor + def initialize(interface) + super(interface) + @context_was_dead = false # Assume we haven't started. + end + + def process_commands(verbose=false) + control_cmds = Command.commands.select do |cmd| + cmd.allow_in_control + end + state = State.new(@interface, control_cmds) + commands = control_cmds.map{|cmd| cmd.new(state) } + + if @context_was_dead + print "The program finished.\n" + @context_was_dead = false + end + + while input = @interface.read_command(prompt(nil)) + print "+#{input}" if verbose + catch(:debug_error) do + if cmd = commands.find{|c| c.match(input) } + cmd.execute + else + errmsg "Unknown command\n" + end + end + end + rescue IOError, Errno::EPIPE + rescue Exception + print "INTERNAL ERROR!!! #{$!}\n" rescue nil + print $!.backtrace.map{|l| "\t#{l}"}.join("\n") rescue nil + ensure + @interface.close + end + + # + # Prompt shown before reading a command. + # + def prompt(context) + return '(byebug:ctrl) ' + end + + class State + attr_reader :commands, :interface + + def initialize(interface, commands) + @interface = interface + @commands = commands + end + + def proceed + end + + extend Forwardable + def_delegators :@interface, :errmsg, :print + + def confirm(*args) + 'y' + end + + def context + nil + end + + def file + errmsg "No filename given.\n" + throw :debug_error + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/helper.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/helper.rb new file mode 100644 index 0000000..90904f9 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/helper.rb @@ -0,0 +1,69 @@ +module Byebug + + module ParseFunctions + Position_regexp = '(?:(\d+)|(.+?)[:.#]([^.:\s]+))' + + # Parse 'str' of command 'cmd' as an integer between + # min and max. If either min or max is nil, that + # value has no bound. + def get_int(str, cmd, min=nil, max=nil, default=1) + return default unless str + begin + int = Integer(str) + if min and int < min + print "\"#{cmd}\" argument \"#{str}\" needs to be at least #{min}.\n" + return nil + elsif max and int > max + print "\"#{cmd}\" argument \"#{str}\" needs to be at most #{max}.\n" + return nil + end + return int + rescue + print "\"#{cmd}\" argument \"#{str}\" needs to be a number.\n" + return nil + end + end + + # Return true if arg is 'on' or 1 and false arg is 'off' or 0. + # Any other value raises RuntimeError. + def get_onoff(arg, default=nil, print_error=true) + if arg.nil? or arg == '' + if default.nil? + if print_error + print "Expecting 'on', 1, 'off', or 0. Got nothing.\n" + raise RuntimeError + end + return default + end + end + case arg.downcase + when '1', 'on' + return true + when '0', 'off' + return false + else + if print_error + print "Expecting 'on', 1, 'off', or 0. Got: #{arg.to_s}.\n" + raise RuntimeError + end + end + end + + # Return 'on' or 'off' for supplied parameter. The parameter should + # be true, false or nil. + def show_onoff(bool) + if not [TrueClass, FalseClass, NilClass].member?(bool.class) + return "??" + end + return bool ? 'on' : 'off' + end + + # Return true if code is syntactically correct for Ruby. + def syntax_valid?(code) + eval("BEGIN {return true}\n#{code}", nil, "", 0) + rescue Exception + false + end + + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interface.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interface.rb new file mode 100644 index 0000000..576093b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interface.rb @@ -0,0 +1,34 @@ +module Byebug + class Interface + attr_writer :have_readline + + def initialize + @have_readline = false + end + + # Common routine for reporting byebug error messages. + # Derived classes may want to override this to capture output. + def errmsg(*args) + print '*** ' + print(*args) + end + + def format(*args) + if args.is_a?(Array) + new_args = args.first + new_args = new_args % args[1..-1] unless args[1..-1].empty? + else + new_args = args + end + new_args + end + + def escape(msg) + msg.gsub('%', '%%') + end + end + + require_relative 'interfaces/local_interface' + require_relative 'interfaces/script_interface' + require_relative 'interfaces/remote_interface' +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/local_interface.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/local_interface.rb new file mode 100644 index 0000000..42ff0c2 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/local_interface.rb @@ -0,0 +1,88 @@ +module Byebug + class LocalInterface < Interface + attr_accessor :command_queue, :history_length, :history_save, :histfile + attr_accessor :restart_file + + FILE_HISTORY = ".byebug_hist" unless defined?(FILE_HISTORY) + + def initialize() + super + @command_queue = [] + @have_readline = false + @history_save = true + @history_length = ENV["HISTSIZE"] ? ENV["HISTSIZE"].to_i : 256 + @histfile = File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", FILE_HISTORY) + open(@histfile, 'r') do |file| + file.each do |line| + line.chomp! + Readline::HISTORY << line + end + end if File.exist?(@histfile) + @restart_file = nil + end + + def read_command(prompt) + readline(prompt, true) + end + + def confirm(prompt) + readline(prompt, false) + end + + def print(*args) + STDOUT.printf(escape(format(*args))) + end + + def close + end + + # Things to do before quitting + def finalize + if Byebug.respond_to?(:save_history) + Byebug.save_history + end + end + + def readline_support? + @have_readline + end + + private + + begin + require 'readline' + class << Byebug + @have_readline = true + define_method(:save_history) do + iface = self.handler.interface + iface.histfile ||= File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", + FILE_HISTORY) + open(iface.histfile, 'w') do |file| + Readline::HISTORY.to_a.last(iface.history_length).each do |line| + file.puts line unless line.strip.empty? + end if defined?(iface.history_save) and iface.history_save + end rescue nil + end + public :save_history + end + + def readline(prompt, hist) + Readline::readline(prompt, hist) + rescue Interrupt + print "^C\n" + retry + end + rescue LoadError + def readline(prompt, hist) + @histfile = '' + @hist_save = false + STDOUT.print prompt + STDOUT.flush + line = STDIN.gets + exit unless line + line.chomp! + line + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/remote_interface.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/remote_interface.rb new file mode 100644 index 0000000..8e82c3f --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/remote_interface.rb @@ -0,0 +1,55 @@ +module Byebug + class RemoteInterface < Interface + attr_accessor :command_queue, :history_length, :history_save, :histfile + attr_accessor :restart_file + + def initialize(socket) + @command_queue = [] + @socket = socket + @history_save = false + @history_length = 256 + @histfile = '' + # Do we read the histfile? + # open(@histfile, 'r') do |file| + # file.each do |line| + # line.chomp! + # Readline::HISTORY << line + # end + # end if File.exist?(@histfile) + @restart_file = nil + end + + def close + @socket.close + rescue Exception + end + + def confirm(prompt) + send_command "CONFIRM #{prompt}" + end + + def finalize + end + + def read_command(prompt) + send_command "PROMPT #{prompt}" + end + + def readline_support? + false + end + + def print(*args) + @socket.printf(escape(format(*args))) + end + + private + + def send_command(msg) + @socket.puts msg + result = @socket.gets + raise IOError unless result + result.chomp + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/script_interface.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/script_interface.rb new file mode 100644 index 0000000..9262007 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/script_interface.rb @@ -0,0 +1,45 @@ +module Byebug + class ScriptInterface < Interface + attr_accessor :command_queue, :history_length, :history_save, :histfile + attr_accessor :restart_file + + def initialize(file, out, verbose=false) + super() + @command_queue = [] + @file = file.respond_to?(:gets) ? file : open(file) + @out = out + @verbose = verbose + @history_save = false + @history_length = 256 + @histfile = '' + end + + def finalize + end + + def read_command(prompt) + while result = @file.gets + puts "# #{result}" if @verbose + next if result =~ /^\s*#/ + next if result.strip.empty? + return result.chomp + end + end + + def readline_support? + false + end + + def confirm(prompt) + 'y' + end + + def print(*args) + @out.printf(*args) + end + + def close + @file.close + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/processor.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/processor.rb new file mode 100644 index 0000000..bcf2754 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/processor.rb @@ -0,0 +1,18 @@ +require 'forwardable' +require_relative 'interface' + +module Byebug + + # Should this be a mixin? + class Processor + attr_accessor :interface + + extend Forwardable + def_delegators :@interface, :errmsg, :print + + def initialize(interface) + @interface = interface + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/remote.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/remote.rb new file mode 100644 index 0000000..736da4f --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/remote.rb @@ -0,0 +1,99 @@ +require 'socket' + +module Byebug + + # Port number used for remote debugging + PORT = 8989 unless defined?(PORT) + + class << self + + # If in remote mode, wait for the remote connection + attr_accessor :wait_connection + + # The actual port that the server is started at + attr_accessor :actual_port + attr_reader :actual_control_port + + # + # Interrupts the current thread + # + def interrupt + current_context.interrupt + end + + # + # Starts a remote byebug + # + def start_server(host = nil, port = PORT) + return if @thread + + self.interface = nil + start + + start_control(host, port == 0 ? 0 : port + 1) + + yield if block_given? + + mutex = Mutex.new + proceed = ConditionVariable.new + + server = TCPServer.new(host, port) + self.actual_port = server.addr[1] + @thread = DebugThread.new do + while (session = server.accept) + self.interface = RemoteInterface.new(session) + if wait_connection + mutex.synchronize do + proceed.signal + end + end + end + end + if wait_connection + mutex.synchronize do + proceed.wait(mutex) + end + end + end + + def start_control(host = nil, ctrl_port = PORT + 1) + return @actual_control_port if @control_thread + server = TCPServer.new(host, ctrl_port) + @actual_control_port = server.addr[1] + @control_thread = Thread.new do + while (session = server.accept) + interface = RemoteInterface.new(session) + ControlCommandProcessor.new(interface).process_commands + end + end + @actual_control_port + end + + # + # Connects to the remote byebug + # + def start_client(host = 'localhost', port = PORT) + interface = Byebug::LocalInterface.new + socket = TCPSocket.new(host, port) + puts "Connected." + + catch(:exit) do + while (line = socket.gets) + case line + when /^PROMPT (.*)$/ + input = interface.read_command($1) + throw :exit unless input + socket.puts input + when /^CONFIRM (.*)$/ + input = interface.confirm($1) + throw :exit unless input + socket.puts input + else + print line + end + end + end + socket.close + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/version.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/version.rb new file mode 100644 index 0000000..1ae7fb5 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/version.rb @@ -0,0 +1,3 @@ +module Byebug + VERSION = '2.7.0' +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/breakpoints_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/breakpoints_test.rb new file mode 100644 index 0000000..f1b15a7 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/breakpoints_test.rb @@ -0,0 +1,453 @@ +class BreakpointExample + def self.a(num) + 4 + end + def b + 3 + end +end + +class BreakpointDeepExample + def a + z = 2 + b(z) + end + + def b(num) + v2 = 5 if 1 == num ; [1,2,v2].map { |a| a.to_f } + c + end + + def c + z = 4 + z += 5 + byebug + end +end + +class TestBreakpoints < TestDsl::TestCase + before do + @tst_file = fullpath('breakpoint') + end + + describe 'setting breakpoint in the current file' do + before { enter 'break 1' } + + subject { Byebug.breakpoints.first } + + def check_subject(field, value) + debug_file('breakpoint') { subject.send(field).must_equal value } + end + + it('must have correct pos') { check_subject(:pos, 1) } + it('must have correct source') { check_subject(:source, @tst_file) } + it('must have correct expression') { check_subject(:expr, nil) } + it('must have correct hit count') { check_subject(:hit_count, 0) } + it('must have correct hit value') { check_subject(:hit_value, 0) } + it('must be enabled') { check_subject(:enabled?, true) } + + it('must return right response') do + id = nil + debug_file('breakpoint') { id = subject.id } + check_output_includes "Created breakpoint #{id} at #{@tst_file}:1" + end + end + + describe 'using shortcut for the command' do + before { enter 'b 1' } + it 'must set a breakpoint' do + debug_file('breakpoint') { Byebug.breakpoints.size.must_equal 1 } + end + end + + describe 'setting breakpoint to unexistent line' do + before { enter 'break 100' } + + it 'must not create a breakpoint' do + debug_file('breakpoint') { Byebug.breakpoints.must_be_empty } + end + + it 'must show an error' do + debug_file('breakpoint') + check_error_includes \ + "There are only #{LineCache.size(@tst_file)} lines in file #{@tst_file}" + end + end + + describe 'setting breakpoint to incorrect line' do + before { enter 'break 2' } + + it 'must not create a breakpoint' do + debug_file('breakpoint') { Byebug.breakpoints.must_be_empty } + end + + it 'must show an error' do + debug_file('breakpoint') + check_error_includes \ + "Line 2 is not a stopping point in file #{@tst_file}" + end + end + + describe 'stopping at breakpoint' do + it 'must stop at the correct line' do + enter 'break 5', 'cont' + debug_file('breakpoint') { state.line.must_equal 5 } + end + + it 'must stop at the correct file' do + enter 'break 5', 'cont' + debug_file('breakpoint') { state.file.must_equal @tst_file } + end + + describe 'show a message' do + describe 'with full filename' do + it 'must show a message with full filename' do + enter 'break 5', 'cont' + debug_file('breakpoint') { @id = Byebug.breakpoints.first.id } + check_output_includes "Created breakpoint #{@id} at #{@tst_file}:5" + end + end + + describe 'with basename' do + temporary_change_hash Byebug.settings, :basename, true + + it 'must show a message with basename' do + enter 'break 5', 'cont' + debug_file('breakpoint') { @id = Byebug.breakpoints.first.id } + check_output_includes "Created breakpoint #{@id} at breakpoint.rb:5" + end + end + end + end + + describe 'reloading source on change' do + describe 'autoreload not set' do + temporary_change_hash Byebug.settings, :autoreload, false + + it 'must not reload source' do + id = nil + enter ->{ change_line_in_file(@tst_file, 5, ''); 'break 5' }, + ->{ change_line_in_file(@tst_file, 5, 'BreakpointExample.new.b'); + cont } + debug_file('breakpoint') { id = Byebug.breakpoints.first.id } + check_output_includes "Created breakpoint #{id} at #{@tst_file}:5" + end + end + + describe 'autoreload set' do + it 'must reload source' do + enter \ + ->{change_line_in_file(@tst_file, 5, ''); 'break 5'}, + ->{change_line_in_file(@tst_file, 5, 'BreakpointExample.new.b'); + 'next'} + debug_file 'breakpoint' + check_error_includes \ + "Line 5 is not a stopping point in file #{@tst_file}" + end + end + end + + describe 'set breakpoint in a file' do + describe 'successfully' do + before { enter "break #{__FILE__}:3", 'cont' } + + it 'must stop at the correct line' do + debug_file('breakpoint') { state.line.must_equal 3 } + end + + it 'must stop at the correct file' do + debug_file('breakpoint') { state.file.must_equal __FILE__ } + end + end + + describe 'when setting breakpoint to unexisted file' do + before do + enter 'break asf:324' + debug_file('breakpoint') + end + + it 'must show an error' do + check_error_includes 'No source file named asf' + end + + it 'must ask about setting breakpoint anyway' do + check_output_includes \ + 'Set breakpoint anyway? (y/n)', interface.confirm_queue + end + end + end + + describe 'set breakpoint to a method' do + describe 'set breakpoint to an instance method' do + before { enter 'break BreakpointExample#b', 'cont' } + + it 'must stop at the correct line' do + debug_file('breakpoint') { state.line.must_equal 5 } + end + + it 'must stop at the correct file' do + debug_file('breakpoint') { state.file.must_equal __FILE__ } + end + end + + describe 'set breakpoint to a class method' do + before { enter 'break BreakpointExample.a', 'cont' } + + it 'must stop at the correct line' do + debug_file('breakpoint') { state.line.must_equal 2 } + end + + it 'must stop at the correct file' do + debug_file('breakpoint') { state.file.must_equal __FILE__ } + end + end + + describe 'set breakpoint to unexisted class' do + it 'must show an error' do + enter 'break B.a' + debug_file('breakpoint') + check_error_includes 'Unknown class B.' + end + end + end + + describe 'set breakpoint to an invalid location' do + before { enter 'break foo' } + + it 'must not create a breakpoint' do + debug_file('breakpoint') { Byebug.breakpoints.must_be_empty } + end + + it 'must show an error' do + debug_file('breakpoint') + check_error_includes 'Invalid breakpoint location: foo.' + end + end + + describe 'disabling breakpoints' do + describe 'successfully' do + before { enter 'break 5', 'break 6' } + + describe 'short syntax' do + before { enter ->{ "disable #{Byebug.breakpoints.first.id}" } } + + it 'must have a breakpoint with #enabled? returning false' do + debug_file('breakpoint') { + Byebug.breakpoints.first.enabled?.must_equal false } + end + + it 'must not stop on the disabled breakpoint' do + enter 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + end + end + + describe 'full syntax' do + describe 'with no args' do + before { enter 'disable breakpoints' } + + it 'must have all breakoints with #enabled? returning false' do + debug_file('breakpoint') do + Byebug.breakpoints.first.enabled?.must_equal false + Byebug.breakpoints.last.enabled?.must_equal false + end + end + + it 'must not stop on any disabled breakpoint' do + enter 'cont' + debug_file('breakpoint') + # Obscure assert to check for program termination + state.proceed.must_equal true + end + end + + describe 'with specific breakpoint' do + before do + enter ->{ "disable breakpoints #{Byebug.breakpoints.first.id}" } + end + + it 'must have a breakpoint with #enabled? returning false' do + debug_file('breakpoint') { + Byebug.breakpoints.first.enabled?.must_equal false } + end + end + end + end + + describe 'unsuccesfully' do + it 'must show an error if syntax is incorrect' do + enter 'disable' + debug_file('breakpoint') + check_error_includes '"disable" must be followed by "display", ' \ + '"breakpoints" or breakpoint numbers.' + end + + it 'must show an error if no breakpoints are set' do + enter 'disable 1' + debug_file('breakpoint') + check_error_includes 'No breakpoints have been set.' + end + + it 'must show an error if a number is not provided as an argument' do + enter 'break 5', 'disable foo' + debug_file('breakpoint') + check_output_includes \ + '"disable breakpoints" argument "foo" needs to be a number.' + end + end + end + + describe 'enabling breakpoints' do + describe 'successfully' do + before { enter 'break 5', 'break 6', 'disable breakpoints' } + + describe 'short syntax' do + before { enter ->{ "enable #{Byebug.breakpoints.first.id}" } } + + it 'must have a breakpoint with #enabled? returning true' do + debug_file('breakpoint') { + Byebug.breakpoints.first.enabled?.must_equal true } + end + + it 'must stop on the enabled breakpoint' do + enter 'cont' + debug_file('breakpoint') { state.line.must_equal 5 } + end + end + + describe 'full syntax' do + describe 'with no args' do + before { enter 'enable breakpoints' } + + it 'must have all breakoints with #enabled? returning true' do + debug_file('breakpoint') do + Byebug.breakpoints.first.enabled?.must_equal true + Byebug.breakpoints.last.enabled?.must_equal true + end + end + + it 'must stop on the first breakpoint' do + enter 'cont' + debug_file('breakpoint') { state.line.must_equal 5 } + end + + it 'must stop on the last breakpoint' do + enter 'cont', 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + end + end + + describe 'with specific breakpoint' do + before do + enter ->{ "enable breakpoints #{Byebug.breakpoints.last.id}" } + end + + it 'must have a breakpoint with #enabled? returning true' do + debug_file('breakpoint') { + Byebug.breakpoints.last.enabled?.must_equal true } + end + + it 'must stop only on the enabled breakpoint' do + enter 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + end + end + end + end + + describe 'errors' do + it 'must show an error if syntax is incorrect' do + enter 'enable' + debug_file('breakpoint') + check_error_includes '"enable" must be followed by "display", ' \ + '"breakpoints" or breakpoint numbers.' + end + end + end + + describe 'deleting a breakpoint' do + before { enter 'break 5', ->{"delete #{Byebug.breakpoints.first.id}"}, + 'break 6' } + + it 'must have only one breakpoint' do + debug_file('breakpoint') { Byebug.breakpoints.size.must_equal 1 } + end + + it 'must not stop on the disabled breakpoint' do + enter 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + end + end + + describe 'Conditional breakpoints' do + it 'must stop if the condition is true' do + enter 'break 5 if z == 5', 'break 6', 'cont' + debug_file('breakpoint') { state.line.must_equal 5 } + end + + it 'must skip if the condition is false' do + enter 'break 5 if z == 3', 'break 6', 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + end + + it 'must show an error when conditional syntax is wrong' do + enter 'break 5 ifa z == 3', 'break 6', 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + check_error_includes \ + 'Expecting "if" in breakpoint condition; got: ifa z == 3.' + end + + describe 'enabling with wrong conditional syntax' do + before { enter 'break 5', + ->{"disable #{Byebug.breakpoints.first.id}"}, + ->{"cond #{Byebug.breakpoints.first.id} z -=( 3"}, + ->{"enable #{Byebug.breakpoints.first.id}"} } + + it 'must not enable a breakpoint' do + debug_file('breakpoint') { + Byebug.breakpoints.first.enabled?.must_equal false } + end + + it 'must show an error' do + debug_file('breakpoint') + check_error_includes 'Expression "z -=( 3" syntactically incorrect; ' \ + 'breakpoint remains disabled.' + end + end + + it 'must show an error if no file or line is specified' do + enter 'break ifa z == 3', 'break 6', 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + check_error_includes 'Invalid breakpoint location: ifa z == 3.' + end + + it 'must show an error if expression syntax is invalid' do + enter 'break if z -=) 3', 'break 6', 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + check_error_includes \ + 'Expression "z -=) 3" syntactically incorrect; breakpoint disabled.' + end + end + + describe 'Stopping through `byebug` keyword' do + describe 'when not the last instruction of a method' do + it 'must stop in the next line' do + debug_file('breakpoint') { state.line.must_equal 4 } + end + end + + describe 'when last instruction of a method' do + it 'must stop right before returning from the frame' do + debug_file('breakpoint_deep') { state.line.must_equal 25 } + end + end + end + + describe 'Help' do + it 'must show info about setting breakpoints when using just "break"' do + enter 'break', 'cont' + debug_file 'breakpoint' + check_output_includes(/b\[reak\] file:line \[if expr\]/) + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/conditions_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/conditions_test.rb new file mode 100644 index 0000000..1034a28 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/conditions_test.rb @@ -0,0 +1,69 @@ +class TestConditions < TestDsl::TestCase + + describe 'setting condition' do + before { enter 'break 3' } + + describe 'successfully' do + before { enter ->{ "cond #{Byebug.breakpoints.first.id} b == 5" }, 'cont'} + + it 'must assign the expression to breakpoint' do + debug_file('conditions') { + Byebug.breakpoints.first.expr.must_equal 'b == 5' } + end + + it 'must stop at the breakpoint if condition is true' do + debug_file('conditions') { state.line.must_equal 3 } + end + + it 'must work with full command name too' do + debug_file('conditions') { state.line.must_equal 3 } + end + end + + describe 'unsuccessfully' do + before { enter 'break 4' } + + it 'must not stop at the breakpoint if condition is false' do + enter ->{ "cond #{Byebug.breakpoints.first.id} b == 3" }, 'cont' + debug_file('conditions') { state.line.must_equal 4 } + end + + it 'must assign expression to breakpoint in spite of incorrect syntax' do + enter ->{ "cond #{Byebug.breakpoints.first.id} b =="}, 'cont' + debug_file('conditions') { + Byebug.breakpoints.first.expr.must_equal 'b ==' } + end + + it 'must ignore the condition if when incorrect syntax' do + enter ->{ "cond #{Byebug.breakpoints.first.id} b ==" }, 'cont' + debug_file('conditions') { state.line.must_equal 4 } + end + end + end + + describe 'removing conditions' do + before { enter 'break 3 if b == 3', 'break 4', + ->{"cond #{Byebug.breakpoints.first.id}"}, 'cont' } + + it 'must remove the condition from the breakpoint' do + debug_file('conditions') { Byebug.breakpoints.first.expr.must_be_nil } + end + + it 'must unconditionally stop on the breakpoint' do + debug_file('conditions') { state.line.must_equal 3 } + end + end + + describe 'errors' do + it 'must show error if there are no breakpoints' do + enter 'cond 1 true' + debug_file('conditions') + check_output_includes 'No breakpoints have been set.' + end + + it 'must not set breakpoint condition if breakpoint id is incorrect' do + enter 'break 3', 'cond 8 b == 3', 'cont' + debug_file('conditions') { state.line.must_equal 3 } + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/continue_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/continue_test.rb new file mode 100644 index 0000000..1c48a00 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/continue_test.rb @@ -0,0 +1,39 @@ +class ContinueExample + def self.a(num) + num + 4 + end +end + +class TestContinue < TestDsl::TestCase + + describe "successful" do + it "must continue up to breakpoint if no line specified" do + enter 'break 4', 'continue' + debug_file('continue') { state.line.must_equal 4 } + end + + it "must work in abbreviated mode too" do + enter 'break 4', 'cont' + debug_file('continue') { state.line.must_equal 4 } + end + + it "must continue up to specified line" do + enter 'cont 4' + debug_file('continue') { state.line.must_equal 4 } + end + end + + describe "unsuccessful" do + it "must ignore the command if specified line is not valid" do + enter 'cont 123' + debug_file('continue') { state.line.must_equal 3 } + end + + it "must show error if specified line is not valid" do + enter 'cont 123' + debug_file 'continue' + check_error_includes \ + "Line 123 is not a stopping point in file \"#{fullpath('continue')}\"" + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/debugger_alias_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/debugger_alias_test.rb new file mode 100644 index 0000000..ddcb039 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/debugger_alias_test.rb @@ -0,0 +1,5 @@ +class TestDebuggerAlias < MiniTest::Spec + it 'aliases "debugger" to "byebug"' do + Kernel.method(:debugger).must_equal(Kernel.method(:byebug)) + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/display_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/display_test.rb new file mode 100644 index 0000000..82813a3 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/display_test.rb @@ -0,0 +1,124 @@ +class TestDisplay < TestDsl::TestCase + + it 'must show expressions' do + enter 'break 3', 'cont', 'display d + 1' + debug_file 'display' + check_output_includes '1: ', 'd + 1 = 5' + end + + it 'must work with shortcut' do + enter 'break 3', 'cont', 'disp d + 1' + debug_file 'display' + check_output_includes '1: ', 'd + 1 = 5' + end + + it 'must save displayed expressions' do + enter 'display d + 1' + debug_file('display') { state.display.must_equal [[true, 'd + 1']] } + end + + it 'displays all expressions available' do + enter 'break 3', 'cont', -> do + Byebug.handler.display.concat([[true, 'abc'], [true, 'd']]); 'display' + end + debug_file 'display' + check_output_includes '1: ', 'abc = nil', '2: ', 'd = 4' + end + + describe 'undisplay' do + describe 'undisplay all' do + before do + enter 'break 3', 'cont', -> do + Byebug.handler.display.concat([[true, 'abc'], [true, 'd']]) + 'undisplay' + end, confirm_response, 'display' + end + + describe 'confirmation is successful' do + let(:confirm_response) { 'y' } + + it 'must ask about confirmation' do + debug_file 'display' + check_output_includes \ + 'Clear all expressions? (y/n)', interface.confirm_queue + end + + it 'must set all expressions saved to "false"' do + debug_file('display') { state.display.must_equal [[false, 'abc'], + [false, 'd']] } + end + + it 'must not show any output' do + debug_file 'display' + check_output_doesnt_include '1: ', 'abc = nil', '2: ', 'd = 4' + end + end + + describe 'confirmation is unsuccessful' do + let(:confirm_response) { 'n' } + + it 'must set all expressions saved to "false"' do + debug_file('display') { state.display.must_equal [[true, 'abc'], + [true, 'd']] } + end + + it 'must not show any output' do + debug_file 'display' + check_output_includes '1: ', 'abc = nil', '2: ', 'd = 4' + end + end + end + + describe 'undisplay specific position' do + before do + enter 'break 3', 'cont', -> do + Byebug.handler.display.concat([[true, 'abc'], [true, 'd']]) + 'undisplay 1' + end, 'display' + end + + it 'must set inactive positions' do + debug_file('display') { state.display.must_equal [[nil, 'abc'], + [true, 'd']] } + end + + it 'must display only the active position' do + debug_file 'display' + check_output_includes '2: ', 'd = 4' + end + + it 'must not display the disabled position' do + debug_file 'display' + check_output_doesnt_include '1: ', 'abc' + end + end + end + + describe 'disable' do + it 'must disable a position' do + enter 'display d', 'disable display 1' + debug_file('display') { state.display.must_equal [[false, 'd']] } + end + + it 'must show an error if no displays are set' do + enter 'disable display 1' + debug_file 'display' + check_output_includes \ + 'No display expressions have been set.', interface.error_queue + end + + it 'must show an error if there is no such display position' do + enter 'display d', 'disable display 4' + debug_file 'display' + check_output_includes \ + '"disable display" argument "4" needs to be at most 1.' + end + end + + describe 'enable' do + it 'must enable a position' do + enter 'display d', 'disable display 1', 'enable display 1' + debug_file('display') { state.display.must_equal [[true, 'd']] } + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/edit_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/edit_test.rb new file mode 100644 index 0000000..3781b6f --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/edit_test.rb @@ -0,0 +1,47 @@ +class TestEdit < TestDsl::TestCase + + describe 'open configured editor' do + temporary_change_hash ENV, 'EDITOR', 'editr' + + it 'must open current file in current line in configured editor' do + Byebug::Edit.any_instance.expects(:system). + with("editr +2 #{fullpath('edit')}") + enter 'edit' + debug_file 'edit' + end + end + + describe 'open default editor' do + temporary_change_hash ENV, 'EDITOR', nil + + it 'must call "vim" with current line and file if EDITOR env not set' do + Byebug::Edit.any_instance.expects(:system). + with("vim +2 #{fullpath('edit')}") + enter 'edit' + debug_file 'edit' + end + end + + describe 'open configured editor specifying line and file' do + temporary_change_hash ENV, 'EDITOR', 'editr' + + it 'must open specified line in specified file with configured editor' do + Byebug::Edit.any_instance.expects(:system). + with("editr +3 #{fullpath('breakpoint')}") + enter "edit #{fullpath('breakpoint')}:3" + debug_file 'edit' + end + end + + it 'must show an error if there is no such line' do + enter "edit #{fullpath('edit3')}:6" + debug_file 'edit' + check_error_includes "File \"#{fullpath('edit3')}\" is not readable." + end + + it 'must show an error if there is incorrect syntax' do + enter 'edit blabla' + debug_file 'edit' + check_error_includes 'Invalid file[:line] number specification: blabla' + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/eval_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/eval_test.rb new file mode 100644 index 0000000..308d89c --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/eval_test.rb @@ -0,0 +1,103 @@ +class EvalTest + def sum(a,b) + a + b + end + + def inspect + raise "Broken" + end +end + +class TestEval < TestDsl::TestCase + it 'must evaluate an expression' do + enter 'eval 3 + 2' + debug_file 'eval' + check_output_includes '5' + end + + it 'must work with shortcut' do + enter 'e 3 + 2' + debug_file 'eval' + check_output_includes '5' + end + + it 'must work with another syntax' do + enter 'p 3 + 2' + debug_file 'eval' + check_output_includes '5' + end + + it 'must work when inspect raises an exception' do + enter 'c 4', 'p @foo' + debug_file('eval') { state.line.must_equal 4 } + check_output_includes 'RuntimeError Exception: Broken' + end + + describe 'autoeval' do + it 'must be set by default' do + enter '[5,6,7].inject(&:+)' + debug_file 'eval' + check_output_includes '18' + end + + it 'can be turned off and back on' do + enter 'set noautoeval', '[5,6,7].inject(&:+)', + 'set autoeval', '[1,2,3].inject(&:+)' + debug_file 'eval' + check_output_doesnt_include '18' + check_output_includes '6' + end + end + + describe 'stack trace on error' do + describe 'when enabled' do + temporary_change_hash Byebug.settings, :stack_on_error, true + + it 'must show a stack trace' do + enter 'eval 2 / 0' + debug_file 'eval' + check_output_includes(/\s*from \S+:in \`eval\'/) + check_output_doesnt_include 'ZeroDivisionError Exception: divided by 0' + end + end + + describe 'when disabled' do + temporary_change_hash Byebug.settings, :stack_on_error, false + + it 'must only show exception' do + enter 'eval 2 / 0' + debug_file 'eval' + check_output_includes 'ZeroDivisionError Exception: divided by 0' + check_output_doesnt_include(/\S+:\d+:in `eval':divided by 0/) + end + end + end + + describe 'pp' do + it 'must pretty print the expression result' do + enter 'pp {a: \'3\' * 40, b: \'4\' * 30}' + debug_file 'eval' + check_output_includes "{:a=>\"#{'3' * 40}\",\n :b=>\"#{'4' * 30}\"}" + end + end + + describe 'putl' do + temporary_change_hash Byebug.settings, :width, 20 + + it 'must print expression and columnize the result' do + enter 'putl [1, 2, 3, 4, 5, 9, 8, 7, 6]' + debug_file 'eval' + check_output_includes "1 3 5 8 6\n2 4 9 7" + end + end + + describe 'ps' do + temporary_change_hash Byebug.settings, :width, 20 + + it 'must print expression and sort and columnize the result' do + enter 'ps [1, 2, 3, 4, 5, 9, 8, 7, 6]' + debug_file 'eval' + check_output_includes "1 3 5 7 9\n2 4 6 8" + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint.rb new file mode 100644 index 0000000..b1a51a7 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint.rb @@ -0,0 +1,6 @@ +y = 3 +# A comment +byebug +z = 5 +BreakpointExample.new.b +BreakpointExample.a(y+z) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint_deep.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint_deep.rb new file mode 100644 index 0000000..bf61656 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint_deep.rb @@ -0,0 +1,4 @@ +ex = BreakpointDeepExample.new.a +2.times do + ex += 1 +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/conditions.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/conditions.rb new file mode 100644 index 0000000..86b4675 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/conditions.rb @@ -0,0 +1,4 @@ +byebug +b = 5 +c = b + 5 +c = Object.new diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/continue.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/continue.rb new file mode 100644 index 0000000..6b8ac75 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/continue.rb @@ -0,0 +1,5 @@ +byebug + +b = 5 +c = b + 5 +ContinueExample.a(c) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/display.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/display.rb new file mode 100644 index 0000000..2789133 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/display.rb @@ -0,0 +1,5 @@ +byebug +d = 4 +d = d + 2 +d = d + 3 +d = d + 6 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/edit.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/edit.rb new file mode 100644 index 0000000..9ff7d40 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/edit.rb @@ -0,0 +1,4 @@ +byebug +d = 1 +b = 2 +DummyObject.new(b, d) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/eval.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/eval.rb new file mode 100644 index 0000000..026eb63 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/eval.rb @@ -0,0 +1,4 @@ +byebug + +@foo = EvalTest.new +@foo.sum(1, 2) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/finish.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/finish.rb new file mode 100644 index 0000000..f24b1de --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/finish.rb @@ -0,0 +1,3 @@ +byebug + +FinishExample.new.a diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/frame.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/frame.rb new file mode 100644 index 0000000..58a680d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/frame.rb @@ -0,0 +1,4 @@ +byebug + +fr_ex = FrameExample.new('f') +fr_ex.a() diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/frame_deep.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/frame_deep.rb new file mode 100644 index 0000000..d3c2578 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/frame_deep.rb @@ -0,0 +1 @@ +FrameDeepExample.new.a diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/gcd.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/gcd.rb new file mode 100644 index 0000000..c74e02d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/gcd.rb @@ -0,0 +1,15 @@ +# Greatest common divisor of a and b +def gcd a, b + x = [a,b].max + y = [a,b].min + + while y != 0 + r = x % y + x = y + y = r + end + + x +end + +puts gcd ARGV[0].to_i, ARGV[1].to_i diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/hanoi.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/hanoi.rb new file mode 100644 index 0000000..d8313d8 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/hanoi.rb @@ -0,0 +1,34 @@ +# Solves the classic Towers of Hanoi puzzle. +def hanoi(n,a,b,c) + if n-1 > 0 + hanoi(n-1, a, c, b) + end + puts "Move disk %s to %s" % [a, b] + if n-1 > 0 + hanoi(n-1, c, b, a) + end +end + +i_args=ARGV.length +if i_args > 1 + puts "*** Need number of disks or no parameter" + exit 1 +end + +n=3 + +if i_args > 0 + begin + n = ARGV[0].to_i + rescue ValueError, :msg + print "** Expecting an integer, got: %s" % ARGV[0].to_s + exit 2 + end +end + +if n < 1 or n > 100 + puts "*** number of disks should be between 1 and 100" + exit 2 +end + +hanoi(n, :a, :b, :c) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/help.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/help.rb new file mode 100644 index 0000000..782b510 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/help.rb @@ -0,0 +1 @@ +byebug diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/info.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/info.rb new file mode 100644 index 0000000..76d3562 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/info.rb @@ -0,0 +1,6 @@ +byebug + +i = InfoExample.new +i.b +i.c +i.d diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/info2.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/info2.rb new file mode 100644 index 0000000..01e79c3 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/info2.rb @@ -0,0 +1,3 @@ +1 +2 +3 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/interrupt.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/interrupt.rb new file mode 100644 index 0000000..4f7a39c --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/interrupt.rb @@ -0,0 +1,8 @@ +byebug + +ex = InterruptExample.a(7) +2.times do + ex += 1 +end + +InterruptExample.b(ex) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/kill.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/kill.rb new file mode 100644 index 0000000..46e787b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/kill.rb @@ -0,0 +1,2 @@ +byebug +KillExample.kill_me diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/list.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/list.rb new file mode 100644 index 0000000..1b37e53 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/list.rb @@ -0,0 +1,23 @@ +byebug +a = 2 +a = 3 +a = 4 +a = 5 +a = 6 +a = 7 +a = 8 +a = 9 +a = 10 +a = 11 +a = 12 +a = 13 +a = 14 +a = 15 +a = 16 +a = 17 +a = 18 +a = 19 +a = 20 +a = 21 +a = 22 +a = '%23' diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/method.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/method.rb new file mode 100644 index 0000000..f0b8e6d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/method.rb @@ -0,0 +1,4 @@ +byebug + +a = MethodExample.new +a.bla diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/post_mortem.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/post_mortem.rb new file mode 100644 index 0000000..72365f0 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/post_mortem.rb @@ -0,0 +1,4 @@ +byebug + +c = PostMortemExample.new +c.a diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/primes.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/primes.rb new file mode 100644 index 0000000..15e8440 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/primes.rb @@ -0,0 +1,25 @@ +# Enumerator for primes +class SievePrime + @@odd_primes = [] + def self.next_prime(&block) + candidate = 2 + yield candidate + not_prime = false + candidate += 1 + while true do + @@odd_primes.each do |p| + not_prime = (0 == (candidate % p)) + break if not_prime + end + unless not_prime + @@odd_primes << candidate + yield candidate + end + candidate += 2 + end + end +end +SievePrime.next_prime do |prime| + puts prime + break if prime > 10 +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/quit.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/quit.rb new file mode 100644 index 0000000..7f0d0d8 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/quit.rb @@ -0,0 +1,2 @@ +byebug +DummyObject.new diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/reload.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/reload.rb new file mode 100644 index 0000000..6630c5b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/reload.rb @@ -0,0 +1,6 @@ +byebug +a = 2 +a = 3 +a = 4 +a = 5 +a = 6 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/repl.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/repl.rb new file mode 100644 index 0000000..6630c5b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/repl.rb @@ -0,0 +1,6 @@ +byebug +a = 2 +a = 3 +a = 4 +a = 5 +a = 6 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/restart.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/restart.rb new file mode 100644 index 0000000..dbf892c --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/restart.rb @@ -0,0 +1,6 @@ +byebug + +a = ARGV[0] +b = ARGV[1] +c = ARGV[2] +RestartExample.new.concat_args(a, b, c) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/save.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/save.rb new file mode 100644 index 0000000..da98d84 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/save.rb @@ -0,0 +1,3 @@ +byebug +a = 2 +a = 3 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/set.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/set.rb new file mode 100644 index 0000000..da98d84 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/set.rb @@ -0,0 +1,3 @@ +byebug +a = 2 +a = 3 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/settings.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/settings.rb new file mode 100644 index 0000000..782b510 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/settings.rb @@ -0,0 +1 @@ +byebug diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/show.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/show.rb new file mode 100644 index 0000000..782b510 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/show.rb @@ -0,0 +1 @@ +byebug diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/source.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/source.rb new file mode 100644 index 0000000..da98d84 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/source.rb @@ -0,0 +1,3 @@ +byebug +a = 2 +a = 3 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping.rb new file mode 100644 index 0000000..c1b1097 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping.rb @@ -0,0 +1,8 @@ +byebug + +ex = SteppingExample.a(7) +2.times do + ex += 1 +end + +SteppingExample.b(ex) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_c_method.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_c_method.rb new file mode 100644 index 0000000..33f7f2b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_c_method.rb @@ -0,0 +1,3 @@ +byebug + +SteppingRaiseFromCMethodExample.new.a diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_ruby_method.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_ruby_method.rb new file mode 100644 index 0000000..f725938 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_ruby_method.rb @@ -0,0 +1,3 @@ +byebug + +SteppingRaiseFromRubyMethodExample.new.a diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/test-triangle.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/test-triangle.rb new file mode 100644 index 0000000..620b499 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/test-triangle.rb @@ -0,0 +1,14 @@ +require 'minitest/autorun' +require_relative 'triangle.rb' + +class TestTri < MiniTest::Unit::TestCase + def test_basic + byebug + solutions = [] + 0.upto(5) do |i| + solutions << triangle(i) + end + assert_equal([0, 1, 3, 6, 10, 15], solutions, + "Testing the first 5 triangle numbers") + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/thread.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/thread.rb new file mode 100644 index 0000000..4bc233e --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/thread.rb @@ -0,0 +1,5 @@ +byebug + +t = ThreadExample.new +t.launch +t.kill diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/tmate.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/tmate.rb new file mode 100644 index 0000000..54926a4 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/tmate.rb @@ -0,0 +1,10 @@ +byebug +class TmateExample + def a + b + end + def b + 3 + end +end +TmateExample.new.a diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/trace.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/trace.rb new file mode 100644 index 0000000..839945d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/trace.rb @@ -0,0 +1,8 @@ +$bla = 2 +byebug +$bla = 3 +$bla = 4 +$bla = 5 +$bla = 6 +$bla = 7 +$bla = (0 == (7 % $bla)) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/tri3.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/tri3.rb new file mode 100644 index 0000000..5b3481f --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/tri3.rb @@ -0,0 +1,6 @@ +def triangle(n) + (0..n).inject do |sum, i| + sum +=i + end +end +puts triangle(3) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/triangle.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/triangle.rb new file mode 100644 index 0000000..2e64933 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/triangle.rb @@ -0,0 +1,13 @@ +# Compute the n'th triangle number, the hard way: triangle(n) == (n*(n+1))/2 +def triangle(n) + tri = 0 + 0.upto(n) do |i| + tri += i + end + tri +end + +if __FILE__ == $0 + t = triangle(3) + puts t +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/variables.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/variables.rb new file mode 100644 index 0000000..5e13f7b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/variables.rb @@ -0,0 +1,4 @@ +byebug + +v = VariablesExample.new +v.run diff --git a/vendor/bundle/gems/byebug-2.7.0/test/finish_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/finish_test.rb new file mode 100644 index 0000000..b598362 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/finish_test.rb @@ -0,0 +1,53 @@ +class FinishExample + def a + b + end + def b + c + 2 + end + def c + d + 3 + end + def d + 5 + end +end + +class TestFinish < TestDsl::TestCase + before { enter "break #{__FILE__}:14", 'cont' } + + it 'must stop at the next frame by default' do + enter 'finish' + debug_file('finish') { state.line.must_equal 11 } + end + + it 'must stop at the #0 frame by default' do + enter 'finish 0' + debug_file('finish') { state.line.must_equal 11 } + end + + it 'must stop at the specified frame' do + enter 'finish 1' + debug_file('finish') { state.line.must_equal 7 } + end + + it 'must stop at the next frame if the current frame was changed' do + enter 'up', 'finish' + debug_file('finish') { state.line.must_equal 7 } + end + + describe 'not a number is specified for frame' do + before { enter 'finish foo' } + + it 'must show an error' do + debug_file('finish') + check_output_includes '"finish" argument "foo" needs to be a number.' + end + + it 'must be on the same line' do + debug_file('finish') { state.line.must_equal 14 } + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/frame_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/frame_test.rb new file mode 100644 index 0000000..fb89f8b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/frame_test.rb @@ -0,0 +1,228 @@ +class FrameExample + def initialize(f) + @f = f + end + + def a + b + end + + def b + c + 2 + end + + def c + d('a') + 3 + end + + def d(e) + 5 + end +end + +class FrameDeepExample + def a + z = 1 + z += b + end + def b + z = 2 + z += c + end + def c + z = 3 + byebug + z += d('a') + end + def d(e) + 4 + end +end + +class TestFrame < TestDsl::TestCase + describe 'when byebug started at the beginning' do + before do + @tst_file = fullpath('frame') + enter "break #{__FILE__}:21", 'cont' + end + + it 'must go up' do + enter 'up' + debug_file('frame') { state.line.must_equal 16 } + end + + it 'must go up by specific number of frames' do + enter 'up 2' + debug_file('frame') { state.line.must_equal 11 } + end + + it 'must go down' do + enter 'up', 'down' + debug_file('frame') { state.line.must_equal 21 } + end + + it 'must go down by specific number of frames' do + enter 'up 3', 'down 2' + debug_file('frame') { state.line.must_equal 16 } + end + + it 'must set frame' do + enter 'frame 2' + debug_file('frame') { state.line.must_equal 11 } + end + + it 'must print current stack frame when without arguments' do + enter 'up', 'frame' + debug_file('frame') + check_output_includes(/#1 FrameExample\.c\s+at #{__FILE__}:16/) + end + + it 'must set frame to the first one' do + enter 'up', 'frame 0' + debug_file('frame') { state.line.must_equal 21 } + end + + it 'must set frame to the last one' do + enter 'frame -1' + debug_file('frame') { File.basename(state.file).must_equal 'test_helper.rb' } + end + + it 'must not set frame if the frame number is too low' do + enter 'down' + debug_file('frame') { state.line.must_equal 21 } + check_output_includes \ + "Can't navigate beyond the newest frame", interface.error_queue + end + + it 'must not set frame if the frame number is too high' do + enter 'up 100' + debug_file('frame') { state.line.must_equal 21 } + check_output_includes \ + "Can't navigate beyond the oldest frame", interface.error_queue + end + + describe 'fullpath' do + describe 'when set' do + temporary_change_hash Byebug.settings, :fullpath, true + + it 'must display current backtrace with fullpaths' do + enter 'where' + debug_file 'frame' + check_output_includes( + /--> #0 FrameExample\.d\(e#String\)\s+at #{__FILE__}:21/, + /#1 FrameExample\.c\s+at #{__FILE__}:16/, + /#2 FrameExample\.b\s+at #{__FILE__}:11/) + end + end + + describe 'when unset' do + temporary_change_hash Byebug.settings, :fullpath, false + + it 'must display current backtrace with shortpaths' do + enter 'where' + debug_file 'frame' + check_output_includes( + /--> #0 FrameExample\.d\(e#String\)\s+at #{shortpath(__FILE__)}:21/, + /#1 FrameExample\.c\s+at #{shortpath(__FILE__)}:16/, + /#2 FrameExample\.b\s+at #{shortpath(__FILE__)}:11/, + /#3 FrameExample\.a\s+at #{shortpath(__FILE__)}:7/) + end + end + end + + describe 'callstyle' do + describe 'long' do + temporary_change_hash Byebug.settings, :callstyle, :long + + it 'displays current backtrace with callstyle "long"' do + enter 'where' + debug_file 'frame' + check_output_includes( + /--> #0 FrameExample\.d\(e#String\)\s+at #{__FILE__}:21/, + /#1 FrameExample\.c\s+at #{__FILE__}:16/, + /#2 FrameExample\.b\s+at #{__FILE__}:11/, + /#3 FrameExample\.a\s+at #{__FILE__}:7/) + end + end + + describe 'short' do + temporary_change_hash Byebug.settings, :callstyle, :short + + it 'displays current backtrace with callstyle "short"' do + enter 'where' + debug_file 'frame' + check_output_includes(/--> #0 d\(e\)\s+at #{__FILE__}:21/, + /#1 c\s+at #{__FILE__}:16/, + /#2 b\s+at #{__FILE__}:11/, + /#3 a\s+at #{__FILE__}:7/) + end + end + end + end + + describe 'when byebug is started deep in the callstack' do + before { enter "break #{__FILE__}:40", 'cont' } + + it 'must print backtrace' do + enter 'where' + debug_file 'frame_deep' + check_output_includes( + /--> #0 FrameDeepExample\.d\(e#String\)\s+at #{__FILE__}:40/, + /#1 FrameDeepExample\.c\s+at #{__FILE__}:37/, + /#2 FrameDeepExample\.b\s+at #{__FILE__}:32/) + end + + it 'must go up' do + enter 'up' + debug_file('frame_deep') { state.line.must_equal 37 } + end + + it 'must go down' do + enter 'up', 'down' + debug_file('frame_deep') { state.line.must_equal 40 } + end + + it 'must set frame' do + enter 'frame 2' + debug_file('frame_deep') { state.line.must_equal 32 } + end + + it 'must eval properly when scaling the stack' do + enter 'p z', 'up', 'p z', 'up', 'p z' + debug_file('frame_deep') + check_output_includes 'nil', '3', '2' + end + end + + describe 'c-frames' do + it 'must mark c-frames when printing the stack' do + enter "break #{__FILE__}:3", 'cont', 'where' + enter 'where' + debug_file 'frame' + check_output_includes( + /--> #0 FrameExample.initialize\(f#String\)\s+at #{__FILE__}:3/, + /ͱ-- #1 Class.new\(\*args\)\s+at #{fullpath('frame')}:3/, + /#2 \s+at #{fullpath('frame')}:3/) + end + + it '"up" skips c-frames' do + enter "break #{__FILE__}:7", 'cont', 'up', 'eval fr_ex.class.to_s' + debug_file 'frame' + check_output_includes '"FrameExample"' + end + + it '"down" skips c-frames' do + enter "break #{__FILE__}:7", 'cont', 'up', 'down', 'eval @f' + debug_file 'frame' + check_output_includes '"f"' + end + + it 'must not jump straigh to c-frames' do + enter "break #{__FILE__}:3", 'cont', 'frame 1' + debug_file 'frame' + check_output_includes "Can't navigate to c-frame", interface.error_queue + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/help_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/help_test.rb new file mode 100644 index 0000000..ee95eec --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/help_test.rb @@ -0,0 +1,50 @@ +class TestHelp < TestDsl::TestCase + include Columnize + + let(:available_commands) { + Byebug::Command.commands.map(&:names).flatten.uniq.sort } + + describe 'when typed alone' do + temporary_change_hash Byebug.settings, :width, 50 + + it 'must show self help when typed alone' do + enter 'help' + debug_file 'help' + check_output_includes \ + 'Type "help " for help on a specific command', + 'Available commands:', columnize(available_commands, 50) + end + + it 'must work when shortcut used' do + enter 'h' + debug_file 'help' + check_output_includes \ + 'Type "help " for help on a specific command' + end + end + + describe 'when typed with a command' do + it 'must show an error if an undefined command is specified' do + enter 'help foobar' + debug_file 'help' + check_error_includes 'Undefined command: "foobar". Try "help".' + end + + it "must show a command's help" do + enter 'help break' + debug_file 'help' + check_output_includes \ + "b[reak] file:line [if expr]\n" \ + "b[reak] class(.|#)method [if expr]\n\n" \ + "Set breakpoint to some position, (optionally) if expr == true\n" + end + end + + describe 'when typed with command and subcommand' do + it "must show subcommand's help" do + enter 'help info breakpoints' + debug_file 'help' + check_output_includes "Status of user-settable breakpoints.\n" + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/info_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/info_test.rb new file mode 100644 index 0000000..eb59e98 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/info_test.rb @@ -0,0 +1,308 @@ +class InfoExample + def initialize + @foo = "bar" + @bla = "blabla" + end + + def a(y, z) + w = "1" * 30 + x = 2 + w + x.to_s + y + z + @foo + end + + def c + a = BasicObject.new + a + end + + def b + a('a', 'b') + e = "%.2f" + e + end + + def d + raise "bang" + rescue + end + +end + +class TestInfo < TestDsl::TestCase + include Columnize + + describe 'Args info' do + it 'must show info about all args' do + enter "break #{__FILE__}:10", 'cont', 'info args' + debug_file 'info' + check_output_includes 'y = "a"', 'z = "b"' + end + end + + describe 'Breakpoints info' do + it 'must show info about all breakpoints' do + enter 'break 4', 'break 5 if y == z', 'info breakpoints' + debug_file 'info' + check_output_includes 'Num Enb What', + /\d+ +y at #{fullpath('info')}:4/, + /\d+ +y at #{fullpath('info')}:5 if y == z/ + end + + it 'must show info about specific breakpoint' do + enter 'break 4', 'break 5', + ->{ "info breakpoints #{Byebug.breakpoints.first.id}" } + debug_file 'info' + check_output_includes 'Num Enb What', /\d+ +y at #{fullpath('info')}:4/ + check_output_doesnt_include(/\d+ +y at #{fullpath('info')}:5/) + end + + it 'must show an error if no breakpoints are found' do + enter 'info breakpoints' + debug_file 'info' + check_output_includes 'No breakpoints.' + end + + it 'must show an error if no breakpoints are found' do + enter 'break 4', 'info breakpoints 123' + debug_file 'info' + check_error_includes 'No breakpoints found among list given.' + end + + it 'must show hit count' do + enter 'break 5', 'cont', 'info breakpoints' + debug_file 'info' + check_output_includes( + /\d+ +y at #{fullpath('info')}:5/, 'breakpoint already hit 1 time') + end + end + + describe 'Display info' do + it 'must show all display expressions' do + enter 'display 3 + 3', 'display a + b', 'info display' + debug_file 'info' + check_output_includes "Auto-display expressions now in effect:\n" \ + 'Num Enb Expression', + '1: y 3 + 3', + '2: y a + b' + end + + it 'must show a message if there are no display expressions created' do + enter 'info display' + debug_file 'info' + check_output_includes 'There are no auto-display expressions now.' + end + end + + describe 'Files info' do + let(:files) { SCRIPT_LINES__.keys.uniq.sort } + + it 'must show all files read in' do + enter 'info files' + debug_file 'info' + check_output_includes files.map { |f| "File #{f}" } + end + + it 'must show all files read in using "info file" too' do + enter 'info file' + debug_file 'info' + check_output_includes files.map { |f| "File #{f}" } + end + + it 'must show explicitly loaded files' do + enter 'info files stat' + debug_file 'info' + check_output_includes "File #{fullpath('info')}", + LineCache.stat(fullpath('info')).mtime.to_s + end + end + + describe 'File info' do + let(:file) { fullpath('info') } + let(:filename) { "File #{file}" } + let(:lines) { "#{LineCache.size(file)} lines" } + let(:mtime) { LineCache.stat(file).mtime.to_s } + let(:sha1) { LineCache.sha1(file) } + let(:breakpoint_line_numbers) { + columnize(LineCache.trace_line_numbers(file).to_a.sort, + Byebug.settings[:width]) } + + it 'must show basic info about the file' do + enter "info file #{file} basic" + debug_file 'info' + check_output_includes filename, lines + check_output_doesnt_include breakpoint_line_numbers, mtime, sha1 + end + + it 'must show number of lines' do + enter "info file #{file} lines" + debug_file 'info' + check_output_includes filename, lines + check_output_doesnt_include breakpoint_line_numbers, mtime, sha1 + end + + it 'must show mtime of the file' do + enter "info file #{file} mtime" + debug_file 'info' + check_output_includes filename, mtime + check_output_doesnt_include lines, breakpoint_line_numbers, sha1 + end + + it 'must show sha1 of the file' do + enter "info file #{file} sha1" + debug_file 'info' + check_output_includes filename, sha1 + check_output_doesnt_include lines, breakpoint_line_numbers, mtime + end + + it 'must show breakpoints in the file' do + enter 'break 4', 'break 5', "info file #{file} breakpoints" + debug_file 'info' + check_output_includes(/Created breakpoint \d+ at #{file}:4/, + /Created breakpoint \d+ at #{file}:5/, + filename, + 'breakpoint line numbers:', breakpoint_line_numbers) + check_output_doesnt_include lines, mtime, sha1 + end + + it 'must show all info about the file' do + enter "info file #{file} all" + debug_file 'info' + check_output_includes \ + filename, lines, breakpoint_line_numbers, mtime, sha1 + end + + it 'must not show any info if the parameter is invalid' do + enter "info file #{file} blabla" + debug_file 'info' + check_error_includes 'Invalid parameter blabla' + end + end + + describe 'Instance variables info' do + it 'must show instance variables' do + enter "break #{__FILE__}:10", 'cont', 'info instance_variables' + debug_file 'info' + check_output_includes '@bla = "blabla"', '@foo = "bar"' + end + end + + describe 'Line info' do + it 'must show the current line' do + enter "break #{__FILE__}:10", 'cont', 'info line' + debug_file 'info' + check_output_includes "Line 10 of \"#{__FILE__}\"" + end + end + + describe 'Locals info' do + temporary_change_hash Byebug.settings, :width, 28 + + it 'must show the current local variables' do + enter "break #{__FILE__}:10", 'cont', 'info locals' + debug_file 'info' + check_output_includes 'w = "11111111111111111111...', 'x = 2' + end + + it 'must fail if local variable doesn\'t respond to #to_s or to #inspect' do + enter "break #{__FILE__}:15", 'cont', 'info locals' + debug_file 'info' + check_output_includes 'a = *Error in evaluation*' + end + end + + describe 'Program info' do + it 'must show the initial stop reason' do + enter 'info program' + debug_file 'info' + check_output_includes \ + 'It stopped after stepping, next\'ing or initial start.' + end + + it 'must show the step stop reason' do + enter 'step', 'info program' + debug_file 'info' + check_output_includes \ + 'Program stopped.', + 'It stopped after stepping, next\'ing or initial start.' + end + + it 'must show the breakpoint stop reason' do + enter 'break 4', 'cont', 'info program' + debug_file 'info' + check_output_includes 'Program stopped.', 'It stopped at a breakpoint.' + end + + it 'must show the catchpoint stop reason' do + enter 'catch Exception', 'cont', 'info program' + debug_file 'info' + check_output_includes 'Program stopped.', 'It stopped at a catchpoint.' + end + + it 'must show the unknown stop reason' do + enter 'break 5', 'cont', + ->{ context.stubs(:stop_reason).returns('blabla'); 'info program' } + debug_file 'info' + check_output_includes 'Program stopped.', 'unknown reason: blabla' + end + + it 'must show an error if the program is crashed' do + skip('TODO') + end + end + + describe 'Stack info' do + it 'must show stack info' do + enter 'set fullpath', "break #{__FILE__}:8", 'cont', 'info stack' + debug_file 'info' + check_output_includes( + /--> #0 InfoExample.a\(y\#String, z\#String\)\s+at #{__FILE__}:8/, + /#1 InfoExample.b\s+at #{__FILE__}:19/, + /#2 \s+at #{fullpath('info')}:4/) + end + end + + describe 'Global Variables info' do + it 'must show global variables' do + enter 'info global_variables' + debug_file 'info' + check_output_includes "$$ = #{Process.pid}" + end + end + + describe 'Variables info' do + temporary_change_hash Byebug.settings, :width, 30 + + it 'must show all variables' do + enter "break #{__FILE__}:10", 'cont', 'info variables' + debug_file 'info' + check_output_includes(/self = # 5: a = 5', '6: a = 6', + '7: a = 7', '8: a = 8', '9: a = 9', '10: a = 10' + end + + it 'must list forward after second call' do + enter 'break 5', 'cont', 'list' + debug_file 'list' + check_output_includes "[11, 20] in #{fullpath('list')}", '11: a = 11', + '12: a = 12', '13: a = 13', '14: a = 14', '15: a = 15', '16: a = 16', + '17: a = 17', '18: a = 18', '19: a = 19', '20: a = 20' + end + end + + describe 'list backwards' do + temporary_change_hash Byebug.settings, :autolist, 0 + + it 'must show surrounding lines with the first call' do + enter 'break 15', 'cont', 'list -' + debug_file 'list' + check_output_includes "[10, 19] in #{fullpath('list')}", '10: a = 10', + '11: a = 11', '12: a = 12', '13: a = 13', '14: a = 14', '=> 15: a = 15', + '16: a = 16', '17: a = 17', '18: a = 18', '19: a = 19' + end + + it 'must list backward after second call' do + enter 'break 15', 'cont', 'list -', 'list -' + debug_file 'list' + check_output_includes "[1, 10] in #{fullpath('list')}", '1: byebug', + '2: a = 2', '3: a = 3', '4: a = 4', '5: a = 5', '6: a = 6', '7: a = 7', + '8: a = 8', '9: a = 9', '10: a = 10' + end + end + + describe 'list surrounding' do + temporary_change_hash Byebug.settings, :autolist, 0 + + it 'must show the surrounding lines with =' do + enter 'break 5', 'cont', 'list =' + debug_file 'list' + check_output_includes "[1, 10] in #{fullpath('list')}", '1: byebug', + '2: a = 2', '3: a = 3', '4: a = 4', '=> 5: a = 5', '6: a = 6', + '7: a = 7', '8: a = 8', '9: a = 9', '10: a = 10' + end + end + + describe 'specific range' do + it 'must show with mm-nn' do + enter 'list 4-6' + debug_file 'list' + check_output_includes \ + "[4, 6] in #{fullpath('list')}", '4: a = 4', '5: a = 5', '6: a = 6' + end + + it 'must show with mm,nn' do + enter 'list 4,6' + debug_file 'list' + check_output_includes \ + "[4, 6] in #{fullpath('list')}", '4: a = 4', '5: a = 5', '6: a = 6' + end + + it 'must show nothing if there is no such lines' do + enter 'list 44,44' + debug_file 'list' + check_error_includes 'Invalid line range' + check_output_doesnt_include "[44, 44] in #{fullpath('list')}" + check_output_doesnt_include(/^44 \S/) + end + + it 'must show nothing if range is incorrect' do + enter 'list 5,4' + debug_file 'list' + check_output_includes "[5, 4] in #{fullpath('list')}" + end + end + + describe 'arround specific line' do + it 'must show surroundings with mm-' do + enter 'list 14-' + debug_file 'list' + check_output_includes "[9, 18] in #{fullpath('list')}", '9: a = 9', + '10: a = 10', '11: a = 11', '12: a = 12', '13: a = 13', '14: a = 14', + '15: a = 15', '16: a = 16', '17: a = 17', '18: a = 18' + end + + it 'must show surroundings with mm,' do + enter 'list 14,' + debug_file 'list' + check_output_includes "[9, 18] in #{fullpath('list')}", '9: a = 9', + '10: a = 10', '11: a = 11', '12: a = 12', '13: a = 13', '14: a = 14', + '15: a = 15', '16: a = 16', '17: a = 17', '18: a = 18' + end + end + + describe 'reload source' do + after { change_line_in_file(fullpath('list'), 4, 'a = 4') } + + describe 'when autoreload is false' do + temporary_change_hash Byebug.settings, :autoreload, false + + it 'must not reload listing with file changes' do + enter -> { change_line_in_file fullpath('list'), 4, 'a = 100' ; + 'list 4-4' } + debug_file 'list' + check_output_includes '4: a = 4' + end + end + + describe 'when autoreload is true' do + it 'must reload listing with file changes' do + enter -> { change_line_in_file fullpath('list'), 4, 'a = 100' ; + 'list 4-4' } + debug_file 'list' + check_output_includes '4: a = 100' + end + end + end + + it 'must show an error when there is no such file' do + enter -> { state.file = 'blabla'; 'list 4-4' } + debug_file 'list' + check_error_includes 'No sourcefile available for blabla' + end + + it 'must correctly print lines containing % sign' do + enter 'list 23' + debug_file 'list' + check_output_includes "23: a = '%23'" + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/method_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/method_test.rb new file mode 100644 index 0000000..cfb561d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/method_test.rb @@ -0,0 +1,78 @@ +class MethodExample + def initialize + @a = 'b' + @c = 'd' + end + def self.foo + "asdf" + end + def bla + "asdf" + end +end + +class TestMethod < TestDsl::TestCase + temporary_change_hash Byebug.settings, :autolist, 0 + + describe 'show instance method of a class' do + before { enter 'break 4', 'cont' } + + it 'must show using full command name' do + enter 'method MethodExample' + debug_file 'method' + check_output_includes(/bla/) + check_output_doesnt_include(/foo/) + end + + it 'must show using shortcut' do + enter 'm MethodExample' + debug_file 'method' + check_output_includes(/bla/) + end + + it 'must show an error if specified object is not a class or module' do + enter 'm a' + debug_file 'method' + check_output_includes 'Should be Class/Module: a' + end + end + + describe 'show methods of an object' do + before { enter 'break 4', 'cont' } + + it 'must show using full command name' do + enter 'method instance a' + debug_file 'method' + check_output_includes(/bla/) + check_output_doesnt_include(/foo/) + end + + it 'must show using shortcut' do + enter 'm i a' + debug_file 'method' + check_output_includes(/bla/) + end + end + + describe 'show signature of a method' do + it 'must work' do + skip('TODO, can\'t install ruby-internal gem') + end + end + + describe 'show instance variables of an object' do + before { enter 'break 4', 'cont' } + + it 'must show using full name command' do + enter 'method iv a' + debug_file 'method' + check_output_includes '@a = "b"', '@c = "d"' + end + + it 'must show using shortcut' do + enter 'm iv a' + debug_file 'method' + check_output_includes '@a = "b"', '@c = "d"' + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/post_mortem_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/post_mortem_test.rb new file mode 100644 index 0000000..c6a2aeb --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/post_mortem_test.rb @@ -0,0 +1,253 @@ +class PostMortemExample + def a + z = 4 + raise 'blabla' + x = 6 + x + z + end +end + +class TestPostMortem < TestDsl::TestCase + + describe 'Features' do + before { enter 'set post_mortem', 'cont' } + + it 'must enter into post-mortem mode' do + debug_file('post_mortem', rescue: true) do + Byebug.post_mortem?.must_equal true + end + end + + it 'must stop at the correct line' do + debug_file('post_mortem', rescue: true) { assert_equal 4, state.line } + end + end + + describe 'Unavailable commands' do + temporary_change_hash Byebug.settings, :autoeval, false + + describe 'step' do + it 'must not work in post-mortem mode' do + enter 'set post_mortem', 'cont', 'step' + debug_file 'post_mortem', rescue: true + check_error_includes 'Unknown command: "step". Try "help".' + end + end + + describe 'next' do + it 'must not work in post-mortem mode' do + enter 'set post_mortem', 'cont', 'next' + debug_file 'post_mortem', rescue: true + check_error_includes 'Unknown command: "next". Try "help".' + end + end + + describe 'finish' do + it 'must not work in post-mortem mode' do + enter 'set post_mortem', 'cont', 'finish' + debug_file 'post_mortem', rescue: true + check_error_includes 'Unknown command: "finish". Try "help".' + end + end + + describe 'break' do + it 'must not be able to set breakpoints in post-mortem mode' do + enter 'set post_mortem', 'cont', "break #{__FILE__}:6" + debug_file 'post_mortem', rescue: true + check_error_includes "Unknown command: \"break #{__FILE__}:6\". " \ + 'Try "help".' + end + end + + describe 'condition' do + it 'must not be able to set conditions in post-mortem mode' do + enter "break #{__FILE__}:6", 'set post_mortem', 'cont', + ->{ "cond #{Byebug.breakpoints.last.id} true" } + debug_file 'post_mortem', rescue: true + check_error_includes \ + "Unknown command: \"cond #{Byebug.breakpoints.last.id} true\". " \ + "Try \"help\"." + end + end + + describe 'display' do + it 'must be not able to set display expressions in post-mortem mode' do + enter 'set post_mortem', 'cont', 'display 2 + 2' + debug_file 'post_mortem', rescue: true + check_error_includes 'Unknown command: "display 2 + 2". Try "help".' + end + end + + describe 'reload' do + it 'must work in post-mortem mode' do + enter 'set post_mortem', 'cont', 'reload' + debug_file 'post_mortem', rescue: true + check_error_includes 'Unknown command: "reload". Try "help".' + end + end + + + end + + describe 'Available commands' do + describe 'restart' do + it 'must work in post-mortem mode' do + must_restart + enter 'cont', 'restart' + debug_file 'post_mortem', rescue: true + end + end + + describe 'frame' do + it 'must work in post-mortem mode' do + enter 'cont', 'frame' + debug_file('post_mortem', rescue: true) { state.line.must_equal 4 } + check_output_includes(/--> #0 PostMortemExample\.a\s+at #{__FILE__}:4/) + end + end + + describe 'exit' do + it 'must work in post-mortem mode' do + Byebug::QuitCommand.any_instance.expects(:exit!) + enter 'cont', 'exit!' + debug_file 'post_mortem', rescue: true + end + end + + describe 'edit' do + temporary_change_hash ENV, 'EDITOR', 'editr' + + it 'must work in post-mortem mode' do + Byebug::Edit.any_instance. + expects(:system).with("editr +2 #{fullpath('edit')}") + enter 'cont', "edit #{fullpath('edit')}:2", 'cont' + debug_file 'post_mortem', rescue: true + end + end + + describe 'info' do + it 'must work in post-mortem mode' do + enter 'cont', 'info line' + debug_file 'post_mortem', rescue: true + check_output_includes "Line 4 of \"#{__FILE__}\"" + end + end + + describe 'irb' do + let(:irb) { stub(context: ->{}) } + + it 'must work in post-mortem mode' do + skip "Don't know why this is failing now..." + irb.stubs(:eval_input).throws(:IRB_EXIT, :cont) + enter 'cont', 'break 11', 'irb' + debug_file('post_mortem', rescue: true) { state.line.must_equal 11 } + end + end + + describe 'source' do + let(:filename) { 'source_example.txt' } + + before { File.open(filename, 'w') { |f| f.puts 'frame' } } + + it 'must work in post-mortem mode' do + enter 'cont', "so #{filename}" + debug_file('post_mortem', rescue: true) + check_output_includes(/--> #0 PostMortemExample\.a\s+at #{__FILE__}:4/) + end + end + + describe 'help' do + it 'must work in post-mortem mode' do + enter 'cont', 'help' + debug_file 'post_mortem', rescue: true + check_output_includes 'Available commands:' + end + end + + describe 'var' do + it 'must work in post-mortem mode' do + enter 'cont', 'var local' + debug_file 'post_mortem', rescue: true + check_output_includes 'x => nil', 'z => 4' + end + end + + describe 'list' do + it 'must work in post-mortem mode' do + enter 'cont' + debug_file 'post_mortem', rescue: true + check_output_includes "[1, 10] in #{__FILE__}" + end + end + + describe 'method' do + it 'must work in post-mortem mode' do + enter 'cont', 'm i self' + debug_file 'post_mortem', rescue: true + check_output_includes(/to_s/) + end + end + + describe 'kill' do + it 'must work in post-mortem mode' do + Process.expects(:kill).with('USR1', Process.pid) + enter 'cont', 'kill USR1' + debug_file 'post_mortem', rescue: true + end + end + + describe 'eval' do + it 'must work in post-mortem mode' do + enter 'cont', 'eval 2 + 2' + debug_file 'post_mortem', rescue: true + check_output_includes '4' + end + end + + describe 'set' do + temporary_change_hash Byebug.settings, :autolist, 0 + + it 'must work in post-mortem mode' do + enter 'cont', 'set autolist on' + debug_file 'post_mortem', rescue: true + check_output_includes 'autolist is on.' + end + end + + describe 'save' do + let(:file_name) { 'save_output.txt' } + let(:file_contents) { File.read(file_name) } + after { File.delete(file_name) } + + it 'must work in post-mortem mode' do + enter 'cont', "save #{file_name}" + debug_file 'post_mortem', rescue: true + file_contents.must_include 'set autoirb off' + end + end + + describe 'show' do + it 'must work in post-mortem mode' do + enter 'cont', 'show autolist' + debug_file 'post_mortem', rescue: true + check_output_includes 'autolist is on.' + end + end + + describe 'trace' do + it 'must work in post-mortem mode' do + enter 'cont', 'trace on' + debug_file 'post_mortem', rescue: true + check_output_includes 'line tracing is on.' + end + end + + describe 'thread' do + it "must work in post-mortem mode" do + enter 'cont', 'thread list' + debug_file 'post_mortem', rescue: true + check_output_includes(/\+ \d+ # do + change_line_in_file(fullpath('reload'), 4, 'a = 100') + 'reload' + end, 'l 4-4' + debug_file 'reload' + check_output_includes '4: a = 100' + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/repl_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/repl_test.rb new file mode 100644 index 0000000..313fc39 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/repl_test.rb @@ -0,0 +1,65 @@ +class TestRepl < TestDsl::TestCase + + describe 'Irb Command' do + before do + interface.stubs(:kind_of?).with(Byebug::LocalInterface).returns(true) + IRB::Irb.stubs(:new).returns(irb) + end + + let(:irb) { stub(context: ->{}) } + + it 'must support next command' do + irb.stubs(:eval_input).throws(:IRB_EXIT, :next) + enter 'irb' + debug_file('repl') { state.line.must_equal 3 } + end + + it 'must support step command' do + irb.stubs(:eval_input).throws(:IRB_EXIT, :step) + enter 'irb' + debug_file('repl') { state.line.must_equal 3 } + end + + it 'must support cont command' do + irb.stubs(:eval_input).throws(:IRB_EXIT, :cont) + enter 'break 4', 'irb' + debug_file('repl') { state.line.must_equal 4 } + end + + describe 'autoirb' do + it 'must call irb automatically after breakpoint' do + irb.expects(:eval_input) + enter 'set autoirb', 'break 4', 'cont', 'set noautoirb' + debug_file 'repl' + end + end + end + + @has_pry = false + describe 'Pry command' do + before do + interface.stubs(:kind_of?).with(Byebug::LocalInterface).returns(true) + Byebug::PryCommand.any_instance.expects(:pry) + end + + it 'must support step command' do + skip 'TODO' + end + + it 'must support cont command' do + skip 'TODO' + end + + describe 'autopry' do + it 'must call pry automatically after breakpoint' do + skip 'TODO' + end + end + + describe 'post-mortem' do + it 'must work in post-mortem mode' do + skip 'TODO' + end + end + end if @has_pry +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/restart_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/restart_test.rb new file mode 100644 index 0000000..aa5108a --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/restart_test.rb @@ -0,0 +1,142 @@ +class RestartExample + def concat_args(a, b, c) + a.to_s + b.to_s + c.to_s + end +end + +class TestRestart < TestDsl::TestCase + describe 'usual restarting' do + temporary_change_const Byebug, 'BYEBUG_SCRIPT', 'byebug_script' + + it 'must be restarted with arguments' do + Byebug::RestartCommand.any_instance.expects(:exec). + with("#{Byebug::BYEBUG_SCRIPT} #{Byebug::PROG_SCRIPT} 1 2 3") + enter 'restart 1 2 3' + debug_file 'restart' + end + + describe 'when arguments have spaces' do + temporary_change_hash Byebug.settings, :argv, ['argv1', 'argv 2'] + + it 'must be correctly escaped' do + Byebug::RestartCommand.any_instance.expects(:exec).with \ + "#{Byebug::BYEBUG_SCRIPT} #{Byebug::PROG_SCRIPT} argv1 argv\\ 2" + enter 'restart' + debug_file 'restart' + end + end + + describe 'when arguments specified by set command' do + temporary_change_hash Byebug.settings, :argv, [] + + it 'must specify arguments by "set" command' do + Byebug::RestartCommand.any_instance.expects(:exec). + with("#{Byebug::BYEBUG_SCRIPT} #{Byebug::PROG_SCRIPT} 1 2 3") + enter 'set args 1 2 3', 'restart' + debug_file 'restart' + end + end + end + + describe 'messaging' do + before { enter 'restart' } + + describe 'reexecing' do + temporary_change_const Byebug, 'BYEBUG_SCRIPT', 'byebug_script' + + describe 'with set args' do + temporary_change_hash Byebug.settings, :argv, ['argv'] + + it 'must restart and show a message about reexecing' do + must_restart + debug_file 'restart' + check_output_includes \ + "Re exec'ing:\n" \ + "\t#{Byebug::BYEBUG_SCRIPT} #{Byebug::PROG_SCRIPT} argv" + end + end + end + + describe 'no script specified' do + temporary_change_const Byebug, 'PROG_SCRIPT', :__undefined__ + + describe 'and no $0 used' do + temporary_change_const Byebug, 'DEFAULT_START_SETTINGS', + { init: false, post_mortem: false, tracing: nil } + + it 'must not restart and show error messages instead' do + must_restart.never + debug_file 'restart' + check_output_includes 'Don\'t know name of debugged program', + interface.error_queue + end + end + + describe 'but initialized from $0' do + it 'must use prog_script from $0' do + old_prog_name = $0 + $0 = 'prog-0' + debug_file 'restart' + check_output_includes 'Ruby program prog-0 doesn\'t exist', + interface.error_queue + $0 = old_prog_name + end + end + end + + describe 'no script at the specified path' do + temporary_change_const Byebug, 'PROG_SCRIPT', 'blabla' + + describe 'and no restart params set' do + temporary_change_const Byebug, 'DEFAULT_START_SETTINGS', + init: false, post_mortem: false, tracing: nil + + it 'must not restart' do + must_restart.never + debug_file 'restart' + end + + it 'must show an error message' do + debug_file 'restart' + check_output_includes 'Ruby program blabla doesn\'t exist', + interface.error_queue + end + end + end + + describe 'byebug runner script is not specified' do + before { must_restart } + + it 'must restart anyway' do + debug_file 'restart' + end + + it 'must show a warning message' do + debug_file 'restart' + check_output_includes 'Byebug was not called from the outset...' + end + + it 'must show a warning message when prog script is not executable' do + debug_file 'restart' + check_output_includes "Ruby program #{Byebug::PROG_SCRIPT} not " \ + "executable... We'll add a call to Ruby." + end + end + + describe 'when can\'t change the dir to INITIAL_DIR' do + temporary_change_const Byebug, 'INITIAL_DIR', '/unexistent/path' + + it 'must restart anyway' do + must_restart + debug_file 'restart' + end + + it 'must show an error message ' do + must_restart + debug_file 'restart' + check_output_includes \ + 'Failed to change initial directory /unexistent/path' + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/save_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/save_test.rb new file mode 100644 index 0000000..e10a85d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/save_test.rb @@ -0,0 +1,74 @@ +class TestSave < TestDsl::TestCase + + describe 'successful saving' do + let(:file_name) { 'save_output.txt' } + let(:file_contents) { File.read(file_name) } + before do + enter 'break 2', 'break 3 if true', 'catch NoMethodError', + 'display 2 + 3', 'display 5 + 6', "save #{file_name}" + debug_file 'save' + end + after do + File.delete(file_name) + end + + it 'must save usual breakpoints' do + file_contents.must_include "break #{fullpath('save')}:2" + end + + it 'must save conditinal breakpoints' do + file_contents.must_include "break #{fullpath('save')}:3 if true" + end + + it 'must save catchpoints' do + file_contents.must_include 'catch NoMethodError' + end + + it 'must save displays' do + file_contents.must_include 'display 2 + 3' + end + + describe 'saving settings' do + it 'must save autoeval' do + file_contents.must_include 'set autoeval on' + end + + it 'must save basename' do + file_contents.must_include 'set basename off' + end + + it 'must save testing' do + file_contents.must_include 'set testing on' + end + + it 'must save autolist' do + file_contents.must_include 'set autolist on' + end + + it 'must save autoirb' do + file_contents.must_include 'set autoirb off' + end + end + + it 'must show a message about successful saving' do + check_output_includes "Saved to '#{file_name}'" + end + end + + describe 'without filename' do + let(:file_contents) { File.read(interface.restart_file) } + after { FileUtils.rm(interface.restart_file) } + + it 'must fabricate a filename if not provided' do + enter 'save' + debug_file 'save' + file_contents.must_include 'set autoirb' + end + + it 'must show a message where the file is saved' do + enter 'save' + debug_file 'save' + check_output_includes "Saved to '#{interface.restart_file}'" + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/set_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/set_test.rb new file mode 100644 index 0000000..607bfee --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/set_test.rb @@ -0,0 +1,188 @@ +class TestSet < TestDsl::TestCase + + describe 'setting to on' do + temporary_change_hash Byebug.settings, :autolist, 0 + + it 'must set a setting to on' do + enter 'set autolist on' + debug_file 'set' + Byebug.settings[:autolist].must_equal 1 + end + + it 'must set a setting to on by 1' do + enter 'set autolist 1' + debug_file 'set' + Byebug.settings[:autolist].must_equal 1 + end + + it 'must set a setting to on by default' do + enter 'set autolist' + debug_file 'set' + Byebug.settings[:autolist].must_equal 1 + end + + it 'must set a setting using shortcut' do + enter 'set autol' + debug_file 'set' + Byebug.settings[:autolist].must_equal 1 + end + end + + describe 'setting to off' do + temporary_change_hash Byebug.settings, :autolist, 1 + + it 'must set a setting to off' do + enter 'set autolist off' + debug_file 'set' + Byebug.settings[:autolist].must_equal 0 + end + + it 'must set a setting to off by 0' do + enter 'set autolist 0' + debug_file 'set' + Byebug.settings[:autolist].must_equal 0 + end + + it 'must set a setting to off by "no" prefix' do + enter 'set noautolist' + debug_file 'set' + Byebug.settings[:autolist].must_equal 0 + end + + it 'must set a setting to off by "no" prefix and shortcut' do + enter 'set noautol' + debug_file 'set' + Byebug.settings[:autolist].must_equal 0 + end + end + + describe 'messages' do + temporary_change_hash Byebug.settings, :autolist, 0 + + it 'must show a message after setting' do + enter 'set autolist on' + debug_file 'set' + check_output_includes 'autolist is on.' + end + end + + describe 'testing' do + describe 'state' do + describe 'when setting "testing" to on' do + temporary_change_hash Byebug.settings, :testing, false + + it 'must get set' do + enter 'set testing', 'break 3', 'cont' + debug_file('set') { + state.must_be_kind_of Byebug::CommandProcessor::State } + end + end + + describe 'when setting "testing" to off' do + temporary_change_hash Byebug.settings, :testing, true + + it 'must get unset' do + enter 'set notesting', 'break 3', 'cont' + debug_file('set') { state.must_be_nil } + end + end + end + end + + describe 'history' do + describe 'save' do + it 'must set history save to on' do + enter 'set history save on' + debug_file 'set' + interface.history_save.must_equal true + end + + it 'must set history save to on when no param' do + enter 'set history save' + debug_file 'set' + interface.history_save.must_equal true + end + + it 'must show a message' do + enter 'set history save on' + debug_file 'set' + check_output_includes 'Saving of history save is on.' + end + + it 'must set history save to off' do + enter 'set history save off' + debug_file 'set' + interface.history_save.must_equal false + end + end + + describe 'size' do + it 'must set history size' do + enter 'set history size 250' + debug_file 'set' + interface.history_length.must_equal 250 + end + + it 'must show a message' do + enter 'set history size 250' + debug_file 'set' + check_output_includes 'Byebug history size is 250' + end + + it 'must show an error message if no size provided' do + enter 'set history size' + debug_file 'set' + check_output_includes 'You need to specify the history size' + end + end + + describe 'filename' do + let(:filename) { + File.join(ENV['HOME']||ENV['HOMEPATH']||'.', '.byebug-hist') } + + it 'must set history filename' do + enter 'set history filename .byebug-hist' + debug_file 'set' + interface.histfile.must_equal filename + end + + it 'must show a message' do + enter 'set history filename .byebug-hist' + debug_file 'set' + check_output_includes "The command history file is \"#{filename}\"" + end + + it 'must show an error message if no filenmae provided' do + enter 'set history filename' + debug_file 'set' + check_output_includes 'You need to specify a filename' + end + + end + + it 'must show an error message if used wrong subcommand' do + enter 'set history bla 2' + debug_file 'set' + check_output_includes \ + 'Invalid history parameter bla. Should be "filename", "save" or "size"' + end + end + + describe 'width' do + temporary_change_hash Byebug.settings, :width, 20 + + it 'must get correctly set' do + enter 'set width 10' + debug_file('set') + Byebug.settings[:width].must_equal 10 + end + end + + describe 'Help' do + it 'must show help when typing just "set"' do + enter 'set', 'cont' + debug_file 'set' + check_output_includes(/List of "set" subcommands:/) + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/show_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/show_test.rb new file mode 100644 index 0000000..29652a7 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/show_test.rb @@ -0,0 +1,265 @@ +class TestShow < TestDsl::TestCase + describe 'args' do + temporary_change_hash Byebug.settings, :argv, %w{foo bar} + + describe 'default behaviour' do + it 'must show args' do + enter 'show args' + debug_file 'show' + check_output_includes 'Argument list to give program being debugged ' \ + 'when it is started is "foo bar".' + end + end + + describe 'when BYEBUG_SCRIPT is defined' do + temporary_change_const Byebug, 'BYEBUG_SCRIPT', 'bla' + + it 'must not show the first arg' do + enter 'show args' + debug_file 'show' + check_output_includes 'Argument list to give program being debugged ' \ + 'when it is started is "bar".' + end + end + end + + describe 'autolist' do + it 'must show default value' do + enter 'show autolist' + debug_file 'show' + check_output_includes 'autolist is on.' + end + end + + describe 'autoeval' do + it 'must show default value' do + enter 'show autoeval' + debug_file 'show' + check_output_includes 'autoeval is on.' + end + end + + describe 'autoreload' do + it 'must show default value' do + enter 'show autoreload' + debug_file 'show' + check_output_includes 'autoreload is on.' + end + end + + describe 'autoirb' do + before { Byebug::IRBCommand.any_instance.stubs(:execute) } + + it 'must show default value' do + enter 'show autoirb' + debug_file 'show' + check_output_includes 'autoirb is off.' + end + end + + describe 'basename' do + it 'must show default value' do + enter 'show basename' + debug_file 'show' + check_output_includes 'basename is off.' + end + end + + describe 'callstyle' do + it 'must show default value' do + enter 'show callstyle' + debug_file 'show' + check_output_includes 'Frame call-display style is long.' + end + end + + describe 'forcestep' do + it 'must show default value' do + enter 'show forcestep' + debug_file 'show' + check_output_includes 'force-stepping is off.' + end + end + + describe 'fullpath' do + it 'must show default value' do + enter 'show fullpath' + debug_file 'show' + check_output_includes 'Displaying frame\'s full file names is on.' + end + end + + describe 'linetrace' do + it 'must show default value' do + enter 'show linetrace' + debug_file 'show' + check_output_includes 'line tracing is off.' + end + end + + describe 'linetrace_plus' do + it 'must show default value' do + enter 'show linetrace_plus' + debug_file 'show' + check_output_includes 'line tracing style is different consecutive lines.' + end + end + + describe 'listsize' do + it 'must show listsize' do + enter 'show listsize' + debug_file 'show' + check_output_includes 'Number of source lines to list is 10.' + end + end + + describe 'stack_on_error' do + it 'must show stack_on_error' do + enter 'show stack_on_error' + debug_file 'show' + check_output_includes 'Displaying stack trace is off.' + end + end + + describe 'version' do + it 'must show version' do + enter 'show version' + debug_file 'show' + check_output_includes "Byebug #{Byebug::VERSION}" + end + end + + describe 'width' do + let(:cols) { `stty size`.scan(/\d+/)[1].to_i } + + it 'must show default width' do + enter 'show width' + debug_file 'show' + check_output_includes "width is #{cols}." + end + end + + describe 'unknown command' do + it 'must show a message' do + enter 'show bla' + debug_file 'show' + check_output_includes 'Unknown show command bla' + end + end + + describe 'history' do + describe 'without arguments' do + before do + interface.histfile = 'hist_file.txt' + interface.history_save = true + interface.history_length = 25 + enter 'show history' + debug_file 'show' + end + + it 'must show history file' do + check_output_includes( + /filename: The command history file is "hist_file\.txt"/) + end + + it 'must show history save setting' do + check_output_includes(/save: Saving of history save is on\./) + end + + it 'must show history length' do + check_output_includes(/size: Byebug history size is 25/) + end + end + + describe 'with "filename" argument' do + it 'must show history filename' do + interface.histfile = 'hist_file.txt' + enter 'show history filename' + debug_file 'show' + check_output_includes 'The command history file is "hist_file.txt"' + end + + it 'must show history save setting' do + interface.history_save = true + enter 'show history save' + debug_file 'show' + check_output_includes 'Saving of history save is on.' + end + + it 'must show history length' do + interface.history_length = 30 + enter 'show history size' + debug_file 'show' + check_output_includes 'Byebug history size is 30' + end + end + end + + describe 'commands' do + describe 'no readline support' do + before { interface.readline_support = false } + + it 'must not show records from readline' do + enter 'show commands' + debug_file 'show' + check_output_includes 'No readline support' + end + end + + describe 'readline support' do + before { interface.readline_support = true } + + describe 'show records' do + temporary_change_const Readline, 'HISTORY', %w{aaa bbb ccc ddd eee fff} + + it 'must show records from readline history' do + enter 'show commands' + debug_file 'show' + check_output_includes(/1 aaa/) + check_output_includes(/6 fff/) + end + end + + describe 'max records' do + temporary_change_const Readline, 'HISTORY', %w{aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm nnn} + + it 'must show last 10 records from readline history' do + enter 'show commands' + debug_file 'show' + check_output_doesnt_include(/3 ddd/) + check_output_includes(/4 eee/) + check_output_includes(/13 nnn/) + end + end + + describe 'with specified positions' do + temporary_change_const Readline, 'HISTORY', %w{aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm nnn} + + it 'must show records within boundaries' do + # Really don't know why it substracts 4, and shows starting from position 6 + enter 'show commands 10' + debug_file 'show' + check_output_doesnt_include(/5 fff/) + check_output_includes(/6 ggg/) + check_output_includes(/13 nnn/) + end + + it 'must adjust first line if it is < 0' do + enter 'show commands 3' + debug_file 'show' + check_output_includes(/1 bbb/) + check_output_includes(/8 iii/) + check_output_doesnt_include(/9 jjj/) + end + end + end + end + + describe 'Help' do + it 'must show help when typing just "show"' do + enter 'show', 'cont' + debug_file 'show' + check_output_includes(/List of "show" subcommands:/) + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/source_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/source_test.rb new file mode 100644 index 0000000..0e9b1b4 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/source_test.rb @@ -0,0 +1,39 @@ +class TestSource < TestDsl::TestCase + let(:filename) { 'source_example.txt' } + + before { File.open(filename, 'w') do |f| + f.puts 'break 2' + f.puts 'break 3 if true' + end } + + after { FileUtils.rm(filename) } + + it 'must run commands from file' do + enter "source #{filename}" + debug_file 'source' do + Byebug.breakpoints[0].pos.must_equal 2 + Byebug.breakpoints[1].pos.must_equal 3 + Byebug.breakpoints[1].expr.must_equal 'true' + end + end + + it 'must be able to use shortcut' do + enter "so #{filename}" + debug_file('source') { Byebug.breakpoints[0].pos.must_equal 2 } + end + + it 'must show an error if file is not found' do + enter 'source blabla' + debug_file 'source' + check_error_includes(/File ".*blabla" not found/) + end + + describe 'Help' do + it 'must show help when used without arguments' do + enter 'source' + debug_file 'source' + check_output_includes \ + "source FILE\texecutes a file containing byebug commands" + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/stepping_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/stepping_test.rb new file mode 100644 index 0000000..e42e9bc --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/stepping_test.rb @@ -0,0 +1,184 @@ +class SteppingExample + def self.a(num) + num += 2 + b(num) + end + + def self.b(num) + v2 = 5 if 1 == num ; [1, 2, v2].map { |a| a.to_f } + c(num) + end + + def self.c(num) + num += 4 + num + end +end + +class SteppingRaiseFromRubyMethodExample + def a + b + rescue + 1 + end + + def b + c + end + + def c + raise 'bang' + end +end + +class SteppingRaiseFromCMethodExample + def a + b + rescue NameError + 1 + end + + def b + c + end + + def c + d + end +end + +class TestStepping < TestDsl::TestCase + + describe 'Next Command' do + + describe 'method call behaviour' do + before { enter "break #{__FILE__}:8", 'cont' } + + it 'must leave on the same line by default' do + enter 'next' + debug_file('stepping') { state.line.must_equal 8 } + end + + it 'must go to the next line if forced by "plus" sign' do + enter 'next+' + debug_file('stepping') { state.line.must_equal 9 } + end + + it 'must leave on the same line if forced by "minus" sign' do + enter 'next-' + debug_file('stepping') { state.line.must_equal 8 } + end + + describe 'when forcestep is set' do + temporary_change_hash Byebug.settings, :forcestep, true + + it 'must go to the next line' do + enter 'next' + debug_file('stepping') { state.line.must_equal 9 } + end + + it 'must go to the next line (by shortcut)' do + enter 'n' + debug_file('stepping') { state.line.must_equal 9 } + end + + it 'must go the specified number of lines forward by default' do + enter 'next 2' + debug_file('stepping') { state.line.must_equal 4 } + end + + it 'must inform when not staying in the same frame' do + enter 'next 2' + debug_file('stepping') + check_output_includes \ + 'Next went up a frame because previous frame finished' + end + + + it 'must ignore it if "minus" is specified' do + enter 'next-' + debug_file('stepping') { state.line.must_equal 8 } + end + end + end + + describe 'block behaviour' do + before { enter 'break 4', 'cont' } + + it 'must step over blocks' do + enter 'next' + debug_file('stepping') { state.line.must_equal 8 } + end + end + + describe 'raise/rescue behaviour' do + describe 'from c method' do + before { enter "break #{__FILE__}:36", 'cont' } + + it 'must step over rescue' do + enter 'next' + debug_file('stepping_raise_from_c_method') { state.line.must_equal 38 } + end + end + + describe 'from ruby method' do + before { enter "break #{__FILE__}:20", 'cont' } + + it 'must step over rescue' do + enter 'next' + debug_file('stepping_raise_from_ruby_method') { state.line.must_equal 22 } + end + end + end + end + + describe 'Step Command' do + + describe 'method call behaviour' do + before { enter "break #{__FILE__}:8", 'cont' } + + it 'must leave on the same line if forced by a setting' do + enter 'step' + debug_file('stepping') { state.line.must_equal 8 } + end + + it 'must go to the step line if forced to do that by "plus" sign' do + enter 'step+' + debug_file('stepping') { state.line.must_equal 9 } + end + + it 'must leave on the same line if forced to do that by "minus" sign' do + enter 'step-' + debug_file('stepping') { state.line.must_equal 8 } + end + + describe 'when forcestep is set' do + temporary_change_hash Byebug.settings, :forcestep, true + + it 'must go to the step line if forced by a setting' do + enter 'step' + debug_file('stepping') { state.line.must_equal 9 } + end + + it 'must go to the next line if forced by a setting (by shortcut)' do + enter 's' + debug_file('stepping') { state.line.must_equal 9 } + end + + it 'must go the specified number of lines forward by default' do + enter 'step 2' + debug_file('stepping') { state.line.must_equal 13 } + end + end + end + + describe 'block behaviour' do + before { enter 'break 4', 'cont' } + + it 'must step into blocks' do + enter 'step' + debug_file('stepping') { state.line.must_equal 5 } + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/support/breakpoint.rb b/vendor/bundle/gems/byebug-2.7.0/test/support/breakpoint.rb new file mode 100644 index 0000000..3bf8370 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/support/breakpoint.rb @@ -0,0 +1,13 @@ +module Byebug + + class Breakpoint + + def inspect + values = %w{id pos source expr hit_condition hit_count hit_value enabled?}.map do |field| + "#{field}: #{send(field)}" + end.join(", ") + "#" + end + + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/support/matchers.rb b/vendor/bundle/gems/byebug-2.7.0/test/support/matchers.rb new file mode 100644 index 0000000..64f6494 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/support/matchers.rb @@ -0,0 +1,68 @@ +module MiniTest::Assertions + + # This matcher checks that given collection is included into the original + # collection and in correct order. It accepts both strings and regexps. + # + # Examples: + # assert_includes_in_order(%w{1 2 3 4 5}, %w{1 3 5}) # => pass + # assert_includes_in_order(%w{1 2 3 4 5}, %w{1 5 3}) # => fail + # assert_includes_in_order(w{1 2 3 4 5}, ["1", /\d+/, "5"]) # => pass + # assert_includes_in_order(w{1 2 3 4 5}, ["1", /\[a-z]+/, "5"]) # => fail + # + def assert_includes_in_order(given_collection, original_collection, msg = nil) + msg = message(msg) do + "Expected #{mu_pp(original_collection)} " \ + "to include #{mu_pp(given_collection)} in order" + end + assert includes_in_order_result(original_collection, given_collection), msg + end + + def refute_includes_in_order(given_collection, original_collection, msg = nil) + msg = message(msg) do + "Expected #{mu_pp(original_collection)} " \ + "to not include #{mu_pp(given_collection)} in order" + end + refute includes_in_order_result(original_collection, given_collection), msg + end + + + private + + def includes_in_order_result(original_collection, given_collection) + result = true + given_collection.each do |given_item| + result &&= case given_item + when String + index = original_collection.index(given_item) + if index + original_collection = original_collection[(index + 1)..-1] + true + else + false + end + when Regexp + index = nil + original_collection.each_with_index do |original_item, i| + if original_item =~ given_item + index = i + break + end + end + if index + original_collection = original_collection[(index + 1)..-1] + true + else + false + end + else + false + end + end + result + end +end + +module MiniTest::Expectations + infect_an_assertion :assert_includes_in_order, :must_include_in_order + infect_an_assertion :refute_includes_in_order, :wont_include_in_order +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/support/test_dsl.rb b/vendor/bundle/gems/byebug-2.7.0/test/support/test_dsl.rb new file mode 100644 index 0000000..a4da015 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/support/test_dsl.rb @@ -0,0 +1,189 @@ +module TestDsl + + class TestCase < MiniTest::Spec + include TestDsl + + def setup + Byebug.handler = Byebug::CommandProcessor.new(TestInterface.new) + Byebug.tracing = false + Byebug.breakpoints.clear if Byebug.breakpoints + end + + def self.temporary_change_hash hash, key, value + before do + @old_hashes ||= {} + @old_hashes.merge!({ hash => { key => hash[key] } }) do |k, v1, v2| + v1.merge(v2) + end + hash[key] = value + end + + after do + hash[key] = @old_hashes[hash][key] + end + end + + def self.temporary_change_const klass, const, value + before do + @old_consts ||= {} + old_value = klass.const_defined?(const) ? + klass.const_get(const) : :__undefined__ + @old_consts.merge!({ klass => { const => old_value } }) do |k, v1, v2| + v1.merge(v2) + end + klass.send :remove_const, const if klass.const_defined?(const) + klass.const_set const, value unless value == :__undefined__ + end + + after do + klass.send :remove_const, const if klass.const_defined?(const) + klass.const_set const, @old_consts[klass][const] unless + @old_consts[klass][const] == :__undefined__ + end + end + end + + # + # Expand fullpath of a given example file + # + def fullpath(filename) + (Pathname.new(__FILE__) + "../../examples/#{filename}.rb").cleanpath.to_s + end + + # + # Shorten a fullpath + # + def shortpath(fullpath) + separator = File::ALT_SEPARATOR || File::SEPARATOR + "...#{separator}" + fullpath.split(separator)[-3..-1].join(separator) + end + + # + # Adds commands to the input queue, so they will be later retrieved by + # Processor, i.e., it emulates user's input. + # + # If a command is a Proc object, it will be executed before being retrieved by + # Processor. May be handy when you need build a command depending on the + # current context/state. + # + # Usage: + # enter 'b 12' + # enter 'b 12', 'cont' + # enter ['b 12', 'cont'] + # enter 'b 12', ->{"disable #{breakpoint.id}"}, 'cont' + # + def enter(*messages) + messages = messages.first.is_a?(Array) ? messages.first : messages + interface.input_queue.concat(messages) + end + + # + # Runs byebug with the provided basename for a file. + # + # You also can specify a block, which will be executed when Processor extracts + # all the commands from the input queue. You can use that for making asserts + # on the current test. If you specified the block and it never was executed, + # the test will fail. + # + # Usage: + # debug_file '/path/to/ex1.rb' + # + # enter 'b 4', 'cont' + # debug_file('/path/to/ex2.rb') { state.line.must_equal 4 } + # + def debug_file(filename, options = {}, &block) + is_test_block_called = false + exception = nil + Byebug.stubs(:run_init_script) + if block + interface.test_block = lambda do + is_test_block_called = true + # We need to store exception and reraise it after completing debugging, + # because Byebug will swallow any exceptions, so e.g. our failed + # assertions will be ignored + begin + block.call + rescue Exception => e + exception = e + end + end + end + begin + load fullpath(filename) + rescue Exception => e + if options[:rescue] + interface.test_block.call if interface.test_block + else + raise e + end + end + + flunk "Test block was provided, but not called" if block && !is_test_block_called + raise exception if exception + end + + # + # Checks the output of byebug. + # + # By default it checks output queue of the current interface, but you can + # check again any queue by providing it as a second argument. + # + # Usage: + # enter 'break 4', 'cont' + # debug 'ex1' + # check_output "Breakpoint 1 at #{fullpath('ex1')}:4" + # + def check_output(check_method, *args) + queue = args.last.is_a?(String) || args.last.is_a?(Regexp) ? + interface.output_queue : args.pop + queue_messages = queue.map(&:strip) + messages = Array(args).map { |msg| msg.is_a?(String) ? msg.strip : msg } + queue_messages.send(check_method, messages) + end + + def check_error_includes(*args) + check_output :must_include_in_order, *args, interface.error_queue + end + + def check_output_includes(*args) + check_output :must_include_in_order, *args + end + + def check_output_doesnt_include(*args) + check_output :wont_include_in_order, *args + end + + def interface + Byebug.handler.interface + end + + def state + Thread.current.thread_variable_get('state') + end + + def context + state.context + end + + def force_set_const(klass, const, value) + force_unset_const(klass, const) + klass.const_set(const, value) + end + + def force_unset_const(klass, const) + klass.send(:remove_const, const) if klass.const_defined?(const) + end + + def change_line_in_file(file, line, new_line_content) + old_content = File.read(file) + new_content = old_content.split("\n") + .tap { |c| c[line - 1] = new_line_content } + .join("\n") + "\n" + File.open(file, 'w') { |f| f.write(new_content) } + end + + def must_restart + Byebug::RestartCommand.any_instance.unstub(:exec) + Byebug::RestartCommand.any_instance.expects(:exec) + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/support/test_interface.rb b/vendor/bundle/gems/byebug-2.7.0/test/support/test_interface.rb new file mode 100644 index 0000000..fe04a26 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/support/test_interface.rb @@ -0,0 +1,59 @@ +class TestInterface < Byebug::Interface + attr_reader :input_queue, :output_queue, :error_queue, :confirm_queue + + attr_accessor :command_queue, :histfile, :history_length, :history_save + attr_accessor :readline_support, :restart_file, :test_block + + def initialize + @input_queue = [] + @output_queue = [] + @error_queue = [] + @confirm_queue = [] + @command_queue = [] + @readline_support = false + end + + def errmsg(*args) + @error_queue << format(*args) + end + + def read_command(*args) + if @input_queue.empty? + if test_block + test_block.call + self.test_block = nil + end + else + result = @input_queue.shift + result.is_a?(Proc) ? result.call : result + end + end + + def print(*args) + @output_queue << format(*args) + end + + def confirm(message) + @confirm_queue << message + read_command message + end + + def readline_support? + @readline_support + end + + def finalize + end + + def close + end + + def inspect + [ + "input_queue: #{input_queue.inspect}", + "output_queue: #{output_queue.inspect}", + "error_queue: #{error_queue.inspect}", + "confirm_queue: #{confirm_queue.inspect}" + ].join("\n") + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/test_helper.rb b/vendor/bundle/gems/byebug-2.7.0/test/test_helper.rb new file mode 100644 index 0000000..8919fa1 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/test_helper.rb @@ -0,0 +1,46 @@ +if ENV['CI'] + require 'coveralls' + Coveralls.wear! do + add_filter 'test' + end +end + +require 'minitest' +require 'minitest/spec' +require 'pathname' +require 'mocha/mini_test' +require 'byebug' + +Dir.glob(File.expand_path("../support/*.rb", __FILE__)).each { |f| require f } + +Byebug.settings[:testing] = true + +class DummyObject + def initialize(*args) + end +end + +# Init globals to avoid warnings +$bla = nil +$binding = binding # this is from irb... + +# Load the test files from the command line. +argv = ARGV.select do |argument| + case argument + when /^-/ then + argument + when /\*/ then + Dir.glob('test/*_test.rb').each do |file| + require File.expand_path file + end + false + else + require File.expand_path argument + false + end +end + +ARGV.replace argv + +# Run the tests +Minitest.run diff --git a/vendor/bundle/gems/byebug-2.7.0/test/thread_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/thread_test.rb new file mode 100644 index 0000000..3cd4a00 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/thread_test.rb @@ -0,0 +1,138 @@ +class ThreadExample + def initialize + Thread.main[:should_break] = false + end + + def launch + @t1 = Thread.new do + while true + break if Thread.main[:should_break] + sleep 0.02 + end + end + + @t2 = Thread.new do + while true + sleep 0.02 + end + end + + @t1.join + Thread.main[:should_break] + end + + def kill + @t2.kill + end +end + +class TestThread < TestDsl::TestCase + let(:release) { 'eval Thread.main[:should_break] = true' } + + describe 'list' do + it 'must show current thread by "plus" sign' do + thnum = nil + enter "break #{__FILE__}:7", 'cont', 'thread list', release + debug_file('thread') { thnum = Byebug.contexts.first.thnum } + check_output_includes(/\+ #{thnum} #\t#{__FILE__}:7/) + end + + it 'must work with shortcut' do + thnum = nil + enter "break #{__FILE__}:7", 'cont', 'th list', release + debug_file('thread') { thnum = Byebug.contexts.first.thnum } + check_output_includes(/\+ #{thnum} #\t#{__FILE__}:7/) + end + + it 'must show 3 available threads' do + enter "break #{__FILE__}:20", 'cont', 'thread list', release + debug_file 'thread' + check_output_includes(/(\+)?\d+ #/, + /(\+)?\d+ #/, + /(\+)?\d+ #/) + end + end + + describe 'stop' do + it 'must mark thread as suspended' do + thnum = nil + enter "break #{__FILE__}:20", 'cont', + ->{ "thread stop #{Byebug.contexts.last.thnum}" }, release + debug_file('thread') { thnum = Byebug.contexts.last.thnum } + check_output_includes(/\$ #{thnum} #{ "thread stop #{Byebug.contexts.last.thnum}" }, release + debug_file('thread') + check_output_doesnt_include(/Tracing: #{__FILE__}:15/, + /Tracing: #{__FILE__}:16/) + end + + it 'must show error message if thread number is not specified' do + enter "break #{__FILE__}:7", 'cont', 'thread stop', release + debug_file 'thread' + check_error_includes '"thread stop" needs a thread number' + end + + it 'must show error message when trying to stop current thread' do + enter "break #{__FILE__}:7", 'cont', + ->{"thread stop #{Byebug.contexts.first.thnum}"}, release + debug_file 'thread' + check_error_includes "It's the current thread" + end + end + + describe 'resume' do + it 'must mark remove thread from the suspended state' do + thnum = nil + enter "break #{__FILE__}:20", 'cont', + -> { thnum = Byebug.contexts.last.thnum ; "thread stop #{thnum}" }, + -> { "thread resume #{thnum}" }, release + debug_file('thread') { Byebug.contexts.last.suspended?.must_equal false } + check_output_includes(/\$ #{thnum} #{ "thread resume #{Byebug.contexts.first.thnum}" }, release + debug_file 'thread' + check_error_includes "It's the current thread" + end + + it 'must show error message if it is not stopped' do + enter "break #{__FILE__}:20", 'cont', + ->{ "thread resume #{Byebug.contexts.last.thnum}" }, release + debug_file 'thread' + check_error_includes 'Already running' + end + end + + describe 'switch' do + it 'must switch to another thread' do + enter "break #{__FILE__}:20", 'cont', + ->{ "thread switch #{Byebug.contexts.last.thnum}" }, release + debug_file('thread') { assert_equal state.line, 15 } + end + + it 'must show error message if thread number is not specified' do + enter "break #{__FILE__}:7", 'cont', 'thread switch', release + debug_file 'thread' + check_error_includes '"thread switch" needs a thread number' + end + + it 'must show error message when trying to switch current thread' do + enter "break #{__FILE__}:7", 'cont', + ->{ "thread switch #{Byebug.contexts.first.thnum}" }, release + debug_file 'thread' + check_error_includes "It's the current thread" + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/trace_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/trace_test.rb new file mode 100644 index 0000000..71bbfa4 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/trace_test.rb @@ -0,0 +1,105 @@ +class TestTrace < TestDsl::TestCase + before do + untrace_var(:$bla) if defined?($bla) + end + + describe 'tracing' do + + describe 'enabling' do + it 'must trace execution by setting trace to on' do + enter 'trace on', 'cont 7', 'trace off' + debug_file 'trace' + check_output_includes 'line tracing is on.', + "Tracing: #{fullpath('trace')}:4 $bla = 4", + "Tracing: #{fullpath('trace')}:7 $bla = 7" + end + + it 'must be able to use a shortcut' do + enter 'tr on', 'cont 7', 'trace off' + debug_file 'trace' + check_output_includes 'line tracing is on.', + "Tracing: #{fullpath('trace')}:4 $bla = 4", + "Tracing: #{fullpath('trace')}:7 $bla = 7" + end + + it 'must correctly print lines containing % sign' do + enter 'cont 7', 'trace on', 'next', 'trace off' + debug_file 'trace' + check_output_includes \ + "Tracing: #{fullpath('trace')}:8 $bla = (0 == (7 % $bla))" + end + + describe 'when basename set' do + temporary_change_hash Byebug.settings, :basename, true + + it 'must correctly print file lines' do + enter 'tr on', 'cont 7', 'trace off' + debug_file 'trace' + check_output_includes \ + "Tracing: #{File.basename(fullpath('trace'))}:7 $bla = 7" + end + end + end + + it 'must show an error message if given subcommand is incorrect' do + enter 'trace bla' + debug_file 'trace' + check_error_includes \ + 'expecting "on", "off", "var" or "variable"; got: "bla"' + end + + describe 'disabling' do + it 'must stop tracing by setting trace to off' do + enter 'trace on', 'next', 'trace off' + debug_file 'trace' + check_output_includes "Tracing: #{fullpath('trace')}:4 $bla = 4" + check_output_doesnt_include "Tracing: #{fullpath('trace')}:5 $bla = 5" + end + + it 'must show a message when turned off' do + enter 'trace off' + debug_file 'trace' + check_output_includes 'line tracing is off.' + end + end + end + + describe 'tracing global variables' do + it 'must track global variable' do + enter 'trace variable bla' + debug_file 'trace' + check_output_includes "traced global variable 'bla' has value '3'", + "traced global variable 'bla' has value '7'" + end + + it 'must be able to use a shortcut' do + enter 'trace var bla' + debug_file 'trace' + check_output_includes "traced global variable 'bla' has value '3'" + end + + it 'must track global variable with stop' do + enter 'trace variable bla stop', 'break 7', 'cont' + debug_file('trace') { state.line.must_equal 4 } + end + + it 'must track global variable with nostop' do + enter 'trace variable bla nostop', 'break 7', 'cont' + debug_file('trace') { state.line.must_equal 7 } + end + + describe 'errors' do + it 'must show an error message if there is no such global variable' do + enter 'trace variable foo' + debug_file 'trace' + check_error_includes "'foo' is not a global variable." + end + + it 'must show an error message if subcommand is invalid' do + enter 'trace variable bla foo' + debug_file 'trace' + check_error_includes 'expecting "stop" or "nostop"; got "foo"' + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/variables_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/variables_test.rb new file mode 100644 index 0000000..48841fc --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/variables_test.rb @@ -0,0 +1,127 @@ +class VariablesExample + SOMECONST = 'foo' unless defined?(SOMECONST) + + def initialize + @inst_a = 1 + @inst_b = 2 + @inst_c = "1" * 40 + @inst_d = BasicObject.new + @@class_c = 3 + end + + def run + a = 4 + b = [1, 2, 3].map do |i| + a * i + end + b + end +end + +class TestVariables < TestDsl::TestCase + describe 'class variables' do + before { enter "break #{__FILE__}:17", 'cont' } + + it 'must show variables' do + enter 'var class' + debug_file 'variables' + check_output_includes '@@class_c = 3' + end + + it 'must be able to use shortcut' do + enter 'v cl' + debug_file 'variables' + check_output_includes '@@class_c = 3' + end + end + + describe 'constants' do + it 'must show constants' do + enter 'break 4', 'cont', 'var const VariablesExample' + debug_file 'variables' + check_output_includes 'SOMECONST => "foo"' + end + + it 'must be able to use shortcut' do + enter 'break 4', 'cont', 'v co VariablesExample' + debug_file 'variables' + check_output_includes 'SOMECONST => "foo"' + end + + it 'must show error message if given object is not a class or a module' do + enter 'break 4', 'cont', 'var const v' + debug_file 'variables' + check_output_includes 'Should be Class/Module: v' + end + end + + describe 'globals' do + it 'must show global variables' do + enter 'break 4', 'cont', 'var global' + debug_file 'variables' + check_output_includes '$VERBOSE = true' + end + + it 'must be able to use shortcut' do + enter 'break 4', 'cont', 'v g' + debug_file 'variables' + check_output_includes '$VERBOSE = true' + end + end + + describe 'instance variables' do + it 'must show instance variables of the given object' do + enter 'break 4', 'cont', 'var instance v' + debug_file 'variables' + check_output_includes '@inst_a = 1', '@inst_b = 2' + end + + it 'must show instance variables of self' do + enter "break #{__FILE__}:9", 'cont', 'var instance' + debug_file 'variables' + check_output_includes '@inst_a = 1', '@inst_b = 2' + end + + it 'must show instance variables' do + enter 'break 4', 'cont', 'var instance v' + debug_file 'variables' + check_output_includes '@inst_a = 1', '@inst_b = 2' + end + + it 'must be able to use shortcut' do + enter 'break 4', 'cont', 'v ins v' + debug_file 'variables' + check_output_includes '@inst_a = 1', '@inst_b = 2' + end + + describe 'when width is too small' do + temporary_change_hash Byebug.settings, :width, 20 + + it 'must cut long variable values according it' do + enter 'break 4', 'cont', 'var instance v' + debug_file 'variables' + check_output_includes '@inst_c = "1111111111111111...' + end + end + + it 'must show error if value doesn\'t have #to_s/#inspect methods' do + enter 'break 4', 'cont', 'var instance v' + debug_file 'variables' + check_output_includes '@inst_d = *Error in evaluation*' + end + end + + describe 'local variables' do + it 'must show local variables' do + enter "break #{__FILE__}:15", 'cont', 'var local' + debug_file 'variables' + check_output_includes 'a => 4', 'b => nil', 'i => 1' + end + end + + describe 'test for "var ct" command' do + it 'must work' do + skip('can\'t install ruby-internal gem') + end + end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/README_INDEX.rdoc b/vendor/bundle/gems/coderay-1.1.0/README_INDEX.rdoc new file mode 100644 index 0000000..7332653 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/README_INDEX.rdoc @@ -0,0 +1,123 @@ += CodeRay + +Tired of blue'n'gray? Try the original version of this documentation on +coderay.rubychan.de[http://coderay.rubychan.de/doc/] :-) + +== About + +CodeRay is a Ruby library for syntax highlighting. + +You put your code in, and you get it back colored; Keywords, strings, +floats, comments - all in different colors. And with line numbers. + +*Syntax* *Highlighting*... +* makes code easier to read and maintain +* lets you detect syntax errors faster +* helps you to understand the syntax of a language +* looks nice +* is what everybody wants to have on their website +* solves all your problems and makes the girls run after you + + +== Installation + + % gem install coderay + + +=== Dependencies + +CodeRay needs Ruby 1.8.7+ or 1.9.2+. It also runs on Rubinius and JRuby. + + +== Example Usage + + require 'coderay' + + html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table) + + +== Documentation + +See CodeRay. + + +== Credits + +=== Special Thanks to + +* licenser (Heinz N. Gies) for ending my QBasic career, inventing the Coder + project and the input/output plugin system. + CodeRay would not exist without him. +* bovi (Daniel Bovensiepen) for helping me out on various occasions. + +=== Thanks to + +* Caleb Clausen for writing RubyLexer (see + http://rubyforge.org/projects/rubylexer) and lots of very interesting mail + traffic +* birkenfeld (Georg Brandl) and mitsuhiku (Arnim Ronacher) for PyKleur, now pygments. + You guys rock! +* Jamis Buck for writing Syntax (see http://rubyforge.org/projects/syntax) + I got some useful ideas from it. +* Doug Kearns and everyone else who worked on ruby.vim - it not only helped me + coding CodeRay, but also gave me a wonderful target to reach for the Ruby + scanner. +* everyone who uses CodeBB on http://www.rubyforen.de and http://www.python-forum.de +* iGEL, magichisoka, manveru, WoNáDo and everyone I forgot from rubyforen.de +* Dethix from ruby-mine.de +* zickzackw +* Dookie (who is no longer with us...) and Leonidas from http://www.python-forum.de +* Andreas Schwarz for finding out that CaseIgnoringWordList was not case + ignoring! Such things really make you write tests. +* closure for the first version of the Scheme scanner. +* Stefan Walk for the first version of the JavaScript and PHP scanners. +* Josh Goebel for another version of the JavaScript scanner, a SQL and a Diff scanner. +* Jonathan Younger for pointing out the licence confusion caused by wrong LICENSE file. +* Jeremy Hinegardner for finding the shebang-on-empty-file bug in FileType. +* Charles Oliver Nutter and Yehuda Katz for helping me benchmark CodeRay on JRuby. +* Andreas Neuhaus for pointing out a markup bug in coderay/for_redcloth. +* 0xf30fc7 for the FileType patch concerning Delphi file extensions. +* The folks at redmine.org - thank you for using and fixing CodeRay! +* Keith Pitt for his SQL scanners +* Rob Aldred for the terminal encoder +* Trans for pointing out $DEBUG dependencies +* Flameeyes for finding that Term::ANSIColor was obsolete +* matz and all Ruby gods and gurus +* The inventors of: the computer, the internet, the true color display, HTML & + CSS, VIM, Ruby, pizza, microwaves, guitars, scouting, programming, anime, + manga, coke and green ice tea. + +Where would we be without all those people? + +=== Created using + +* Ruby[http://ruby-lang.org/] +* Chihiro (my Sony VAIO laptop); Henrietta (my old MacBook); + Triella, born Rico (my new MacBook); as well as + Seras and Hikari (my PCs) +* RDE[http://homepage2.nifty.com/sakazuki/rde_e.html], + VIM[http://vim.org] and TextMate[http://macromates.com] +* Subversion[http://subversion.tigris.org/] +* Redmine[http://redmine.org/] +* Firefox[http://www.mozilla.org/products/firefox/], + Firebug[http://getfirebug.com/], Safari[http://www.apple.com/safari/], and + Thunderbird[http://www.mozilla.org/products/thunderbird/] +* RubyGems[http://docs.rubygems.org/] and Rake[http://rake.rubyforge.org/] +* TortoiseSVN[http://tortoisesvn.tigris.org/] using Apache via + XAMPP[http://www.apachefriends.org/en/xampp.html] +* RDoc (though I'm quite unsatisfied with it) +* Microsoft Windows (yes, I confess!) and MacOS X +* GNUWin32, MinGW and some other tools to make the shell under windows a bit + less useless +* Term::ANSIColor[http://term-ansicolor.rubyforge.org/] +* PLEAC[http://pleac.sourceforge.net/] code examples +* Github +* Travis CI (http://travis-ci.org/rubychan/github) + +=== Free + +* As you can see, CodeRay was created under heavy use of *free* software. +* So CodeRay is also *free*. +* If you use CodeRay to create software, think about making this software + *free*, too. +* Thanks :) diff --git a/vendor/bundle/gems/coderay-1.1.0/Rakefile b/vendor/bundle/gems/coderay-1.1.0/Rakefile new file mode 100644 index 0000000..c9b1e8a --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/Rakefile @@ -0,0 +1,37 @@ +require 'bundler/gem_tasks' + +$:.unshift File.dirname(__FILE__) unless $:.include? '.' + +ROOT = '.' +LIB_ROOT = File.join ROOT, 'lib' + +task :default => :test + +if File.directory? 'rake_tasks' + + # load rake tasks from subfolder + for task_file in Dir['rake_tasks/*.rake'].sort + load task_file + end + +else + + # fallback tasks when rake_tasks folder is not present (eg. in the distribution package) + desc 'Run CodeRay tests (basic)' + task :test do + ruby './test/functional/suite.rb' + ruby './test/functional/for_redcloth.rb' + end + + gem 'rdoc' if defined? gem + require 'rdoc/task' + desc 'Generate documentation for CodeRay' + Rake::RDocTask.new :doc do |rd| + rd.title = 'CodeRay Documentation' + rd.main = 'README_INDEX.rdoc' + rd.rdoc_files.add Dir['lib'] + rd.rdoc_files.add rd.main + rd.rdoc_dir = 'doc' + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/bin/coderay b/vendor/bundle/gems/coderay-1.1.0/bin/coderay new file mode 100755 index 0000000..889ae72 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/bin/coderay @@ -0,0 +1,215 @@ +#!/usr/bin/env ruby +require 'coderay' + +$options, args = ARGV.partition { |arg| arg[/^-[hv]$|--\w+/] } +subcommand = args.first if /^\w/ === args.first +subcommand = nil if subcommand && File.exist?(subcommand) +args.delete subcommand + +def option? *options + !($options & options).empty? +end + +def tty? + $stdout.tty? || option?('--tty') +end + +def version + puts <<-USAGE +CodeRay #{CodeRay::VERSION} + USAGE +end + +def help + puts <<-HELP +This is CodeRay #{CodeRay::VERSION}, a syntax highlighting tool for selected languages. + +usage: + coderay [-language] [input] [-format] [output] + +defaults: + language detect from input file name or shebang; fall back to plain text + input STDIN + format detect from output file name or use terminal; fall back to HTML + output STDOUT + +common: + coderay file.rb # highlight file to terminal + coderay file.rb > file.html # highlight file to HTML page + coderay file.rb -div > file.html # highlight file to HTML snippet + +configure output: + coderay file.py output.json # output tokens as JSON + coderay file.py -loc # count lines of code in Python file + +configure input: + coderay -python file # specify the input language + coderay -ruby # take input from STDIN + +more: + coderay stylesheet [style] # print CSS stylesheet + HELP +end + +def commands + puts <<-COMMANDS + general: + highlight code highlighting (default command, optional) + stylesheet print the CSS stylesheet with the given name (aliases: style, css) + + about: + list [of] list all available plugins (or just the scanners|encoders|styles|filetypes) + commands print this list + help show some help + version print CodeRay version + COMMANDS +end + +def print_list_of plugin_host + plugins = plugin_host.all_plugins.map do |plugin| + info = " #{plugin.plugin_id}: #{plugin.title}" + + aliases = (plugin.aliases - [:default]).map { |key| "-#{key}" }.sort_by { |key| key.size } + if plugin.respond_to?(:file_extension) || !aliases.empty? + additional_info = [] + additional_info << aliases.join(', ') unless aliases.empty? + info << " (#{additional_info.join('; ')})" + end + + info << ' <-- default' if plugin.aliases.include? :default + + info + end + puts plugins.sort +end + +if option? '-v', '--version' + version +end + +if option? '-h', '--help' + help +end + +case subcommand +when 'highlight', nil + if ARGV.empty? + version + help + else + signature = args.map { |arg| arg[/^-/] ? '-' : 'f' }.join + names = args.map { |arg| arg.sub(/^-/, '') } + case signature + when /^$/ + exit + when /^ff?$/ + input_file, output_file, = *names + when /^f-f?$/ + input_file, output_format, output_file, = *names + when /^-ff?$/ + input_lang, input_file, output_file, = *names + when /^-f-f?$/ + input_lang, input_file, output_format, output_file, = *names + when /^--?f?$/ + input_lang, output_format, output_file, = *names + else + $stdout = $stderr + help + puts + puts "Unknown parameter order: #{args.join ' '}, expected: [-language] [input] [-format] [output]" + exit 1 + end + + if input_file + input_lang ||= CodeRay::FileType.fetch input_file, :text, true + end + + if output_file + output_format ||= CodeRay::FileType[output_file] || :plain + else + output_format ||= :terminal + end + + output_format = :page if output_format.to_s == 'html' + + if input_file + input = File.read input_file + else + input = $stdin.read + end + + begin + file = + if output_file + File.open output_file, 'w' + else + $stdout + end + CodeRay.encode(input, input_lang, output_format, :out => file) + file.puts + rescue CodeRay::PluginHost::PluginNotFound => boom + $stdout = $stderr + if boom.message[/CodeRay::(\w+)s could not load plugin :?(.*?): /] + puts "I don't know the #$1 \"#$2\"." + else + puts boom.message + end + # puts "I don't know this plugin: #{boom.message[/Could not load plugin (.*?): /, 1]}." + rescue CodeRay::Scanners::Scanner::ScanError + # this is sometimes raised by pagers; ignore + # FIXME: rescue Errno::EPIPE + ensure + file.close if output_file + end + end +when 'li', 'list' + arg = args.first && args.first.downcase + if [nil, 's', 'sc', 'scanner', 'scanners'].include? arg + puts 'input languages (Scanners):' + print_list_of CodeRay::Scanners + end + + if [nil, 'e', 'en', 'enc', 'encoder', 'encoders'].include? arg + puts 'output formats (Encoders):' + print_list_of CodeRay::Encoders + end + + if [nil, 'st', 'style', 'styles'].include? arg + puts 'CSS themes for HTML output (Styles):' + print_list_of CodeRay::Styles + end + + if [nil, 'f', 'ft', 'file', 'filetype', 'filetypes'].include? arg + puts 'recognized file types:' + + filetypes = Hash.new { |h, k| h[k] = [] } + CodeRay::FileType::TypeFromExt.inject filetypes do |types, (ext, type)| + types[type.to_s] << ".#{ext}" + types + end + CodeRay::FileType::TypeFromName.inject filetypes do |types, (name, type)| + types[type.to_s] << name + types + end + + filetypes.sort.each do |type, exts| + puts " #{type}: #{exts.sort_by { |ext| ext.size }.join(', ')}" + end + end +when 'stylesheet', 'style', 'css' + puts CodeRay::Encoders[:html]::CSS.new(args.first || :default).stylesheet +when 'commands' + commands +when 'help' + help +else + $stdout = $stderr + help + puts + if subcommand[/\A\w+\z/] + puts "Unknown command: #{subcommand}" + else + puts "File not found: #{subcommand}" + end + exit 1 +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay.rb new file mode 100644 index 0000000..f759ed6 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay.rb @@ -0,0 +1,284 @@ +# encoding: utf-8 +# Encoding.default_internal = 'UTF-8' + +# = CodeRay Library +# +# CodeRay is a Ruby library for syntax highlighting. +# +# I try to make CodeRay easy to use and intuitive, but at the same time fully +# featured, complete, fast and efficient. +# +# See README. +# +# It consists mainly of +# * the main engine: CodeRay (Scanners::Scanner, Tokens, Encoders::Encoder) +# * the plugin system: PluginHost, Plugin +# * the scanners in CodeRay::Scanners +# * the encoders in CodeRay::Encoders +# * the styles in CodeRay::Styles +# +# Here's a fancy graphic to light up this gray docu: +# +# http://cycnus.de/raindark/coderay/scheme.png +# +# == Documentation +# +# See CodeRay, Encoders, Scanners, Tokens. +# +# == Usage +# +# Remember you need RubyGems to use CodeRay, unless you have it in your load +# path. Run Ruby with -rubygems option if required. +# +# === Highlight Ruby code in a string as html +# +# require 'coderay' +# print CodeRay.scan('puts "Hello, world!"', :ruby).html +# +# # prints something like this: +# puts "Hello, world!" +# +# +# === Highlight C code from a file in a html div +# +# require 'coderay' +# print CodeRay.scan(File.read('ruby.h'), :c).div +# print CodeRay.scan_file('ruby.h').html.div +# +# You can include this div in your page. The used CSS styles can be printed with +# +# % coderay_stylesheet +# +# === Highlight without typing too much +# +# If you are one of the hasty (or lazy, or extremely curious) people, just run this file: +# +# % ruby -rubygems /path/to/coderay/coderay.rb > example.html +# +# and look at the file it created in your browser. +# +# = CodeRay Module +# +# The CodeRay module provides convenience methods for the engine. +# +# * The +lang+ and +format+ arguments select Scanner and Encoder to use. These are +# simply lower-case symbols, like :python or :html. +# * All methods take an optional hash as last parameter, +options+, that is send to +# the Encoder / Scanner. +# * Input and language are always sorted in this order: +code+, +lang+. +# (This is in alphabetical order, if you need a mnemonic ;) +# +# You should be able to highlight everything you want just using these methods; +# so there is no need to dive into CodeRay's deep class hierarchy. +# +# The examples in the demo directory demonstrate common cases using this interface. +# +# = Basic Access Ways +# +# Read this to get a general view what CodeRay provides. +# +# == Scanning +# +# Scanning means analysing an input string, splitting it up into Tokens. +# Each Token knows about what type it is: string, comment, class name, etc. +# +# Each +lang+ (language) has its own Scanner; for example, :ruby code is +# handled by CodeRay::Scanners::Ruby. +# +# CodeRay.scan:: Scan a string in a given language into Tokens. +# This is the most common method to use. +# CodeRay.scan_file:: Scan a file and guess the language using FileType. +# +# The Tokens object you get from these methods can encode itself; see Tokens. +# +# == Encoding +# +# Encoding means compiling Tokens into an output. This can be colored HTML or +# LaTeX, a textual statistic or just the number of non-whitespace tokens. +# +# Each Encoder provides output in a specific +format+, so you select Encoders via +# formats like :html or :statistic. +# +# CodeRay.encode:: Scan and encode a string in a given language. +# CodeRay.encode_tokens:: Encode the given tokens. +# CodeRay.encode_file:: Scan a file, guess the language using FileType and encode it. +# +# == All-in-One Encoding +# +# CodeRay.encode:: Highlight a string with a given input and output format. +# +# == Instanciating +# +# You can use an Encoder instance to highlight multiple inputs. This way, the setup +# for this Encoder must only be done once. +# +# CodeRay.encoder:: Create an Encoder instance with format and options. +# CodeRay.scanner:: Create an Scanner instance for lang, with '' as default code. +# +# To make use of CodeRay.scanner, use CodeRay::Scanner::code=. +# +# The scanning methods provide more flexibility; we recommend to use these. +# +# == Reusing Scanners and Encoders +# +# If you want to re-use scanners and encoders (because that is faster), see +# CodeRay::Duo for the most convenient (and recommended) interface. +module CodeRay + + $CODERAY_DEBUG ||= false + + CODERAY_PATH = File.expand_path('../coderay', __FILE__) + + # Assuming the path is a subpath of lib/coderay/ + def self.coderay_path *path + File.join CODERAY_PATH, *path + end + + require 'coderay/version' + + # helpers + autoload :FileType, coderay_path('helpers', 'file_type') + + # Tokens + autoload :Tokens, coderay_path('tokens') + autoload :TokensProxy, coderay_path('tokens_proxy') + autoload :TokenKinds, coderay_path('token_kinds') + + # Plugin system + autoload :PluginHost, coderay_path('helpers', 'plugin') + autoload :Plugin, coderay_path('helpers', 'plugin') + + # Plugins + autoload :Scanners, coderay_path('scanner') + autoload :Encoders, coderay_path('encoder') + autoload :Styles, coderay_path('style') + + # convenience access and reusable Encoder/Scanner pair + autoload :Duo, coderay_path('duo') + + class << self + + # Scans the given +code+ (a String) with the Scanner for +lang+. + # + # This is a simple way to use CodeRay. Example: + # require 'coderay' + # page = CodeRay.scan("puts 'Hello, world!'", :ruby).html + # + # See also demo/demo_simple. + def scan code, lang, options = {}, &block + TokensProxy.new code, lang, options, block + end + + # Scans +filename+ (a path to a code file) with the Scanner for +lang+. + # + # If +lang+ is :auto or omitted, the CodeRay::FileType module is used to + # determine it. If it cannot find out what type it is, it uses + # CodeRay::Scanners::Text. + # + # Calls CodeRay.scan. + # + # Example: + # require 'coderay' + # page = CodeRay.scan_file('some_c_code.c').html + def scan_file filename, lang = :auto, options = {}, &block + lang = FileType.fetch filename, :text, true if lang == :auto + code = File.read filename + scan code, lang, options, &block + end + + # Encode a string. + # + # This scans +code+ with the the Scanner for +lang+ and then + # encodes it with the Encoder for +format+. + # +options+ will be passed to the Encoder. + # + # See CodeRay::Encoder.encode. + def encode code, lang, format, options = {} + encoder(format, options).encode code, lang, options + end + + # Encode pre-scanned Tokens. + # Use this together with CodeRay.scan: + # + # require 'coderay' + # + # # Highlight a short Ruby code example in a HTML span + # tokens = CodeRay.scan '1 + 2', :ruby + # puts CodeRay.encode_tokens(tokens, :span) + # + def encode_tokens tokens, format, options = {} + encoder(format, options).encode_tokens tokens, options + end + + # Encodes +filename+ (a path to a code file) with the Scanner for +lang+. + # + # See CodeRay.scan_file. + # Notice that the second argument is the output +format+, not the input language. + # + # Example: + # require 'coderay' + # page = CodeRay.encode_file 'some_c_code.c', :html + def encode_file filename, format, options = {} + tokens = scan_file filename, :auto, get_scanner_options(options) + encode_tokens tokens, format, options + end + + # Highlight a string into a HTML
. + # + # CSS styles use classes, so you have to include a stylesheet + # in your output. + # + # See encode. + def highlight code, lang, options = { :css => :class }, format = :div + encode code, lang, format, options + end + + # Highlight a file into a HTML
. + # + # CSS styles use classes, so you have to include a stylesheet + # in your output. + # + # See encode. + def highlight_file filename, options = { :css => :class }, format = :div + encode_file filename, format, options + end + + # Finds the Encoder class for +format+ and creates an instance, passing + # +options+ to it. + # + # Example: + # require 'coderay' + # + # stats = CodeRay.encoder(:statistic) + # stats.encode("puts 17 + 4\n", :ruby) + # + # puts '%d out of %d tokens have the kind :integer.' % [ + # stats.type_stats[:integer].count, + # stats.real_token_count + # ] + # #-> 2 out of 4 tokens have the kind :integer. + def encoder format, options = {} + Encoders[format].new options + end + + # Finds the Scanner class for +lang+ and creates an instance, passing + # +options+ to it. + # + # See Scanner.new. + def scanner lang, options = {}, &block + Scanners[lang].new '', options, &block + end + + # Extract the options for the scanner from the +options+ hash. + # + # Returns an empty Hash if :scanner_options is not set. + # + # This is used if a method like CodeRay.encode has to provide options + # for Encoder _and_ scanner. + def get_scanner_options options + options.fetch :scanner_options, {} + end + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/duo.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/duo.rb new file mode 100644 index 0000000..cb3f8ee --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/duo.rb @@ -0,0 +1,81 @@ +module CodeRay + + # = Duo + # + # A Duo is a convenient way to use CodeRay. You just create a Duo, + # giving it a lang (language of the input code) and a format (desired + # output format), and call Duo#highlight with the code. + # + # Duo makes it easy to re-use both scanner and encoder for a repetitive + # task. It also provides a very easy interface syntax: + # + # require 'coderay' + # CodeRay::Duo[:python, :div].highlight 'import this' + # + # Until you want to do uncommon things with CodeRay, I recommend to use + # this method, since it takes care of everything. + class Duo + + attr_accessor :lang, :format, :options + + # Create a new Duo, holding a lang and a format to highlight code. + # + # simple: + # CodeRay::Duo[:ruby, :html].highlight 'bla 42' + # + # with options: + # CodeRay::Duo[:ruby, :html, :hint => :debug].highlight '????::??' + # + # alternative syntax without options: + # CodeRay::Duo[:ruby => :statistic].encode 'class << self; end' + # + # alternative syntax with options: + # CodeRay::Duo[{ :ruby => :statistic }, :do => :something].encode 'abc' + # + # The options are forwarded to scanner and encoder + # (see CodeRay.get_scanner_options). + def initialize lang = nil, format = nil, options = {} + if format.nil? && lang.is_a?(Hash) && lang.size == 1 + @lang = lang.keys.first + @format = lang[@lang] + else + @lang = lang + @format = format + end + @options = options + end + + class << self + # To allow calls like Duo[:ruby, :html].highlight. + alias [] new + end + + # The scanner of the duo. Only created once. + def scanner + @scanner ||= CodeRay.scanner @lang, CodeRay.get_scanner_options(@options) + end + + # The encoder of the duo. Only created once. + def encoder + @encoder ||= CodeRay.encoder @format, @options + end + + # Tokenize and highlight the code using +scanner+ and +encoder+. + def encode code, options = {} + options = @options.merge options + encoder.encode(code, @lang, options) + end + alias highlight encode + + # Allows to use Duo like a proc object: + # + # CodeRay::Duo[:python => :yaml].call(code) + # + # or, in Ruby 1.9 and later: + # + # CodeRay::Duo[:python => :yaml].(code) + alias call encode + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoder.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoder.rb new file mode 100644 index 0000000..d2d6c7e --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoder.rb @@ -0,0 +1,201 @@ +module CodeRay + + # This module holds the Encoder class and its subclasses. + # For example, the HTML encoder is named CodeRay::Encoders::HTML + # can be found in coderay/encoders/html. + # + # Encoders also provides methods and constants for the register + # mechanism and the [] method that returns the Encoder class + # belonging to the given format. + module Encoders + + extend PluginHost + plugin_path File.dirname(__FILE__), 'encoders' + + # = Encoder + # + # The Encoder base class. Together with Scanner and + # Tokens, it forms the highlighting triad. + # + # Encoder instances take a Tokens object and do something with it. + # + # The most common Encoder is surely the HTML encoder + # (CodeRay::Encoders::HTML). It highlights the code in a colorful + # html page. + # If you want the highlighted code in a div or a span instead, + # use its subclasses Div and Span. + class Encoder + extend Plugin + plugin_host Encoders + + class << self + + # If FILE_EXTENSION isn't defined, this method returns the + # downcase class name instead. + def const_missing sym + if sym == :FILE_EXTENSION + (defined?(@plugin_id) && @plugin_id || name[/\w+$/].downcase).to_s + else + super + end + end + + # The default file extension for output file of this encoder class. + def file_extension + self::FILE_EXTENSION + end + + end + + # Subclasses are to store their default options in this constant. + DEFAULT_OPTIONS = { } + + # The options you gave the Encoder at creating. + attr_accessor :options, :scanner + + # Creates a new Encoder. + # +options+ is saved and used for all encode operations, as long + # as you don't overwrite it there by passing additional options. + # + # Encoder objects provide three encode methods: + # - encode simply takes a +code+ string and a +lang+ + # - encode_tokens expects a +tokens+ object instead + # + # Each method has an optional +options+ parameter. These are + # added to the options you passed at creation. + def initialize options = {} + @options = self.class::DEFAULT_OPTIONS.merge options + @@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN = false + end + + # Encode a Tokens object. + def encode_tokens tokens, options = {} + options = @options.merge options + @scanner = tokens.scanner if tokens.respond_to? :scanner + setup options + compile tokens, options + finish options + end + + # Encode the given +code+ using the Scanner for +lang+. + def encode code, lang, options = {} + options = @options.merge options + @scanner = Scanners[lang].new code, CodeRay.get_scanner_options(options).update(:tokens => self) + setup options + @scanner.tokenize + finish options + end + + # You can use highlight instead of encode, if that seems + # more clear to you. + alias highlight encode + + # The default file extension for this encoder. + def file_extension + self.class.file_extension + end + + def << token + unless @@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN + warn 'Using old Tokens#<< interface.' + @@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN = true + end + self.token(*token) + end + + # Called with +content+ and +kind+ of the currently scanned token. + # For simple scanners, it's enougth to implement this method. + # + # By default, it calls text_token, begin_group, end_group, begin_line, + # or end_line, depending on the +content+. + def token content, kind + case content + when String + text_token content, kind + when :begin_group + begin_group kind + when :end_group + end_group kind + when :begin_line + begin_line kind + when :end_line + end_line kind + else + raise ArgumentError, 'Unknown token content type: %p, kind = %p' % [content, kind] + end + end + + # Called for each text token ([text, kind]), where text is a String. + def text_token text, kind + @out << text + end + + # Starts a token group with the given +kind+. + def begin_group kind + end + + # Ends a token group with the given +kind+. + def end_group kind + end + + # Starts a new line token group with the given +kind+. + def begin_line kind + end + + # Ends a new line token group with the given +kind+. + def end_line kind + end + + protected + + # Called with merged options before encoding starts. + # Sets @out to an empty string. + # + # See the HTML Encoder for an example of option caching. + def setup options + @out = get_output(options) + end + + def get_output options + options[:out] || '' + end + + # Append data.to_s to the output. Returns the argument. + def output data + @out << data.to_s + data + end + + # Called with merged options after encoding starts. + # The return value is the result of encoding, typically @out. + def finish options + @out + end + + # Do the encoding. + # + # The already created +tokens+ object must be used; it must be a + # Tokens object. + def compile tokens, options = {} + content = nil + for item in tokens + if item.is_a? Array + raise ArgumentError, 'Two-element array tokens are no longer supported.' + end + if content + token content, item + content = nil + else + content = item + end + end + raise 'odd number list for Tokens' if content + end + + alias tokens compile + public :tokens + + end + + end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/_map.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/_map.rb new file mode 100644 index 0000000..4cca196 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/_map.rb @@ -0,0 +1,17 @@ +module CodeRay +module Encoders + + map \ + :loc => :lines_of_code, + :plain => :text, + :plaintext => :text, + :remove_comments => :comment_filter, + :stats => :statistic, + :term => :terminal, + :tty => :terminal, + :yml => :yaml + + # No default because Tokens#nonsense should raise NoMethodError. + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/comment_filter.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/comment_filter.rb new file mode 100644 index 0000000..28336b3 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/comment_filter.rb @@ -0,0 +1,25 @@ +module CodeRay +module Encoders + + load :token_kind_filter + + # A simple Filter that removes all tokens of the :comment kind. + # + # Alias: +remove_comments+ + # + # Usage: + # CodeRay.scan('print # foo', :ruby).comment_filter.text + # #-> "print " + # + # See also: TokenKindFilter, LinesOfCode + class CommentFilter < TokenKindFilter + + register_for :comment_filter + + DEFAULT_OPTIONS = superclass::DEFAULT_OPTIONS.merge \ + :exclude => [:comment, :docstring] + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/count.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/count.rb new file mode 100644 index 0000000..98a427e --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/count.rb @@ -0,0 +1,39 @@ +module CodeRay +module Encoders + + # Returns the number of tokens. + # + # Text and block tokens are counted. + class Count < Encoder + + register_for :count + + protected + + def setup options + super + + @count = 0 + end + + def finish options + output @count + end + + public + + def text_token text, kind + @count += 1 + end + + def begin_group kind + @count += 1 + end + alias end_group begin_group + alias begin_line begin_group + alias end_line begin_group + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug.rb new file mode 100644 index 0000000..f4db330 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug.rb @@ -0,0 +1,49 @@ +module CodeRay +module Encoders + + # = Debug Encoder + # + # Fast encoder producing simple debug output. + # + # It is readable and diff-able and is used for testing. + # + # You cannot fully restore the tokens information from the + # output, because consecutive :space tokens are merged. + # + # See also: Scanners::Debug + class Debug < Encoder + + register_for :debug + + FILE_EXTENSION = 'raydebug' + + def text_token text, kind + if kind == :space + @out << text + else + text = text.gsub('\\', '\\\\\\\\') if text.index('\\') + text = text.gsub(')', '\\\\)') if text.index(')') + @out << "#{kind}(#{text})" + end + end + + def begin_group kind + @out << "#{kind}<" + end + + def end_group kind + @out << '>' + end + + def begin_line kind + @out << "#{kind}[" + end + + def end_line kind + @out << ']' + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug_lint.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug_lint.rb new file mode 100644 index 0000000..a4eba2c --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug_lint.rb @@ -0,0 +1,63 @@ +module CodeRay +module Encoders + + load :lint + + # = Debug Lint Encoder + # + # Debug encoder with additional checks for: + # + # - empty tokens + # - incorrect nesting + # + # It will raise an InvalidTokenStream exception when any of the above occurs. + # + # See also: Encoders::Debug + class DebugLint < Debug + + register_for :debug_lint + + def text_token text, kind + raise Lint::EmptyToken, 'empty token for %p' % [kind] if text.empty? + raise Lint::UnknownTokenKind, 'unknown token kind %p (text was %p)' % [kind, text] unless TokenKinds.has_key? kind + super + end + + def begin_group kind + @opened << kind + super + end + + def end_group kind + raise Lint::IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_group)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind + @opened.pop + super + end + + def begin_line kind + @opened << kind + super + end + + def end_line kind + raise Lint::IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_line)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind + @opened.pop + super + end + + protected + + def setup options + super + @opened = [] + end + + def finish options + raise 'Some tokens still open at end of token stream: %p' % [@opened] unless @opened.empty? + super + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/div.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/div.rb new file mode 100644 index 0000000..efd9435 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/div.rb @@ -0,0 +1,23 @@ +module CodeRay +module Encoders + + load :html + + # Wraps HTML output into a DIV element, using inline styles by default. + # + # See Encoders::HTML for available options. + class Div < HTML + + FILE_EXTENSION = 'div.html' + + register_for :div + + DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \ + :css => :style, + :wrap => :div, + :line_numbers => false + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/filter.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/filter.rb new file mode 100644 index 0000000..e7f34d6 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/filter.rb @@ -0,0 +1,58 @@ +module CodeRay +module Encoders + + # A Filter encoder has another Tokens instance as output. + # It can be subclass to select, remove, or modify tokens in the stream. + # + # Subclasses of Filter are called "Filters" and can be chained. + # + # == Options + # + # === :tokens + # + # The Tokens object which will receive the output. + # + # Default: Tokens.new + # + # See also: TokenKindFilter + class Filter < Encoder + + register_for :filter + + protected + def setup options + super + + @tokens = options[:tokens] || Tokens.new + end + + def finish options + output @tokens + end + + public + + def text_token text, kind # :nodoc: + @tokens.text_token text, kind + end + + def begin_group kind # :nodoc: + @tokens.begin_group kind + end + + def begin_line kind # :nodoc: + @tokens.begin_line kind + end + + def end_group kind # :nodoc: + @tokens.end_group kind + end + + def end_line kind # :nodoc: + @tokens.end_line kind + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html.rb new file mode 100644 index 0000000..d2ebb5a --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html.rb @@ -0,0 +1,332 @@ +require 'set' + +module CodeRay +module Encoders + + # = HTML Encoder + # + # This is CodeRay's most important highlighter: + # It provides save, fast XHTML generation and CSS support. + # + # == Usage + # + # require 'coderay' + # puts CodeRay.scan('Some /code/', :ruby).html #-> a HTML page + # puts CodeRay.scan('Some /code/', :ruby).html(:wrap => :span) + # #-> Some /code/ + # puts CodeRay.scan('Some /code/', :ruby).span #-> the same + # + # puts CodeRay.scan('Some code', :ruby).html( + # :wrap => nil, + # :line_numbers => :inline, + # :css => :style + # ) + # + # == Options + # + # === :tab_width + # Convert \t characters to +n+ spaces (a number.) + # + # Default: 8 + # + # === :css + # How to include the styles; can be :class or :style. + # + # Default: :class + # + # === :wrap + # Wrap in :page, :div, :span or nil. + # + # You can also use Encoders::Div and Encoders::Span. + # + # Default: nil + # + # === :title + # + # The title of the HTML page (works only when :wrap is set to :page.) + # + # Default: 'CodeRay output' + # + # === :break_lines + # + # Split multiline blocks at line breaks. + # Forced to true if :line_numbers option is set to :inline. + # + # Default: false + # + # === :line_numbers + # Include line numbers in :table, :inline, or nil (no line numbers) + # + # Default: nil + # + # === :line_number_anchors + # Adds anchors and links to the line numbers. Can be false (off), true (on), + # or a prefix string that will be prepended to the anchor name. + # + # The prefix must consist only of letters, digits, and underscores. + # + # Default: true, default prefix name: "line" + # + # === :line_number_start + # Where to start with line number counting. + # + # Default: 1 + # + # === :bold_every + # Make every +n+-th number appear bold. + # + # Default: 10 + # + # === :highlight_lines + # + # Highlights certain line numbers. + # Can be any Enumerable, typically just an Array or Range, of numbers. + # + # Bolding is deactivated when :highlight_lines is set. It only makes sense + # in combination with :line_numbers. + # + # Default: nil + # + # === :hint + # Include some information into the output using the title attribute. + # Can be :info (show token kind on mouse-over), :info_long (with full path) + # or :debug (via inspect). + # + # Default: false + class HTML < Encoder + + register_for :html + + FILE_EXTENSION = 'snippet.html' + + DEFAULT_OPTIONS = { + :tab_width => 8, + + :css => :class, + :style => :alpha, + :wrap => nil, + :title => 'CodeRay output', + + :break_lines => false, + + :line_numbers => nil, + :line_number_anchors => 'n', + :line_number_start => 1, + :bold_every => 10, + :highlight_lines => nil, + + :hint => false, + } + + autoload :Output, CodeRay.coderay_path('encoders', 'html', 'output') + autoload :CSS, CodeRay.coderay_path('encoders', 'html', 'css') + autoload :Numbering, CodeRay.coderay_path('encoders', 'html', 'numbering') + + attr_reader :css + + protected + + def self.make_html_escape_hash + { + '&' => '&', + '"' => '"', + '>' => '>', + '<' => '<', + # "\t" => will be set to ' ' * options[:tab_width] during setup + }.tap do |hash| + # Escape ASCII control codes except \x9 == \t and \xA == \n. + (Array(0x00..0x8) + Array(0xB..0x1F)).each { |invalid| hash[invalid.chr] = ' ' } + end + end + + HTML_ESCAPE = make_html_escape_hash + HTML_ESCAPE_PATTERN = /[\t"&><\0-\x8\xB-\x1F]/ + + TOKEN_KIND_TO_INFO = Hash.new do |h, kind| + h[kind] = kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize } + end + + TRANSPARENT_TOKEN_KINDS = Set[ + :delimiter, :modifier, :content, :escape, :inline_delimiter, + ] + + # Generate a hint about the given +kinds+ in a +hint+ style. + # + # +hint+ may be :info, :info_long or :debug. + def self.token_path_to_hint hint, kinds + kinds = Array kinds + title = + case hint + when :info + kinds = kinds[1..-1] if TRANSPARENT_TOKEN_KINDS.include? kinds.first + TOKEN_KIND_TO_INFO[kinds.first] + when :info_long + kinds.reverse.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/') + when :debug + kinds.inspect + end + title ? " title=\"#{title}\"" : '' + end + + def setup options + super + + check_options! options + + if options[:wrap] || options[:line_numbers] + @real_out = @out + @out = '' + end + + @break_lines = (options[:break_lines] == true) + + @HTML_ESCAPE = HTML_ESCAPE.merge("\t" => ' ' * options[:tab_width]) + + @opened = [] + @last_opened = nil + @css = CSS.new options[:style] + + @span_for_kinds = make_span_for_kinds(options[:css], options[:hint]) + + @set_last_opened = options[:hint] || options[:css] == :style + end + + def finish options + unless @opened.empty? + @out << '' while @opened.pop + @last_opened = nil + end + + if @out.respond_to? :to_str + @out.extend Output + @out.css = @css + if options[:line_numbers] + Numbering.number! @out, options[:line_numbers], options + end + @out.wrap! options[:wrap] + @out.apply_title! options[:title] + end + + if defined?(@real_out) && @real_out + @real_out << @out + @out = @real_out + end + + super + end + + public + + def text_token text, kind + style = @span_for_kinds[@last_opened ? [kind, *@opened] : kind] + + text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] } if text =~ /#{HTML_ESCAPE_PATTERN}/o + text = break_lines(text, style) if @break_lines && (style || @opened.size > 0) && text.index("\n") + + if style + @out << style << text << '' + else + @out << text + end + end + + # token groups, eg. strings + def begin_group kind + @out << (@span_for_kinds[@last_opened ? [kind, *@opened] : kind] || '') + @opened << kind + @last_opened = kind if @set_last_opened + end + + def end_group kind + check_group_nesting 'token group', kind if $CODERAY_DEBUG + close_span + end + + # whole lines to be highlighted, eg. a deleted line in a diff + def begin_line kind + if style = @span_for_kinds[@last_opened ? [kind, *@opened] : kind] + if style['class="'] + @out << style.sub('class="', 'class="line ') + else + @out << style.sub('>', ' class="line">') + end + else + @out << '' + end + @opened << kind + @last_opened = kind if @options[:css] == :style + end + + def end_line kind + check_group_nesting 'line', kind if $CODERAY_DEBUG + close_span + end + + protected + + def check_options! options + unless [false, nil, :debug, :info, :info_long].include? options[:hint] + raise ArgumentError, "Unknown value %p for :hint; expected :info, :info_long, :debug, false, or nil." % [options[:hint]] + end + + unless [:class, :style].include? options[:css] + raise ArgumentError, 'Unknown value %p for :css.' % [options[:css]] + end + + options[:break_lines] = true if options[:line_numbers] == :inline + end + + def css_class_for_kinds kinds + TokenKinds[kinds.is_a?(Symbol) ? kinds : kinds.first] + end + + def style_for_kinds kinds + css_classes = kinds.is_a?(Array) ? kinds.map { |c| TokenKinds[c] } : [TokenKinds[kinds]] + @css.get_style_for_css_classes css_classes + end + + def make_span_for_kinds method, hint + Hash.new do |h, kinds| + begin + css_class = css_class_for_kinds(kinds) + title = HTML.token_path_to_hint hint, kinds if hint + + if css_class || title + if method == :style + style = style_for_kinds(kinds) + "" + else + "" + end + end + end.tap do |span| + h.clear if h.size >= 100 + h[kinds] = span + end + end + end + + def check_group_nesting name, kind + if @opened.empty? || @opened.last != kind + warn "Malformed token stream: Trying to close a #{name} (%p) that is not open. Open are: %p." % [kind, @opened[1..-1]] + end + end + + def break_lines text, style + reopen = '' + @opened.each_with_index do |kind, index| + reopen << (@span_for_kinds[index > 0 ? [kind, *@opened[0...index]] : kind] || '') + end + text.gsub("\n", "#{'' * @opened.size}#{'' if style}\n#{reopen}#{style}") + end + + def close_span + if @opened.pop + @out << '' + @last_opened = @opened.last if @last_opened + end + end + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/css.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/css.rb new file mode 100644 index 0000000..164d7f8 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/css.rb @@ -0,0 +1,65 @@ +module CodeRay +module Encoders + + class HTML + class CSS # :nodoc: + + attr :stylesheet + + def CSS.load_stylesheet style = nil + CodeRay::Styles[style] + end + + def initialize style = :default + @styles = Hash.new + style = CSS.load_stylesheet style + @stylesheet = [ + style::CSS_MAIN_STYLES, + style::TOKEN_COLORS.gsub(/^(?!$)/, '.CodeRay ') + ].join("\n") + parse style::TOKEN_COLORS + end + + def get_style_for_css_classes css_classes + cl = @styles[css_classes.first] + return '' unless cl + style = '' + 1.upto css_classes.size do |offset| + break if style = cl[css_classes[offset .. -1]] + end + # warn 'Style not found: %p' % [styles] if style.empty? + return style + end + + private + + CSS_CLASS_PATTERN = / + ( # $1 = selectors + (?: + (?: \s* \. [-\w]+ )+ + \s* ,? + )+ + ) + \s* \{ \s* + ( [^\}]+ )? # $2 = style + \s* \} \s* + | + ( [^\n]+ ) # $3 = error + /mx + def parse stylesheet + stylesheet.scan CSS_CLASS_PATTERN do |selectors, style, error| + raise "CSS parse error: '#{error.inspect}' not recognized" if error + for selector in selectors.split(',') + classes = selector.scan(/[-\w]+/) + cl = classes.pop + @styles[cl] ||= Hash.new + @styles[cl][classes] = style.to_s.strip.delete(' ').chomp(';') + end + end + end + + end + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/numbering.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/numbering.rb new file mode 100644 index 0000000..a1b9c04 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/numbering.rb @@ -0,0 +1,108 @@ +module CodeRay +module Encoders + + class HTML + + module Numbering # :nodoc: + + def self.number! output, mode = :table, options = {} + return self unless mode + + options = DEFAULT_OPTIONS.merge options + + start = options[:line_number_start] + unless start.is_a? Integer + raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start + end + + anchor_prefix = options[:line_number_anchors] + anchor_prefix = 'line' if anchor_prefix == true + anchor_prefix = anchor_prefix.to_s[/[\w-]+/] if anchor_prefix + anchoring = + if anchor_prefix + proc do |line| + line = line.to_s + anchor = anchor_prefix + line + "#{line}" + end + else + :to_s.to_proc + end + + bold_every = options[:bold_every] + highlight_lines = options[:highlight_lines] + bolding = + if bold_every == false && highlight_lines == nil + anchoring + elsif highlight_lines.is_a? Enumerable + highlight_lines = highlight_lines.to_set + proc do |line| + if highlight_lines.include? line + "#{anchoring[line]}" # highlighted line numbers in bold + else + anchoring[line] + end + end + elsif bold_every.is_a? Integer + raise ArgumentError, ":bolding can't be 0." if bold_every == 0 + proc do |line| + if line % bold_every == 0 + "#{anchoring[line]}" # every bold_every-th number in bold + else + anchoring[line] + end + end + else + raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every + end + + if position_of_last_newline = output.rindex(RUBY_VERSION >= '1.9' ? /\n/ : ?\n) + after_last_newline = output[position_of_last_newline + 1 .. -1] + ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/] + + if ends_with_newline + line_count = output.count("\n") + else + line_count = output.count("\n") + 1 + end + else + line_count = 1 + end + + case mode + when :inline + max_width = (start + line_count).to_s.size + line_number = start + output.gsub!(/^.*$\n?/) do |line| + line_number_text = bolding.call line_number + indent = ' ' * (max_width - line_number.to_s.size) + line_number += 1 + "#{indent}#{line_number_text}#{line}" + end + + when :table + line_numbers = (start ... start + line_count).map(&bolding).join("\n") + line_numbers << "\n" + line_numbers_table_template = Output::TABLE.apply('LINE_NUMBERS', line_numbers) + + output.gsub!(/<\/div>\n/, '
') + output.wrap_in! line_numbers_table_template + output.wrapped_in = :div + + when :list + raise NotImplementedError, 'The :list option is no longer available. Use :table.' + + else + raise ArgumentError, 'Unknown value %p for mode: expected one of %p' % + [mode, [:table, :inline]] + end + + output + end + + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/output.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/output.rb new file mode 100644 index 0000000..de6f6ea --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/output.rb @@ -0,0 +1,166 @@ +module CodeRay +module Encoders + + class HTML + + # This module is included in the output String of the HTML Encoder. + # + # It provides methods like wrap, div, page etc. + # + # Remember to use #clone instead of #dup to keep the modules the object was + # extended with. + # + # TODO: Rewrite this without monkey patching. + module Output + + attr_accessor :css + + class << self + + # Raises an exception if an object that doesn't respond to to_str is extended by Output, + # to prevent users from misuse. Use Module#remove_method to disable. + def extended o # :nodoc: + warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str + end + + def make_stylesheet css, in_tag = false # :nodoc: + sheet = css.stylesheet + sheet = <<-'CSS' if in_tag + + CSS + sheet + end + + def page_template_for_css css # :nodoc: + sheet = make_stylesheet css + PAGE.apply 'CSS', sheet + end + + end + + def wrapped_in? element + wrapped_in == element + end + + def wrapped_in + @wrapped_in ||= nil + end + attr_writer :wrapped_in + + def wrap_in! template + Template.wrap! self, template, 'CONTENT' + self + end + + def apply_title! title + self.sub!(/()(<\/title>)/) { $1 + title + $2 } + self + end + + def wrap! element, *args + return self if not element or element == wrapped_in + case element + when :div + raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil + wrap_in! DIV + when :span + raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil + wrap_in! SPAN + when :page + wrap! :div if wrapped_in? nil + raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div + wrap_in! Output.page_template_for_css(@css) + if args.first.is_a?(Hash) && title = args.first[:title] + apply_title! title + end + self + when nil + return self + else + raise "Unknown value %p for :wrap" % element + end + @wrapped_in = element + self + end + + def stylesheet in_tag = false + Output.make_stylesheet @css, in_tag + end + +#-- don't include the templates in docu + + class Template < String # :nodoc: + + def self.wrap! str, template, target + target = Regexp.new(Regexp.escape("<%#{target}%>")) + if template =~ target + str[0,0] = $` + str << $' + else + raise "Template target <%%%p%%> not found" % target + end + end + + def apply target, replacement + target = Regexp.new(Regexp.escape("<%#{target}%>")) + if self =~ target + Template.new($` + replacement + $') + else + raise "Template target <%%%p%%> not found" % target + end + end + + end + + SPAN = Template.new '<span class="CodeRay"><%CONTENT%></span>' + + DIV = Template.new <<-DIV +<div class="CodeRay"> + <div class="code"><pre><%CONTENT%></pre></div> +</div> + DIV + + TABLE = Template.new <<-TABLE +<table class="CodeRay"><tr> + <td class="line-numbers"><pre><%LINE_NUMBERS%></pre></td> + <td class="code"><pre><%CONTENT%></pre></td> +</tr></table> + TABLE + + PAGE = Template.new <<-PAGE +<!DOCTYPE html> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title> + + + + +<%CONTENT%> + + + PAGE + + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/json.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/json.rb new file mode 100644 index 0000000..a9e40dc --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/json.rb @@ -0,0 +1,83 @@ +module CodeRay +module Encoders + + # A simple JSON Encoder. + # + # Example: + # CodeRay.scan('puts "Hello world!"', :ruby).json + # yields + # [ + # {"type"=>"text", "text"=>"puts", "kind"=>"ident"}, + # {"type"=>"text", "text"=>" ", "kind"=>"space"}, + # {"type"=>"block", "action"=>"open", "kind"=>"string"}, + # {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"}, + # {"type"=>"text", "text"=>"Hello world!", "kind"=>"content"}, + # {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"}, + # {"type"=>"block", "action"=>"close", "kind"=>"string"}, + # ] + class JSON < Encoder + + begin + require 'json' + rescue LoadError + begin + require 'rubygems' unless defined? Gem + gem 'json' + require 'json' + rescue LoadError + $stderr.puts "The JSON encoder needs the JSON library.\n" \ + "Please gem install json." + raise + end + end + + register_for :json + FILE_EXTENSION = 'json' + + protected + def setup options + super + + @first = true + @out << '[' + end + + def finish options + @out << ']' + end + + def append data + if @first + @first = false + else + @out << ',' + end + + @out << data.to_json + end + + public + def text_token text, kind + append :type => 'text', :text => text, :kind => kind + end + + def begin_group kind + append :type => 'block', :action => 'open', :kind => kind + end + + def end_group kind + append :type => 'block', :action => 'close', :kind => kind + end + + def begin_line kind + append :type => 'block', :action => 'begin_line', :kind => kind + end + + def end_line kind + append :type => 'block', :action => 'end_line', :kind => kind + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lines_of_code.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lines_of_code.rb new file mode 100644 index 0000000..5f8422f --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lines_of_code.rb @@ -0,0 +1,45 @@ +module CodeRay +module Encoders + + # Counts the LoC (Lines of Code). Returns an Integer >= 0. + # + # Alias: +loc+ + # + # Everything that is not comment, markup, doctype/shebang, or an empty line, + # is considered to be code. + # + # For example, + # * HTML files not containing JavaScript have 0 LoC + # * in a Java class without comments, LoC is the number of non-empty lines + # + # A Scanner class should define the token kinds that are not code in the + # KINDS_NOT_LOC constant, which defaults to [:comment, :doctype]. + class LinesOfCode < TokenKindFilter + + register_for :lines_of_code + + NON_EMPTY_LINE = /^\s*\S.*$/ + + protected + + def setup options + if scanner + kinds_not_loc = scanner.class::KINDS_NOT_LOC + else + warn "Tokens have no associated scanner, counting all nonempty lines." if $VERBOSE + kinds_not_loc = CodeRay::Scanners::Scanner::KINDS_NOT_LOC + end + + options[:exclude] = kinds_not_loc + + super options + end + + def finish options + output @tokens.text.scan(NON_EMPTY_LINE).size + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lint.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lint.rb new file mode 100644 index 0000000..88c8bd1 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lint.rb @@ -0,0 +1,59 @@ +module CodeRay +module Encoders + + # = Lint Encoder + # + # Checks for: + # + # - empty tokens + # - incorrect nesting + # + # It will raise an InvalidTokenStream exception when any of the above occurs. + # + # See also: Encoders::DebugLint + class Lint < Debug + + register_for :lint + + InvalidTokenStream = Class.new StandardError + EmptyToken = Class.new InvalidTokenStream + UnknownTokenKind = Class.new InvalidTokenStream + IncorrectTokenGroupNesting = Class.new InvalidTokenStream + + def text_token text, kind + raise EmptyToken, 'empty token for %p' % [kind] if text.empty? + raise UnknownTokenKind, 'unknown token kind %p (text was %p)' % [kind, text] unless TokenKinds.has_key? kind + end + + def begin_group kind + @opened << kind + end + + def end_group kind + raise IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_group)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind + @opened.pop + end + + def begin_line kind + @opened << kind + end + + def end_line kind + raise IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_line)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind + @opened.pop + end + + protected + + def setup options + @opened = [] + end + + def finish options + raise 'Some tokens still open at end of token stream: %p' % [@opened] unless @opened.empty? + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/null.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/null.rb new file mode 100644 index 0000000..73ba47d --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/null.rb @@ -0,0 +1,18 @@ +module CodeRay +module Encoders + + # = Null Encoder + # + # Does nothing and returns an empty string. + class Null < Encoder + + register_for :null + + def text_token text, kind + # do nothing + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/page.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/page.rb new file mode 100644 index 0000000..800e73f --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/page.rb @@ -0,0 +1,24 @@ +module CodeRay +module Encoders + + load :html + + # Wraps the output into a HTML page, using CSS classes and + # line numbers in the table format by default. + # + # See Encoders::HTML for available options. + class Page < HTML + + FILE_EXTENSION = 'html' + + register_for :page + + DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \ + :css => :class, + :wrap => :page, + :line_numbers => :table + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/span.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/span.rb new file mode 100644 index 0000000..da705bd --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/span.rb @@ -0,0 +1,23 @@ +module CodeRay +module Encoders + + load :html + + # Wraps HTML output into a SPAN element, using inline styles by default. + # + # See Encoders::HTML for available options. + class Span < HTML + + FILE_EXTENSION = 'span.html' + + register_for :span + + DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \ + :css => :style, + :wrap => :span, + :line_numbers => false + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/statistic.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/statistic.rb new file mode 100644 index 0000000..b2f8b83 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/statistic.rb @@ -0,0 +1,95 @@ +module CodeRay +module Encoders + + # Makes a statistic for the given tokens. + # + # Alias: +stats+ + class Statistic < Encoder + + register_for :statistic + + attr_reader :type_stats, :real_token_count # :nodoc: + + TypeStats = Struct.new :count, :size # :nodoc: + + protected + + def setup options + super + + @type_stats = Hash.new { |h, k| h[k] = TypeStats.new 0, 0 } + @real_token_count = 0 + end + + STATS = <<-STATS # :nodoc: + +Code Statistics + +Tokens %8d + Non-Whitespace %8d +Bytes Total %8d + +Token Types (%d): + type count ratio size (average) +------------------------------------------------------------- +%s + STATS + + TOKEN_TYPES_ROW = <<-TKR # :nodoc: + %-20s %8d %6.2f %% %5.1f + TKR + + def finish options + all = @type_stats['TOTAL'] + all_count, all_size = all.count, all.size + @type_stats.each do |type, stat| + stat.size /= stat.count.to_f + end + types_stats = @type_stats.sort_by { |k, v| [-v.count, k.to_s] }.map do |k, v| + TOKEN_TYPES_ROW % [k, v.count, 100.0 * v.count / all_count, v.size] + end.join + @out << STATS % [ + all_count, @real_token_count, all_size, + @type_stats.delete_if { |k, v| k.is_a? String }.size, + types_stats + ] + + super + end + + public + + def text_token text, kind + @real_token_count += 1 unless kind == :space + @type_stats[kind].count += 1 + @type_stats[kind].size += text.size + @type_stats['TOTAL'].size += text.size + @type_stats['TOTAL'].count += 1 + end + + def begin_group kind + block_token ':begin_group', kind + end + + def end_group kind + block_token ':end_group', kind + end + + def begin_line kind + block_token ':begin_line', kind + end + + def end_line kind + block_token ':end_line', kind + end + + def block_token action, kind + @type_stats['TOTAL'].count += 1 + @type_stats[action].count += 1 + @type_stats[kind].count += 1 + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/terminal.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/terminal.rb new file mode 100644 index 0000000..c7ae014 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/terminal.rb @@ -0,0 +1,195 @@ +module CodeRay + module Encoders + + # Outputs code highlighted for a color terminal. + # + # Note: This encoder is in beta. It currently doesn't use the Styles. + # + # Alias: +term+ + # + # == Authors & License + # + # By Rob Aldred (http://robaldred.co.uk) + # + # Based on idea by Nathan Weizenbaum (http://nex-3.com) + # + # MIT License (http://www.opensource.org/licenses/mit-license.php) + class Terminal < Encoder + + register_for :terminal + + TOKEN_COLORS = { + :debug => "\e[1;37;44m", + + :annotation => "\e[34m", + :attribute_name => "\e[35m", + :attribute_value => "\e[31m", + :binary => { + :self => "\e[31m", + :char => "\e[1;31m", + :delimiter => "\e[1;31m", + }, + :char => { + :self => "\e[35m", + :delimiter => "\e[1;35m" + }, + :class => "\e[1;35;4m", + :class_variable => "\e[36m", + :color => "\e[32m", + :comment => { + :self => "\e[1;30m", + :char => "\e[37m", + :delimiter => "\e[37m", + }, + :constant => "\e[1;34;4m", + :decorator => "\e[35m", + :definition => "\e[1;33m", + :directive => "\e[33m", + :docstring => "\e[31m", + :doctype => "\e[1;34m", + :done => "\e[1;30;2m", + :entity => "\e[31m", + :error => "\e[1;37;41m", + :exception => "\e[1;31m", + :float => "\e[1;35m", + :function => "\e[1;34m", + :global_variable => "\e[1;32m", + :hex => "\e[1;36m", + :id => "\e[1;34m", + :include => "\e[31m", + :integer => "\e[1;34m", + :imaginary => "\e[1;34m", + :important => "\e[1;31m", + :key => { + :self => "\e[35m", + :char => "\e[1;35m", + :delimiter => "\e[1;35m", + }, + :keyword => "\e[32m", + :label => "\e[1;33m", + :local_variable => "\e[33m", + :namespace => "\e[1;35m", + :octal => "\e[1;34m", + :predefined => "\e[36m", + :predefined_constant => "\e[1;36m", + :predefined_type => "\e[1;32m", + :preprocessor => "\e[1;36m", + :pseudo_class => "\e[1;34m", + :regexp => { + :self => "\e[35m", + :delimiter => "\e[1;35m", + :modifier => "\e[35m", + :char => "\e[1;35m", + }, + :reserved => "\e[32m", + :shell => { + :self => "\e[33m", + :char => "\e[1;33m", + :delimiter => "\e[1;33m", + :escape => "\e[1;33m", + }, + :string => { + :self => "\e[31m", + :modifier => "\e[1;31m", + :char => "\e[1;35m", + :delimiter => "\e[1;31m", + :escape => "\e[1;31m", + }, + :symbol => { + :self => "\e[33m", + :delimiter => "\e[1;33m", + }, + :tag => "\e[32m", + :type => "\e[1;34m", + :value => "\e[36m", + :variable => "\e[34m", + + :insert => { + :self => "\e[42m", + :insert => "\e[1;32;42m", + :eyecatcher => "\e[102m", + }, + :delete => { + :self => "\e[41m", + :delete => "\e[1;31;41m", + :eyecatcher => "\e[101m", + }, + :change => { + :self => "\e[44m", + :change => "\e[37;44m", + }, + :head => { + :self => "\e[45m", + :filename => "\e[37;45m" + }, + } + + TOKEN_COLORS[:keyword] = TOKEN_COLORS[:reserved] + TOKEN_COLORS[:method] = TOKEN_COLORS[:function] + TOKEN_COLORS[:escape] = TOKEN_COLORS[:delimiter] + + protected + + def setup(options) + super + @opened = [] + @color_scopes = [TOKEN_COLORS] + end + + public + + def text_token text, kind + if color = @color_scopes.last[kind] + color = color[:self] if color.is_a? Hash + + @out << color + @out << (text.index("\n") ? text.gsub("\n", "\e[0m\n" + color) : text) + @out << "\e[0m" + if outer_color = @color_scopes.last[:self] + @out << outer_color + end + else + @out << text + end + end + + def begin_group kind + @opened << kind + @out << open_token(kind) + end + alias begin_line begin_group + + def end_group kind + if @opened.pop + @color_scopes.pop + @out << "\e[0m" + if outer_color = @color_scopes.last[:self] + @out << outer_color + end + end + end + + def end_line kind + @out << (@line_filler ||= "\t" * 100) + end_group kind + end + + private + + def open_token kind + if color = @color_scopes.last[kind] + if color.is_a? Hash + @color_scopes << color + color[:self] + else + @color_scopes << @color_scopes.last + color + end + else + @color_scopes << @color_scopes.last + '' + end + end + end + end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/text.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/text.rb new file mode 100644 index 0000000..15c66f9 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/text.rb @@ -0,0 +1,46 @@ +module CodeRay +module Encoders + + # Concats the tokens into a single string, resulting in the original + # code string if no tokens were removed. + # + # Alias: +plain+, +plaintext+ + # + # == Options + # + # === :separator + # A separator string to join the tokens. + # + # Default: empty String + class Text < Encoder + + register_for :text + + FILE_EXTENSION = 'txt' + + DEFAULT_OPTIONS = { + :separator => nil + } + + def text_token text, kind + super + + if @first + @first = false + else + @out << @sep + end if @sep + end + + protected + def setup options + super + + @first = true + @sep = options[:separator] + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/token_kind_filter.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/token_kind_filter.rb new file mode 100644 index 0000000..4773ea3 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/token_kind_filter.rb @@ -0,0 +1,111 @@ +module CodeRay +module Encoders + + load :filter + + # A Filter that selects tokens based on their token kind. + # + # == Options + # + # === :exclude + # + # One or many symbols (in an Array) which shall be excluded. + # + # Default: [] + # + # === :include + # + # One or many symbols (in an array) which shall be included. + # + # Default: :all, which means all tokens are included. + # + # Exclusion wins over inclusion. + # + # See also: CommentFilter + class TokenKindFilter < Filter + + register_for :token_kind_filter + + DEFAULT_OPTIONS = { + :exclude => [], + :include => :all + } + + protected + def setup options + super + + @group_excluded = false + @exclude = options[:exclude] + @exclude = Array(@exclude) unless @exclude == :all + @include = options[:include] + @include = Array(@include) unless @include == :all + end + + def include_text_token? text, kind + include_group? kind + end + + def include_group? kind + (@include == :all || @include.include?(kind)) && + !(@exclude == :all || @exclude.include?(kind)) + end + + public + + # Add the token to the output stream if +kind+ matches the conditions. + def text_token text, kind + super if !@group_excluded && include_text_token?(text, kind) + end + + # Add the token group to the output stream if +kind+ matches the + # conditions. + # + # If it does not, all tokens inside the group are excluded from the + # stream, even if their kinds match. + def begin_group kind + if @group_excluded + @group_excluded += 1 + elsif include_group? kind + super + else + @group_excluded = 1 + end + end + + # See +begin_group+. + def begin_line kind + if @group_excluded + @group_excluded += 1 + elsif include_group? kind + super + else + @group_excluded = 1 + end + end + + # Take care of re-enabling the delegation of tokens to the output stream + # if an exluded group has ended. + def end_group kind + if @group_excluded + @group_excluded -= 1 + @group_excluded = false if @group_excluded.zero? + else + super + end + end + + # See +end_group+. + def end_line kind + if @group_excluded + @group_excluded -= 1 + @group_excluded = false if @group_excluded.zero? + else + super + end + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/xml.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/xml.rb new file mode 100644 index 0000000..3d306a6 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/xml.rb @@ -0,0 +1,72 @@ +module CodeRay +module Encoders + + # = XML Encoder + # + # Uses REXML. Very slow. + class XML < Encoder + + register_for :xml + + FILE_EXTENSION = 'xml' + + autoload :REXML, 'rexml/document' + + DEFAULT_OPTIONS = { + :tab_width => 8, + :pretty => -1, + :transitive => false, + } + + protected + def setup options + super + + @doc = REXML::Document.new + @doc << REXML::XMLDecl.new + @tab_width = options[:tab_width] + @root = @node = @doc.add_element('coderay-tokens') + end + + def finish options + @doc.write @out, options[:pretty], options[:transitive], true + + super + end + + public + def text_token text, kind + if kind == :space + token = @node + else + token = @node.add_element kind.to_s + end + text.scan(/(\x20+)|(\t+)|(\n)|[^\x20\t\n]+/) do |space, tab, nl| + case + when space + token << REXML::Text.new(space, true) + when tab + token << REXML::Text.new(tab, true) + when nl + token << REXML::Text.new(nl, true) + else + token << REXML::Text.new($&) + end + end + end + + def begin_group kind + @node = @node.add_element kind.to_s + end + + def end_group kind + if @node == @root + raise 'no token to close!' + end + @node = @node.parent + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/yaml.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/yaml.rb new file mode 100644 index 0000000..ba6e715 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/yaml.rb @@ -0,0 +1,50 @@ +autoload :YAML, 'yaml' + +module CodeRay +module Encoders + + # = YAML Encoder + # + # Slow. + class YAML < Encoder + + register_for :yaml + + FILE_EXTENSION = 'yaml' + + protected + def setup options + super + + @data = [] + end + + def finish options + output ::YAML.dump(@data) + end + + public + def text_token text, kind + @data << [text, kind] + end + + def begin_group kind + @data << [:begin_group, kind] + end + + def end_group kind + @data << [:end_group, kind] + end + + def begin_line kind + @data << [:begin_line, kind] + end + + def end_line kind + @data << [:end_line, kind] + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/for_redcloth.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/for_redcloth.rb new file mode 100644 index 0000000..f9df32b --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/for_redcloth.rb @@ -0,0 +1,95 @@ +module CodeRay + + # A little hack to enable CodeRay highlighting in RedCloth. + # + # Usage: + # require 'coderay' + # require 'coderay/for_redcloth' + # RedCloth.new('@[ruby]puts "Hello, World!"@').to_html + # + # Make sure you have RedCloth 4.0.3 activated, for example by calling + # require 'rubygems' + # before RedCloth is loaded and before calling CodeRay.for_redcloth. + module ForRedCloth + + def self.install + gem 'RedCloth', '>= 4.0.3' if defined? gem + require 'redcloth' + unless RedCloth::VERSION.to_s >= '4.0.3' + if defined? gem + raise 'CodeRay.for_redcloth needs RedCloth version 4.0.3 or later. ' + + "You have #{RedCloth::VERSION}. Please gem install RedCloth." + else + $".delete 'redcloth.rb' # sorry, but it works + require 'rubygems' + return install # retry + end + end + unless RedCloth::VERSION.to_s >= '4.2.2' + warn 'CodeRay.for_redcloth works best with RedCloth version 4.2.2 or later.' + end + RedCloth::TextileDoc.send :include, ForRedCloth::TextileDoc + RedCloth::Formatters::HTML.module_eval do + def unescape(html) # :nodoc: + replacements = { + '&' => '&', + '"' => '"', + '>' => '>', + '<' => '<', + } + html.gsub(/&(?:amp|quot|[gl]t);/) { |entity| replacements[entity] } + end + undef code, bc_open, bc_close, escape_pre + def code(opts) # :nodoc: + opts[:block] = true + if !opts[:lang] && RedCloth::VERSION.to_s >= '4.2.0' + # simulating pre-4.2 behavior + if opts[:text].sub!(/\A\[(\w+)\]/, '') + if CodeRay::Scanners[$1].lang == :text + opts[:text] = $& + opts[:text] + else + opts[:lang] = $1 + end + end + end + if opts[:lang] && !filter_coderay + require 'coderay' + @in_bc ||= nil + format = @in_bc ? :div : :span + opts[:text] = unescape(opts[:text]) unless @in_bc + highlighted_code = CodeRay.encode opts[:text], opts[:lang], format + highlighted_code.sub!(/\A<(span|div)/) { |m| m + pba(@in_bc || opts) } + highlighted_code + else + "#{opts[:text]}" + end + end + def bc_open(opts) # :nodoc: + opts[:block] = true + @in_bc = opts + opts[:lang] ? '' : "" + end + def bc_close(opts) # :nodoc: + opts = @in_bc + @in_bc = nil + opts[:lang] ? '' : "\n" + end + def escape_pre(text) # :nodoc: + if @in_bc ||= nil + text + else + html_esc(text, :html_escape_preformatted) + end + end + end + end + + module TextileDoc # :nodoc: + attr_accessor :filter_coderay + end + + end + +end + +CodeRay::ForRedCloth.install \ No newline at end of file diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/file_type.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/file_type.rb new file mode 100644 index 0000000..7de34d5 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/file_type.rb @@ -0,0 +1,151 @@ +module CodeRay + + # = FileType + # + # A simple filetype recognizer. + # + # == Usage + # + # # determine the type of the given + # lang = FileType[file_name] + # + # # return :text if the file type is unknown + # lang = FileType.fetch file_name, :text + # + # # try the shebang line, too + # lang = FileType.fetch file_name, :text, true + module FileType + + UnknownFileType = Class.new Exception + + class << self + + # Try to determine the file type of the file. + # + # +filename+ is a relative or absolute path to a file. + # + # The file itself is only accessed when +read_shebang+ is set to true. + # That means you can get filetypes from files that don't exist. + def [] filename, read_shebang = false + name = File.basename filename + ext = File.extname(name).sub(/^\./, '') # from last dot, delete the leading dot + ext2 = filename.to_s[/\.(.*)/, 1] # from first dot + + type = + TypeFromExt[ext] || + TypeFromExt[ext.downcase] || + (TypeFromExt[ext2] if ext2) || + (TypeFromExt[ext2.downcase] if ext2) || + TypeFromName[name] || + TypeFromName[name.downcase] + type ||= type_from_shebang(filename) if read_shebang + + type + end + + # This works like Hash#fetch. + # + # If the filetype cannot be found, the +default+ value + # is returned. + def fetch filename, default = nil, read_shebang = false + if default && block_given? + warn 'Block supersedes default value argument; use either.' + end + + if type = self[filename, read_shebang] + type + else + return yield if block_given? + return default if default + raise UnknownFileType, 'Could not determine type of %p.' % filename + end + end + + protected + + def type_from_shebang filename + return unless File.exist? filename + File.open filename, 'r' do |f| + if first_line = f.gets + if type = first_line[TypeFromShebang] + type.to_sym + end + end + end + end + + end + + TypeFromExt = { + 'c' => :c, + 'cfc' => :xml, + 'cfm' => :xml, + 'clj' => :clojure, + 'css' => :css, + 'diff' => :diff, + 'dpr' => :delphi, + 'erb' => :erb, + 'gemspec' => :ruby, + 'go' => :go, + 'groovy' => :groovy, + 'gvy' => :groovy, + 'h' => :c, + 'haml' => :haml, + 'htm' => :html, + 'html' => :html, + 'html.erb' => :erb, + 'java' => :java, + 'js' => :java_script, + 'json' => :json, + 'lua' => :lua, + 'mab' => :ruby, + 'pas' => :delphi, + 'patch' => :diff, + 'phtml' => :php, + 'php' => :php, + 'php3' => :php, + 'php4' => :php, + 'php5' => :php, + 'prawn' => :ruby, + 'py' => :python, + 'py3' => :python, + 'pyw' => :python, + 'rake' => :ruby, + 'raydebug' => :raydebug, + 'rb' => :ruby, + 'rbw' => :ruby, + 'rhtml' => :erb, + 'rjs' => :ruby, + 'rpdf' => :ruby, + 'ru' => :ruby, # config.ru + 'rxml' => :ruby, + 'sass' => :sass, + 'sql' => :sql, + 'taskpaper' => :taskpaper, + 'template' => :json, # AWS CloudFormation template + 'tmproj' => :xml, + 'xaml' => :xml, + 'xhtml' => :html, + 'xml' => :xml, + 'yaml' => :yaml, + 'yml' => :yaml, + } + for cpp_alias in %w[cc cpp cp cxx c++ C hh hpp h++ cu] + TypeFromExt[cpp_alias] = :cpp + end + + TypeFromShebang = /\b(?:ruby|perl|python|sh)\b/ + + TypeFromName = { + 'Capfile' => :ruby, + 'Rakefile' => :ruby, + 'Rantfile' => :ruby, + 'Gemfile' => :ruby, + 'Guardfile' => :ruby, + 'Vagrantfile' => :ruby, + 'Appraisals' => :ruby + } + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/plugin.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/plugin.rb new file mode 100644 index 0000000..9a724ff --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/plugin.rb @@ -0,0 +1,274 @@ +module CodeRay + + # = PluginHost + # + # A simple subclass/subfolder plugin system. + # + # Example: + # class Generators + # extend PluginHost + # plugin_path 'app/generators' + # end + # + # class Generator + # extend Plugin + # PLUGIN_HOST = Generators + # end + # + # class FancyGenerator < Generator + # register_for :fancy + # end + # + # Generators[:fancy] #-> FancyGenerator + # # or + # CodeRay.require_plugin 'Generators/fancy' + # # or + # Generators::Fancy + module PluginHost + + # Raised if Encoders::[] fails because: + # * a file could not be found + # * the requested Plugin is not registered + PluginNotFound = Class.new LoadError + HostNotFound = Class.new LoadError + + PLUGIN_HOSTS = [] + PLUGIN_HOSTS_BY_ID = {} # dummy hash + + # Loads all plugins using list and load. + def load_all + for plugin in list + load plugin + end + end + + # Returns the Plugin for +id+. + # + # Example: + # yaml_plugin = MyPluginHost[:yaml] + def [] id, *args, &blk + plugin = validate_id(id) + begin + plugin = plugin_hash.[](plugin, *args, &blk) + end while plugin.is_a? String + plugin + end + + alias load [] + + # Tries to +load+ the missing plugin by translating +const+ to the + # underscore form (eg. LinesOfCode becomes lines_of_code). + def const_missing const + id = const.to_s. + gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). + gsub(/([a-z\d])([A-Z])/,'\1_\2'). + downcase + load id + end + + class << self + + # Adds the module/class to the PLUGIN_HOSTS list. + def extended mod + PLUGIN_HOSTS << mod + end + + end + + # The path where the plugins can be found. + def plugin_path *args + unless args.empty? + @plugin_path = File.expand_path File.join(*args) + end + @plugin_path ||= '' + end + + # Map a plugin_id to another. + # + # Usage: Put this in a file plugin_path/_map.rb. + # + # class MyColorHost < PluginHost + # map :navy => :dark_blue, + # :maroon => :brown, + # :luna => :moon + # end + def map hash + for from, to in hash + from = validate_id from + to = validate_id to + plugin_hash[from] = to unless plugin_hash.has_key? from + end + end + + # Define the default plugin to use when no plugin is found + # for a given id, or return the default plugin. + # + # See also map. + # + # class MyColorHost < PluginHost + # map :navy => :dark_blue + # default :gray + # end + # + # MyColorHost.default # loads and returns the Gray plugin + def default id = nil + if id + id = validate_id id + raise "The default plugin can't be named \"default\"." if id == :default + plugin_hash[:default] = id + else + load :default + end + end + + # Every plugin must register itself for +id+ by calling register_for, + # which calls this method. + # + # See Plugin#register_for. + def register plugin, id + plugin_hash[validate_id(id)] = plugin + end + + # A Hash of plugion_id => Plugin pairs. + def plugin_hash + @plugin_hash ||= (@plugin_hash = make_plugin_hash).tap { load_plugin_map } + end + + # Returns an array of all .rb files in the plugin path. + # + # The extension .rb is not included. + def list + Dir[path_to('*')].select do |file| + File.basename(file)[/^(?!_)\w+\.rb$/] + end.map do |file| + File.basename(file, '.rb').to_sym + end + end + + # Returns an array of all Plugins. + # + # Note: This loads all plugins using load_all. + def all_plugins + load_all + plugin_hash.values.grep(Class) + end + + # Loads the map file (see map). + # + # This is done automatically when plugin_path is called. + def load_plugin_map + mapfile = path_to '_map' + if File.exist? mapfile + require mapfile + true + else + false + end + end + + protected + + # Return a plugin hash that automatically loads plugins. + def make_plugin_hash + Hash.new do |h, plugin_id| + id = validate_id(plugin_id) + path = path_to id + begin + require path + rescue LoadError => boom + if h.has_key?(:default) + h[:default] + else + raise PluginNotFound, '%p could not load plugin %p: %s' % [self, id, boom] + end + else + # Plugin should have registered by now + if h.has_key? id + h[id] + else + raise PluginNotFound, "No #{self.name} plugin for #{id.inspect} found in #{path}." + end + end + end + end + + # Returns the expected path to the plugin file for the given id. + def path_to plugin_id + File.join plugin_path, "#{plugin_id}.rb" + end + + # Converts +id+ to a valid plugin ID String, or returns +nil+. + # + # Raises +ArgumentError+ for all other objects, or if the + # given String includes non-alphanumeric characters (\W). + def validate_id id + case id + when Symbol + id.to_s + when String + if id[/\w+/] == id + id.downcase + else + raise ArgumentError, "Invalid id given: #{id}" + end + else + raise ArgumentError, "Symbol or String expected, but #{id.class} given." + end + end + + end + + + # = Plugin + # + # Plugins have to include this module. + # + # IMPORTANT: Use extend for this module. + # + # See CodeRay::PluginHost for examples. + module Plugin + + attr_reader :plugin_id + + # Register this class for the given +id+. + # + # Example: + # class MyPlugin < PluginHost::BaseClass + # register_for :my_id + # ... + # end + # + # See PluginHost.register. + def register_for id + @plugin_id = id + plugin_host.register self, id + end + + # Returns the title of the plugin, or sets it to the + # optional argument +title+. + def title title = nil + if title + @title = title.to_s + else + @title ||= name[/([^:]+)$/, 1] + end + end + + # The PluginHost for this Plugin class. + def plugin_host host = nil + if host.is_a? PluginHost + const_set :PLUGIN_HOST, host + end + self::PLUGIN_HOST + end + + def aliases + plugin_host.plugin_hash.inject [] do |aliases, (key, _)| + aliases << key if plugin_host[key] == self + aliases + end + end + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/word_list.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/word_list.rb new file mode 100644 index 0000000..4a42c4a --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/word_list.rb @@ -0,0 +1,72 @@ +module CodeRay + + # = WordList + # + # A Hash subclass designed for mapping word lists to token types. + # + # A WordList is a Hash with some additional features. + # It is intended to be used for keyword recognition. + # + # WordList is optimized to be used in Scanners, + # typically to decide whether a given ident is a special token. + # + # For case insensitive words use WordList::CaseIgnoring. + # + # Example: + # + # # define word arrays + # RESERVED_WORDS = %w[ + # asm break case continue default do else + # ] + # + # PREDEFINED_TYPES = %w[ + # int long short char void + # ] + # + # # make a WordList + # IDENT_KIND = WordList.new(:ident). + # add(RESERVED_WORDS, :reserved). + # add(PREDEFINED_TYPES, :predefined_type) + # + # ... + # + # def scan_tokens tokens, options + # ... + # + # elsif scan(/[A-Za-z_][A-Za-z_0-9]*/) + # # use it + # kind = IDENT_KIND[match] + # ... + class WordList < Hash + + # Create a new WordList with +default+ as default value. + def initialize default = false + super default + end + + # Add words to the list and associate them with +value+. + # + # Returns +self+, so you can concat add calls. + def add words, value = true + words.each { |word| self[word] = value } + self + end + + end + + + # A CaseIgnoring WordList is like a WordList, only that + # keys are compared case-insensitively (normalizing keys using +downcase+). + class WordList::CaseIgnoring < WordList + + def [] key + super key.downcase + end + + def []= key, value + super key.downcase, value + end + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanner.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanner.rb new file mode 100644 index 0000000..b3f7e17 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanner.rb @@ -0,0 +1,355 @@ +# encoding: utf-8 +require 'strscan' + +module CodeRay + + autoload :WordList, coderay_path('helpers', 'word_list') + + # = Scanners + # + # This module holds the Scanner class and its subclasses. + # For example, the Ruby scanner is named CodeRay::Scanners::Ruby + # can be found in coderay/scanners/ruby. + # + # Scanner also provides methods and constants for the register + # mechanism and the [] method that returns the Scanner class + # belonging to the given lang. + # + # See PluginHost. + module Scanners + extend PluginHost + plugin_path File.dirname(__FILE__), 'scanners' + + + # = Scanner + # + # The base class for all Scanners. + # + # It is a subclass of Ruby's great +StringScanner+, which + # makes it easy to access the scanning methods inside. + # + # It is also +Enumerable+, so you can use it like an Array of + # Tokens: + # + # require 'coderay' + # + # c_scanner = CodeRay::Scanners[:c].new "if (*p == '{') nest++;" + # + # for text, kind in c_scanner + # puts text if kind == :operator + # end + # + # # prints: (*==)++; + # + # OK, this is a very simple example :) + # You can also use +map+, +any?+, +find+ and even +sort_by+, + # if you want. + class Scanner < StringScanner + + extend Plugin + plugin_host Scanners + + # Raised if a Scanner fails while scanning + ScanError = Class.new StandardError + + # The default options for all scanner classes. + # + # Define @default_options for subclasses. + DEFAULT_OPTIONS = { } + + KINDS_NOT_LOC = [:comment, :doctype, :docstring] + + attr_accessor :state + + class << self + + # Normalizes the given code into a string with UNIX newlines, in the + # scanner's internal encoding, with invalid and undefined charachters + # replaced by placeholders. Always returns a new object. + def normalize code + # original = code + code = code.to_s unless code.is_a? ::String + return code if code.empty? + + if code.respond_to? :encoding + code = encode_with_encoding code, self.encoding + else + code = to_unix code + end + # code = code.dup if code.eql? original + code + end + + # The typical filename suffix for this scanner's language. + def file_extension extension = lang + @file_extension ||= extension.to_s + end + + # The encoding used internally by this scanner. + def encoding name = 'UTF-8' + @encoding ||= defined?(Encoding.find) && Encoding.find(name) + end + + # The lang of this Scanner class, which is equal to its Plugin ID. + def lang + @plugin_id + end + + protected + + def encode_with_encoding code, target_encoding + if code.encoding == target_encoding + if code.valid_encoding? + return to_unix(code) + else + source_encoding = guess_encoding code + end + else + source_encoding = code.encoding + end + # print "encode_with_encoding from #{source_encoding} to #{target_encoding}" + code.encode target_encoding, source_encoding, :universal_newline => true, :undef => :replace, :invalid => :replace + end + + def to_unix code + code.index(?\r) ? code.gsub(/\r\n?/, "\n") : code + end + + def guess_encoding s + #:nocov: + IO.popen("file -b --mime -", "w+") do |file| + file.write s[0, 1024] + file.close_write + begin + Encoding.find file.gets[/charset=([-\w]+)/, 1] + rescue ArgumentError + Encoding::BINARY + end + end + #:nocov: + end + + end + + # Create a new Scanner. + # + # * +code+ is the input String and is handled by the superclass + # StringScanner. + # * +options+ is a Hash with Symbols as keys. + # It is merged with the default options of the class (you can + # overwrite default options here.) + # + # Else, a Tokens object is used. + def initialize code = '', options = {} + if self.class == Scanner + raise NotImplementedError, "I am only the basic Scanner class. I can't scan anything. :( Use my subclasses." + end + + @options = self.class::DEFAULT_OPTIONS.merge options + + super self.class.normalize(code) + + @tokens = options[:tokens] || Tokens.new + @tokens.scanner = self if @tokens.respond_to? :scanner= + + setup + end + + # Sets back the scanner. Subclasses should redefine the reset_instance + # method instead of this one. + def reset + super + reset_instance + end + + # Set a new string to be scanned. + def string= code + code = self.class.normalize(code) + super code + reset_instance + end + + # the Plugin ID for this scanner + def lang + self.class.lang + end + + # the default file extension for this scanner + def file_extension + self.class.file_extension + end + + # Scan the code and returns all tokens in a Tokens object. + def tokenize source = nil, options = {} + options = @options.merge(options) + + set_tokens_from_options options + set_string_from_source source + + begin + scan_tokens @tokens, options + rescue => e + message = "Error in %s#scan_tokens, initial state was: %p" % [self.class, defined?(state) && state] + raise_inspect e.message, @tokens, message, 30, e.backtrace + end + + @cached_tokens = @tokens + if source.is_a? Array + @tokens.split_into_parts(*source.map { |part| part.size }) + else + @tokens + end + end + + # Cache the result of tokenize. + def tokens + @cached_tokens ||= tokenize + end + + # Traverse the tokens. + def each &block + tokens.each(&block) + end + include Enumerable + + # The current line position of the scanner, starting with 1. + # See also: #column. + # + # Beware, this is implemented inefficiently. It should be used + # for debugging only. + def line pos = self.pos + return 1 if pos <= 0 + binary_string[0...pos].count("\n") + 1 + end + + # The current column position of the scanner, starting with 1. + # See also: #line. + def column pos = self.pos + return 1 if pos <= 0 + pos - (binary_string.rindex(?\n, pos - 1) || -1) + end + + # The string in binary encoding. + # + # To be used with #pos, which is the index of the byte the scanner + # will scan next. + def binary_string + @binary_string ||= + if string.respond_to?(:bytesize) && string.bytesize != string.size + #:nocov: + string.dup.force_encoding('binary') + #:nocov: + else + string + end + end + + protected + + # Can be implemented by subclasses to do some initialization + # that has to be done once per instance. + # + # Use reset for initialization that has to be done once per + # scan. + def setup # :doc: + end + + def set_string_from_source source + case source + when Array + self.string = self.class.normalize(source.join) + when nil + reset + else + self.string = self.class.normalize(source) + end + end + + def set_tokens_from_options options + @tokens = options[:tokens] || @tokens || Tokens.new + @tokens.scanner = self if @tokens.respond_to? :scanner= + end + + # This is the central method, and commonly the only one a + # subclass implements. + # + # Subclasses must implement this method; it must return +tokens+ + # and must only use Tokens#<< for storing scanned tokens! + def scan_tokens tokens, options # :doc: + raise NotImplementedError, "#{self.class}#scan_tokens not implemented." + end + + # Resets the scanner. + def reset_instance + @tokens.clear if @tokens.respond_to?(:clear) && !@options[:keep_tokens] + @cached_tokens = nil + @binary_string = nil if defined? @binary_string + end + + SCAN_ERROR_MESSAGE = <<-MESSAGE + + +***ERROR in %s: %s (after %s tokens) + +tokens: +%s + +%s + +surrounding code: +%p ~~ %p + + +***ERROR*** + + MESSAGE + + def raise_inspect_arguments message, tokens, state, ambit + return File.basename(caller[0]), + message, + tokens_size(tokens), + tokens_last(tokens, 10).map(&:inspect).join("\n"), + scanner_state_info(state), + binary_string[pos - ambit, ambit], + binary_string[pos, ambit] + end + + SCANNER_STATE_INFO = <<-INFO +current line: %d column: %d pos: %d +matched: %p state: %p +bol?: %p, eos?: %p + INFO + + def scanner_state_info state + SCANNER_STATE_INFO % [ + line, column, pos, + matched, state || 'No state given!', + bol?, eos?, + ] + end + + # Scanner error with additional status information + def raise_inspect message, tokens, state = self.state, ambit = 30, backtrace = caller + raise ScanError, SCAN_ERROR_MESSAGE % raise_inspect_arguments(message, tokens, state, ambit), backtrace + end + + def tokens_size tokens + tokens.size if tokens.respond_to?(:size) + end + + def tokens_last tokens, n + tokens.respond_to?(:last) ? tokens.last(n) : [] + end + + # Shorthand for scan_until(/\z/). + # This method also avoids a JRuby 1.9 mode bug. + def scan_rest + rest = self.rest + terminate + rest + end + + end + + end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/_map.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/_map.rb new file mode 100644 index 0000000..a240298 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/_map.rb @@ -0,0 +1,24 @@ +module CodeRay +module Scanners + + map \ + :'c++' => :cpp, + :cplusplus => :cpp, + :ecmascript => :java_script, + :ecma_script => :java_script, + :rhtml => :erb, + :eruby => :erb, + :irb => :ruby, + :javascript => :java_script, + :js => :java_script, + :pascal => :delphi, + :patch => :diff, + :plain => :text, + :plaintext => :text, + :xhtml => :html, + :yml => :yaml + + default :text + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/c.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/c.rb new file mode 100644 index 0000000..84b6e8e --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/c.rb @@ -0,0 +1,189 @@ +module CodeRay +module Scanners + + # Scanner for C. + class C < Scanner + + register_for :c + file_extension 'c' + + KEYWORDS = [ + 'asm', 'break', 'case', 'continue', 'default', 'do', + 'else', 'enum', 'for', 'goto', 'if', 'return', + 'sizeof', 'struct', 'switch', 'typedef', 'union', 'while', + 'restrict', # added in C99 + ] # :nodoc: + + PREDEFINED_TYPES = [ + 'int', 'long', 'short', 'char', + 'signed', 'unsigned', 'float', 'double', + 'bool', 'complex', # added in C99 + ] # :nodoc: + + PREDEFINED_CONSTANTS = [ + 'EOF', 'NULL', + 'true', 'false', # added in C99 + ] # :nodoc: + DIRECTIVES = [ + 'auto', 'extern', 'register', 'static', 'void', + 'const', 'volatile', # added in C89 + 'inline', # added in C99 + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(PREDEFINED_TYPES, :predefined_type). + add(DIRECTIVES, :directive). + add(PREDEFINED_CONSTANTS, :predefined_constant) # :nodoc: + + ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: + + protected + + def scan_tokens encoder, options + + state = :initial + label_expected = true + case_expected = false + label_expected_before_preproc_line = nil + in_preproc_line = false + + until eos? + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + if in_preproc_line && match != "\\\n" && match.index(?\n) + in_preproc_line = false + label_expected = label_expected_before_preproc_line + end + encoder.text_token match, :space + + elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) + encoder.text_token match, :comment + + elsif match = scan(/ [-+*=<>?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x) + label_expected = match =~ /[;\{\}]/ + if case_expected + label_expected = true if match == ':' + case_expected = false + end + encoder.text_token match, :operator + + elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) + kind = IDENT_KIND[match] + if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/) + kind = :label + match << matched + else + label_expected = false + if kind == :keyword + case match + when 'case', 'default' + case_expected = true + end + end + end + encoder.text_token match, kind + + elsif match = scan(/L?"/) + encoder.begin_group :string + if match[0] == ?L + encoder.text_token 'L', :modifier + match = '"' + end + encoder.text_token match, :delimiter + state = :string + + elsif match = scan(/ \# \s* if \s* 0 /x) + match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos? + encoder.text_token match, :comment + + elsif match = scan(/#[ \t]*(\w*)/) + encoder.text_token match, :preprocessor + in_preproc_line = true + label_expected_before_preproc_line = label_expected + state = :include_expected if self[1] == 'include' + + elsif match = scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox) + label_expected = false + encoder.text_token match, :char + + elsif match = scan(/\$/) + encoder.text_token match, :ident + + elsif match = scan(/0[xX][0-9A-Fa-f]+/) + label_expected = false + encoder.text_token match, :hex + + elsif match = scan(/(?:0[0-7]+)(?![89.eEfF])/) + label_expected = false + encoder.text_token match, :octal + + elsif match = scan(/(?:\d+)(?![.eEfF])L?L?/) + label_expected = false + encoder.text_token match, :integer + + elsif match = scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/) + label_expected = false + encoder.text_token match, :float + + else + encoder.text_token getch, :error + + end + + when :string + if match = scan(/[^\\\n"]+/) + encoder.text_token match, :content + elsif match = scan(/"/) + encoder.text_token match, :delimiter + encoder.end_group :string + state = :initial + label_expected = false + elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + encoder.text_token match, :char + elsif match = scan(/ \\ | $ /x) + encoder.end_group :string + encoder.text_token match, :error unless match.empty? + state = :initial + label_expected = false + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder + end + + when :include_expected + if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/) + encoder.text_token match, :include + state = :initial + + elsif match = scan(/\s+/) + encoder.text_token match, :space + state = :initial if match.index ?\n + + else + state = :initial + + end + + else + raise_inspect 'Unknown state', encoder + + end + + end + + if state == :string + encoder.end_group :string + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/clojure.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/clojure.rb new file mode 100644 index 0000000..f8fbf65 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/clojure.rb @@ -0,0 +1,217 @@ +# encoding: utf-8 +module CodeRay + module Scanners + + # Clojure scanner by Licenser. + class Clojure < Scanner + + register_for :clojure + file_extension 'clj' + + SPECIAL_FORMS = %w[ + def if do let quote var fn loop recur throw try catch monitor-enter monitor-exit . + new + ] # :nodoc: + + CORE_FORMS = %w[ + + - -> ->> .. / * <= < = == >= > accessor aclone add-classpath add-watch + agent agent-error agent-errors aget alength alias all-ns alter alter-meta! + alter-var-root amap ancestors and apply areduce array-map aset aset-boolean + aset-byte aset-char aset-double aset-float aset-int aset-long aset-short + assert assoc assoc! assoc-in associative? atom await await-for bases bean + bigdec bigint binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or + bit-set bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array + booleans bound-fn bound-fn* bound? butlast byte byte-array bytes case cast char + char-array char-escape-string char-name-string char? chars class class? + clear-agent-errors clojure-version coll? comment commute comp comparator + compare compare-and-set! compile complement concat cond condp conj conj! + cons constantly construct-proxy contains? count counted? create-ns + create-struct cycle dec decimal? declare definline defmacro defmethod defmulti + defn defn- defonce defprotocol defrecord defstruct deftype delay delay? + deliver denominator deref derive descendants disj disj! dissoc dissoc! + distinct distinct? doall doc dorun doseq dosync dotimes doto double + double-array doubles drop drop-last drop-while empty empty? ensure + enumeration-seq error-handler error-mode eval even? every? extend + extend-protocol extend-type extenders extends? false? ffirst file-seq + filter find find-doc find-ns find-var first float float-array float? + floats flush fn fn? fnext for force format future future-call future-cancel + future-cancelled? future-done? future? gen-class gen-interface gensym get + get-in get-method get-proxy-class get-thread-bindings get-validator hash + hash-map hash-set identical? identity if-let if-not ifn? import in-ns + inc init-proxy instance? int int-array integer? interleave intern + interpose into into-array ints io! isa? iterate iterator-seq juxt key + keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* + list? load load-file load-reader load-string loaded-libs locking long + long-array longs loop macroexpand macroexpand-1 make-array make-hierarchy + map map? mapcat max max-key memfn memoize merge merge-with meta methods + min min-key mod name namespace neg? newline next nfirst nil? nnext not + not-any? not-empty not-every? not= ns ns-aliases ns-imports ns-interns + ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias ns-unmap nth + nthnext num number? numerator object-array odd? or parents partial + partition pcalls peek persistent! pmap pop pop! pop-thread-bindings + pos? pr pr-str prefer-method prefers print print-namespace-doc + print-str printf println println-str prn prn-str promise proxy + proxy-mappings proxy-super push-thread-bindings pvalues quot rand + rand-int range ratio? rationalize re-find re-groups re-matcher + re-matches re-pattern re-seq read read-line read-string reduce ref + ref-history-count ref-max-history ref-min-history ref-set refer + refer-clojure reify release-pending-sends rem remove remove-all-methods + remove-method remove-ns remove-watch repeat repeatedly replace replicate + require reset! reset-meta! resolve rest restart-agent resultset-seq + reverse reversible? rseq rsubseq satisfies? second select-keys send + send-off seq seq? seque sequence sequential? set set-error-handler! + set-error-mode! set-validator! set? short short-array shorts + shutdown-agents slurp some sort sort-by sorted-map sorted-map-by + sorted-set sorted-set-by sorted? special-form-anchor special-symbol? + split-at split-with str string? struct struct-map subs subseq subvec + supers swap! symbol symbol? sync syntax-symbol-anchor take take-last + take-nth take-while test the-ns thread-bound? time to-array to-array-2d + trampoline transient tree-seq true? type unchecked-add unchecked-dec + unchecked-divide unchecked-inc unchecked-multiply unchecked-negate + unchecked-remainder unchecked-subtract underive update-in update-proxy + use val vals var-get var-set var? vary-meta vec vector vector-of vector? + when when-first when-let when-not while with-bindings with-bindings* + with-in-str with-local-vars with-meta with-open with-out-str + with-precision xml-seq zero? zipmap + ] # :nodoc: + + PREDEFINED_CONSTANTS = %w[ + true false nil *1 *2 *3 *agent* *clojure-version* *command-line-args* + *compile-files* *compile-path* *e *err* *file* *flush-on-newline* + *in* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* + *print-readably* *read-eval* *warn-on-reflection* + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(SPECIAL_FORMS, :keyword). + add(CORE_FORMS, :keyword). + add(PREDEFINED_CONSTANTS, :predefined_constant) + + KEYWORD_NEXT_TOKEN_KIND = WordList.new(nil). + add(%w[ def defn defn- definline defmacro defmulti defmethod defstruct defonce declare ], :function). + add(%w[ ns ], :namespace). + add(%w[ defprotocol defrecord ], :class) + + BASIC_IDENTIFIER = /[a-zA-Z$%*\/_+!?&<>\-=]=?[a-zA-Z0-9$&*+!\/_?<>\-\#]*/ + IDENTIFIER = /(?!-\d)(?:(?:#{BASIC_IDENTIFIER}\.)*#{BASIC_IDENTIFIER}(?:\/#{BASIC_IDENTIFIER})?\.?)|\.\.?/ + SYMBOL = /::?#{IDENTIFIER}/o + DIGIT = /\d/ + DIGIT10 = DIGIT + DIGIT16 = /[0-9a-f]/i + DIGIT8 = /[0-7]/ + DIGIT2 = /[01]/ + RADIX16 = /\#x/i + RADIX8 = /\#o/i + RADIX2 = /\#b/i + RADIX10 = /\#d/i + EXACTNESS = /#i|#e/i + SIGN = /[\+-]?/ + EXP_MARK = /[esfdl]/i + EXP = /#{EXP_MARK}#{SIGN}#{DIGIT}+/ + SUFFIX = /#{EXP}?/ + PREFIX10 = /#{RADIX10}?#{EXACTNESS}?|#{EXACTNESS}?#{RADIX10}?/ + PREFIX16 = /#{RADIX16}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX16}/ + PREFIX8 = /#{RADIX8}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX8}/ + PREFIX2 = /#{RADIX2}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX2}/ + UINT10 = /#{DIGIT10}+#*/ + UINT16 = /#{DIGIT16}+#*/ + UINT8 = /#{DIGIT8}+#*/ + UINT2 = /#{DIGIT2}+#*/ + DECIMAL = /#{DIGIT10}+#+\.#*#{SUFFIX}|#{DIGIT10}+\.#{DIGIT10}*#*#{SUFFIX}|\.#{DIGIT10}+#*#{SUFFIX}|#{UINT10}#{EXP}/ + UREAL10 = /#{UINT10}\/#{UINT10}|#{DECIMAL}|#{UINT10}/ + UREAL16 = /#{UINT16}\/#{UINT16}|#{UINT16}/ + UREAL8 = /#{UINT8}\/#{UINT8}|#{UINT8}/ + UREAL2 = /#{UINT2}\/#{UINT2}|#{UINT2}/ + REAL10 = /#{SIGN}#{UREAL10}/ + REAL16 = /#{SIGN}#{UREAL16}/ + REAL8 = /#{SIGN}#{UREAL8}/ + REAL2 = /#{SIGN}#{UREAL2}/ + IMAG10 = /i|#{UREAL10}i/ + IMAG16 = /i|#{UREAL16}i/ + IMAG8 = /i|#{UREAL8}i/ + IMAG2 = /i|#{UREAL2}i/ + COMPLEX10 = /#{REAL10}@#{REAL10}|#{REAL10}\+#{IMAG10}|#{REAL10}-#{IMAG10}|\+#{IMAG10}|-#{IMAG10}|#{REAL10}/ + COMPLEX16 = /#{REAL16}@#{REAL16}|#{REAL16}\+#{IMAG16}|#{REAL16}-#{IMAG16}|\+#{IMAG16}|-#{IMAG16}|#{REAL16}/ + COMPLEX8 = /#{REAL8}@#{REAL8}|#{REAL8}\+#{IMAG8}|#{REAL8}-#{IMAG8}|\+#{IMAG8}|-#{IMAG8}|#{REAL8}/ + COMPLEX2 = /#{REAL2}@#{REAL2}|#{REAL2}\+#{IMAG2}|#{REAL2}-#{IMAG2}|\+#{IMAG2}|-#{IMAG2}|#{REAL2}/ + NUM10 = /#{PREFIX10}?#{COMPLEX10}/ + NUM16 = /#{PREFIX16}#{COMPLEX16}/ + NUM8 = /#{PREFIX8}#{COMPLEX8}/ + NUM2 = /#{PREFIX2}#{COMPLEX2}/ + NUM = /#{NUM10}|#{NUM16}|#{NUM8}|#{NUM2}/ + + protected + + def scan_tokens encoder, options + + state = :initial + kind = nil + + until eos? + + case state + when :initial + if match = scan(/ \s+ | \\\n | , /x) + encoder.text_token match, :space + elsif match = scan(/['`\(\[\)\]\{\}]|\#[({]|~@?|[@\^]/) + encoder.text_token match, :operator + elsif match = scan(/;.*/) + encoder.text_token match, :comment # TODO: recognize (comment ...) too + elsif match = scan(/\#?\\(?:newline|space|.?)/) + encoder.text_token match, :char + elsif match = scan(/\#[ft]/) + encoder.text_token match, :predefined_constant + elsif match = scan(/#{IDENTIFIER}/o) + kind = IDENT_KIND[match] + encoder.text_token match, kind + if rest? && kind == :keyword + if kind = KEYWORD_NEXT_TOKEN_KIND[match] + encoder.text_token match, :space if match = scan(/\s+/o) + encoder.text_token match, kind if match = scan(/#{IDENTIFIER}/o) + end + end + elsif match = scan(/#{SYMBOL}/o) + encoder.text_token match, :symbol + elsif match = scan(/\./) + encoder.text_token match, :operator + elsif match = scan(/ \# \^ #{IDENTIFIER} /ox) + encoder.text_token match, :type + elsif match = scan(/ (\#)? " /x) + state = self[1] ? :regexp : :string + encoder.begin_group state + encoder.text_token match, :delimiter + elsif match = scan(/#{NUM}/o) and not matched.empty? + encoder.text_token match, match[/[.e\/]/i] ? :float : :integer + else + encoder.text_token getch, :error + end + + when :string, :regexp + if match = scan(/[^"\\]+|\\.?/) + encoder.text_token match, :content + elsif match = scan(/"/) + encoder.text_token match, :delimiter + encoder.end_group state + state = :initial + else + raise_inspect "else case \" reached; %p not handled." % peek(1), + encoder, state + end + + else + raise 'else case reached' + + end + + end + + if [:string, :regexp].include? state + encoder.end_group state + end + + encoder + + end + end + end +end \ No newline at end of file diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/cpp.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/cpp.rb new file mode 100644 index 0000000..e61f56f --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/cpp.rb @@ -0,0 +1,215 @@ +module CodeRay +module Scanners + + # Scanner for C++. + # + # Aliases: +cplusplus+, c++ + class CPlusPlus < Scanner + + register_for :cpp + file_extension 'cpp' + title 'C++' + + #-- http://www.cppreference.com/wiki/keywords/start + KEYWORDS = [ + 'and', 'and_eq', 'asm', 'bitand', 'bitor', 'break', + 'case', 'catch', 'class', 'compl', 'const_cast', + 'continue', 'default', 'delete', 'do', 'dynamic_cast', 'else', + 'enum', 'export', 'for', 'goto', 'if', 'namespace', 'new', + 'not', 'not_eq', 'or', 'or_eq', 'reinterpret_cast', 'return', + 'sizeof', 'static_cast', 'struct', 'switch', 'template', + 'throw', 'try', 'typedef', 'typeid', 'typename', 'union', + 'while', 'xor', 'xor_eq', + ] # :nodoc: + + PREDEFINED_TYPES = [ + 'bool', 'char', 'double', 'float', 'int', 'long', + 'short', 'signed', 'unsigned', 'wchar_t', 'string', + ] # :nodoc: + PREDEFINED_CONSTANTS = [ + 'false', 'true', + 'EOF', 'NULL', + ] # :nodoc: + PREDEFINED_VARIABLES = [ + 'this', + ] # :nodoc: + DIRECTIVES = [ + 'auto', 'const', 'explicit', 'extern', 'friend', 'inline', 'mutable', 'operator', + 'private', 'protected', 'public', 'register', 'static', 'using', 'virtual', 'void', + 'volatile', + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(PREDEFINED_TYPES, :predefined_type). + add(PREDEFINED_VARIABLES, :local_variable). + add(DIRECTIVES, :directive). + add(PREDEFINED_CONSTANTS, :predefined_constant) # :nodoc: + + ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: + + protected + + def scan_tokens encoder, options + + state = :initial + label_expected = true + case_expected = false + label_expected_before_preproc_line = nil + in_preproc_line = false + + until eos? + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + if in_preproc_line && match != "\\\n" && match.index(?\n) + in_preproc_line = false + label_expected = label_expected_before_preproc_line + end + encoder.text_token match, :space + + elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) + encoder.text_token match, :comment + + elsif match = scan(/ \# \s* if \s* 0 /x) + match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos? + encoder.text_token match, :comment + + elsif match = scan(/ [-+*=<>?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x) + label_expected = match =~ /[;\{\}]/ + if case_expected + label_expected = true if match == ':' + case_expected = false + end + encoder.text_token match, :operator + + elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) + kind = IDENT_KIND[match] + if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/) + kind = :label + match << matched + else + label_expected = false + if kind == :keyword + case match + when 'class' + state = :class_name_expected + when 'case', 'default' + case_expected = true + end + end + end + encoder.text_token match, kind + + elsif match = scan(/\$/) + encoder.text_token match, :ident + + elsif match = scan(/L?"/) + encoder.begin_group :string + if match[0] == ?L + encoder.text_token match, 'L', :modifier + match = '"' + end + state = :string + encoder.text_token match, :delimiter + + elsif match = scan(/#[ \t]*(\w*)/) + encoder.text_token match, :preprocessor + in_preproc_line = true + label_expected_before_preproc_line = label_expected + state = :include_expected if self[1] == 'include' + + elsif match = scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox) + label_expected = false + encoder.text_token match, :char + + elsif match = scan(/0[xX][0-9A-Fa-f]+/) + label_expected = false + encoder.text_token match, :hex + + elsif match = scan(/(?:0[0-7]+)(?![89.eEfF])/) + label_expected = false + encoder.text_token match, :octal + + elsif match = scan(/(?:\d+)(?![.eEfF])L?L?/) + label_expected = false + encoder.text_token match, :integer + + elsif match = scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/) + label_expected = false + encoder.text_token match, :float + + else + encoder.text_token getch, :error + + end + + when :string + if match = scan(/[^\\"]+/) + encoder.text_token match, :content + elsif match = scan(/"/) + encoder.text_token match, :delimiter + encoder.end_group :string + state = :initial + label_expected = false + elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + encoder.text_token match, :char + elsif match = scan(/ \\ | $ /x) + encoder.end_group :string + encoder.text_token match, :error unless match.empty? + state = :initial + label_expected = false + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder + end + + when :include_expected + if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/) + encoder.text_token match, :include + state = :initial + + elsif match = scan(/\s+/) + encoder.text_token match, :space + state = :initial if match.index ?\n + + else + state = :initial + + end + + when :class_name_expected + if match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) + encoder.text_token match, :class + state = :initial + + elsif match = scan(/\s+/) + encoder.text_token match, :space + + else + encoder.text_token getch, :error + state = :initial + + end + + else + raise_inspect 'Unknown state', encoder + + end + + end + + if state == :string + encoder.end_group :string + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/css.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/css.rb new file mode 100644 index 0000000..55d5239 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/css.rb @@ -0,0 +1,196 @@ +module CodeRay +module Scanners + + class CSS < Scanner + + register_for :css + + KINDS_NOT_LOC = [ + :comment, + :class, :pseudo_class, :tag, + :id, :directive, + :key, :value, :operator, :color, :float, :string, + :error, :important, :type, + ] # :nodoc: + + module RE # :nodoc: + Hex = /[0-9a-fA-F]/ + Unicode = /\\#{Hex}{1,6}\b/ # differs from standard because it allows uppercase hex too + Escape = /#{Unicode}|\\[^\n0-9a-fA-F]/ + NMChar = /[-_a-zA-Z0-9]/ + NMStart = /[_a-zA-Z]/ + String1 = /"(?:[^\n\\"]+|\\\n|#{Escape})*"?/ # TODO: buggy regexp + String2 = /'(?:[^\n\\']+|\\\n|#{Escape})*'?/ # TODO: buggy regexp + String = /#{String1}|#{String2}/ + + HexColor = /#(?:#{Hex}{6}|#{Hex}{3})/ + + Num = /-?(?:[0-9]*\.[0-9]+|[0-9]+)n?/ + Name = /#{NMChar}+/ + Ident = /-?#{NMStart}#{NMChar}*/ + AtKeyword = /@#{Ident}/ + Percentage = /#{Num}%/ + + reldimensions = %w[em ex px] + absdimensions = %w[in cm mm pt pc] + Unit = Regexp.union(*(reldimensions + absdimensions + %w[s dpi dppx deg])) + + Dimension = /#{Num}#{Unit}/ + + Function = /(?:url|alpha|attr|counters?)\((?:[^)\n]|\\\))*\)?/ + + Id = /(?!#{HexColor}\b(?!-))##{Name}/ + Class = /\.#{Name}/ + PseudoClass = /::?#{Ident}/ + AttributeSelector = /\[[^\]]*\]?/ + end + + protected + + def setup + @state = :initial + @value_expected = false + end + + def scan_tokens encoder, options + states = Array(options[:state] || @state).dup + value_expected = @value_expected + + until eos? + + if match = scan(/\s+/) + encoder.text_token match, :space + + elsif case states.last + when :initial, :media + if match = scan(/(?>#{RE::Ident})(?!\()|\*/ox) + encoder.text_token match, :tag + next + elsif match = scan(RE::Class) + encoder.text_token match, :class + next + elsif match = scan(RE::Id) + encoder.text_token match, :id + next + elsif match = scan(RE::PseudoClass) + encoder.text_token match, :pseudo_class + next + elsif match = scan(RE::AttributeSelector) + # TODO: Improve highlighting inside of attribute selectors. + encoder.text_token match[0,1], :operator + encoder.text_token match[1..-2], :attribute_name if match.size > 2 + encoder.text_token match[-1,1], :operator if match[-1] == ?] + next + elsif match = scan(/@media/) + encoder.text_token match, :directive + states.push :media_before_name + next + end + + when :block + if match = scan(/(?>#{RE::Ident})(?!\()/ox) + if value_expected + encoder.text_token match, :value + else + encoder.text_token match, :key + end + next + end + + when :media_before_name + if match = scan(RE::Ident) + encoder.text_token match, :type + states[-1] = :media_after_name + next + end + + when :media_after_name + if match = scan(/\{/) + encoder.text_token match, :operator + states[-1] = :media + next + end + + else + #:nocov: + raise_inspect 'Unknown state', encoder + #:nocov: + + end + + elsif match = scan(/\/\*(?:.*?\*\/|\z)/m) + encoder.text_token match, :comment + + elsif match = scan(/\{/) + value_expected = false + encoder.text_token match, :operator + states.push :block + + elsif match = scan(/\}/) + value_expected = false + encoder.text_token match, :operator + if states.last == :block || states.last == :media + states.pop + end + + elsif match = scan(/#{RE::String}/o) + encoder.begin_group :string + encoder.text_token match[0, 1], :delimiter + encoder.text_token match[1..-2], :content if match.size > 2 + encoder.text_token match[-1, 1], :delimiter if match.size >= 2 + encoder.end_group :string + + elsif match = scan(/#{RE::Function}/o) + encoder.begin_group :function + start = match[/^\w+\(/] + encoder.text_token start, :delimiter + if match[-1] == ?) + encoder.text_token match[start.size..-2], :content if match.size > start.size + 1 + encoder.text_token ')', :delimiter + else + encoder.text_token match[start.size..-1], :content if match.size > start.size + end + encoder.end_group :function + + elsif match = scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox) + encoder.text_token match, :float + + elsif match = scan(/#{RE::HexColor}/o) + encoder.text_token match, :color + + elsif match = scan(/! *important/) + encoder.text_token match, :important + + elsif match = scan(/(?:rgb|hsl)a?\([^()\n]*\)?/) + encoder.text_token match, :color + + elsif match = scan(RE::AtKeyword) + encoder.text_token match, :directive + + elsif match = scan(/ [+>~:;,.=()\/] /x) + if match == ':' + value_expected = true + elsif match == ';' + value_expected = false + end + encoder.text_token match, :operator + + else + encoder.text_token getch, :error + + end + + end + + if options[:keep_state] + @state = states + @value_expected = value_expected + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/debug.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/debug.rb new file mode 100644 index 0000000..83ede9a --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/debug.rb @@ -0,0 +1,75 @@ +require 'set' + +module CodeRay +module Scanners + + # = Debug Scanner + # + # Interprets the output of the Encoders::Debug encoder (basically the inverse function). + class Debug < Scanner + + register_for :debug + title 'CodeRay Token Dump Import' + + protected + + def setup + super + @known_token_kinds = TokenKinds.keys.map(&:to_s).to_set + end + + def scan_tokens encoder, options + + opened_tokens = [] + + until eos? + + if match = scan(/\s+/) + encoder.text_token match, :space + + elsif match = scan(/ (\w+) \( ( [^\)\\]* ( \\. [^\)\\]* )* ) \)? /x) + if @known_token_kinds.include? self[1] + encoder.text_token self[2].gsub(/\\(.)/m, '\1'), self[1].to_sym + else + encoder.text_token matched, :unknown + end + + elsif match = scan(/ (\w+) ([<\[]) /x) + if @known_token_kinds.include? self[1] + kind = self[1].to_sym + else + kind = :unknown + end + + opened_tokens << kind + case self[2] + when '<' + encoder.begin_group kind + when '[' + encoder.begin_line kind + else + raise 'CodeRay bug: This case should not be reached.' + end + + elsif !opened_tokens.empty? && match = scan(/ > /x) + encoder.end_group opened_tokens.pop + + elsif !opened_tokens.empty? && match = scan(/ \] /x) + encoder.end_line opened_tokens.pop + + else + encoder.text_token getch, :space + + end + + end + + encoder.end_group opened_tokens.pop until opened_tokens.empty? + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/delphi.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/delphi.rb new file mode 100644 index 0000000..b328155 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/delphi.rb @@ -0,0 +1,144 @@ +module CodeRay +module Scanners + + # Scanner for the Delphi language (Object Pascal). + # + # Alias: +pascal+ + class Delphi < Scanner + + register_for :delphi + file_extension 'pas' + + KEYWORDS = [ + 'and', 'array', 'as', 'at', 'asm', 'at', 'begin', 'case', 'class', + 'const', 'constructor', 'destructor', 'dispinterface', 'div', 'do', + 'downto', 'else', 'end', 'except', 'exports', 'file', 'finalization', + 'finally', 'for', 'function', 'goto', 'if', 'implementation', 'in', + 'inherited', 'initialization', 'inline', 'interface', 'is', 'label', + 'library', 'mod', 'nil', 'not', 'object', 'of', 'or', 'out', 'packed', + 'procedure', 'program', 'property', 'raise', 'record', 'repeat', + 'resourcestring', 'set', 'shl', 'shr', 'string', 'then', 'threadvar', + 'to', 'try', 'type', 'unit', 'until', 'uses', 'var', 'while', 'with', + 'xor', 'on', + ] # :nodoc: + + DIRECTIVES = [ + 'absolute', 'abstract', 'assembler', 'at', 'automated', 'cdecl', + 'contains', 'deprecated', 'dispid', 'dynamic', 'export', + 'external', 'far', 'forward', 'implements', 'local', + 'near', 'nodefault', 'on', 'overload', 'override', + 'package', 'pascal', 'platform', 'private', 'protected', 'public', + 'published', 'read', 'readonly', 'register', 'reintroduce', + 'requires', 'resident', 'safecall', 'stdcall', 'stored', 'varargs', + 'virtual', 'write', 'writeonly', + ] # :nodoc: + + IDENT_KIND = WordList::CaseIgnoring.new(:ident). + add(KEYWORDS, :keyword). + add(DIRECTIVES, :directive) # :nodoc: + + NAME_FOLLOWS = WordList::CaseIgnoring.new(false). + add(%w(procedure function .)) # :nodoc: + + protected + + def scan_tokens encoder, options + + state = :initial + last_token = '' + + until eos? + + if state == :initial + + if match = scan(/ \s+ /x) + encoder.text_token match, :space + next + + elsif match = scan(%r! \{ \$ [^}]* \}? | \(\* \$ (?: .*? \*\) | .* ) !mx) + encoder.text_token match, :preprocessor + next + + elsif match = scan(%r! // [^\n]* | \{ [^}]* \}? | \(\* (?: .*? \*\) | .* ) !mx) + encoder.text_token match, :comment + next + + elsif match = scan(/ <[>=]? | >=? | :=? | [-+=*\/;,@\^|\(\)\[\]] | \.\. /x) + encoder.text_token match, :operator + + elsif match = scan(/\./) + encoder.text_token match, :operator + next if last_token == 'end' + + elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) + encoder.text_token match, NAME_FOLLOWS[last_token] ? :ident : IDENT_KIND[match] + + elsif match = skip(/ ' ( [^\n']|'' ) (?:'|$) /x) + encoder.begin_group :char + encoder.text_token "'", :delimiter + encoder.text_token self[1], :content + encoder.text_token "'", :delimiter + encoder.end_group :char + next + + elsif match = scan(/ ' /x) + encoder.begin_group :string + encoder.text_token match, :delimiter + state = :string + + elsif match = scan(/ \# (?: \d+ | \$[0-9A-Fa-f]+ ) /x) + encoder.text_token match, :char + + elsif match = scan(/ \$ [0-9A-Fa-f]+ /x) + encoder.text_token match, :hex + + elsif match = scan(/ (?: \d+ ) (?![eE]|\.[^.]) /x) + encoder.text_token match, :integer + + elsif match = scan(/ \d+ (?: \.\d+ (?: [eE][+-]? \d+ )? | [eE][+-]? \d+ ) /x) + encoder.text_token match, :float + + else + encoder.text_token getch, :error + next + + end + + elsif state == :string + if match = scan(/[^\n']+/) + encoder.text_token match, :content + elsif match = scan(/''/) + encoder.text_token match, :char + elsif match = scan(/'/) + encoder.text_token match, :delimiter + encoder.end_group :string + state = :initial + next + elsif match = scan(/\n/) + encoder.end_group :string + encoder.text_token match, :space + state = :initial + else + raise "else case \' reached; %p not handled." % peek(1), encoder + end + + else + raise 'else-case reached', encoder + + end + + last_token = match + + end + + if state == :string + encoder.end_group state + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/diff.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/diff.rb new file mode 100644 index 0000000..fd1aed6 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/diff.rb @@ -0,0 +1,221 @@ +module CodeRay +module Scanners + + # Scanner for output of the diff command. + # + # Alias: +patch+ + class Diff < Scanner + + register_for :diff + title 'diff output' + + DEFAULT_OPTIONS = { + :highlight_code => true, + :inline_diff => true, + } + + protected + + def scan_tokens encoder, options + + line_kind = nil + state = :initial + deleted_lines_count = 0 + scanners = Hash.new do |h, lang| + h[lang] = Scanners[lang].new '', :keep_tokens => true, :keep_state => true + end + content_scanner = scanners[:plain] + content_scanner_entry_state = nil + + until eos? + + if match = scan(/\n/) + deleted_lines_count = 0 unless line_kind == :delete + if line_kind + encoder.end_line line_kind + line_kind = nil + end + encoder.text_token match, :space + next + end + + case state + + when :initial + if match = scan(/--- |\+\+\+ |=+|_+/) + encoder.begin_line line_kind = :head + encoder.text_token match, :head + if match = scan(/[^\x00\n]+?(?=$|[\t\n]| \(revision)/) + encoder.text_token match, :filename + if options[:highlight_code] && match != '/dev/null' + file_type = CodeRay::FileType.fetch(match, :text) + file_type = :text if file_type == :diff + content_scanner = scanners[file_type] + content_scanner_entry_state = nil + end + end + next unless match = scan(/.+/) + encoder.text_token match, :plain + elsif match = scan(/Index: |Property changes on: /) + encoder.begin_line line_kind = :head + encoder.text_token match, :head + next unless match = scan(/.+/) + encoder.text_token match, :plain + elsif match = scan(/Added: /) + encoder.begin_line line_kind = :head + encoder.text_token match, :head + next unless match = scan(/.+/) + encoder.text_token match, :plain + state = :added + elsif match = scan(/\\ .*/) + encoder.text_token match, :comment + elsif match = scan(/@@(?>[^@\n]+)@@/) + content_scanner.state = :initial unless match?(/\n\+/) + content_scanner_entry_state = nil + if check(/\n|$/) + encoder.begin_line line_kind = :change + else + encoder.begin_group :change + end + encoder.text_token match[0,2], :change + encoder.text_token match[2...-2], :plain + encoder.text_token match[-2,2], :change + encoder.end_group :change unless line_kind + next unless match = scan(/.+/) + if options[:highlight_code] + content_scanner.tokenize match, :tokens => encoder + else + encoder.text_token match, :plain + end + next + elsif match = scan(/\+/) + encoder.begin_line line_kind = :insert + encoder.text_token match, :insert + next unless match = scan(/.+/) + if options[:highlight_code] + content_scanner.tokenize match, :tokens => encoder + else + encoder.text_token match, :plain + end + next + elsif match = scan(/-/) + deleted_lines_count += 1 + if options[:inline_diff] && deleted_lines_count == 1 && (changed_lines_count = 1 + check(/.*(?:\n\-.*)*/).count("\n")) && match?(/(?>.*(?:\n\-.*){#{changed_lines_count - 1}}(?:\n\+.*){#{changed_lines_count}})$(?!\n\+)/) + deleted_lines = Array.new(changed_lines_count) { |i| skip(/\n\-/) if i > 0; scan(/.*/) } + inserted_lines = Array.new(changed_lines_count) { |i| skip(/\n\+/) ; scan(/.*/) } + + deleted_lines_tokenized = [] + inserted_lines_tokenized = [] + for deleted_line, inserted_line in deleted_lines.zip(inserted_lines) + pre, deleted_part, inserted_part, post = diff deleted_line, inserted_line + content_scanner_entry_state = content_scanner.state + deleted_lines_tokenized << content_scanner.tokenize([pre, deleted_part, post], :tokens => Tokens.new) + content_scanner.state = content_scanner_entry_state || :initial + inserted_lines_tokenized << content_scanner.tokenize([pre, inserted_part, post], :tokens => Tokens.new) + end + + for pre, deleted_part, post in deleted_lines_tokenized + encoder.begin_line :delete + encoder.text_token '-', :delete + encoder.tokens pre + unless deleted_part.empty? + encoder.begin_group :eyecatcher + encoder.tokens deleted_part + encoder.end_group :eyecatcher + end + encoder.tokens post + encoder.end_line :delete + encoder.text_token "\n", :space + end + + for pre, inserted_part, post in inserted_lines_tokenized + encoder.begin_line :insert + encoder.text_token '+', :insert + encoder.tokens pre + unless inserted_part.empty? + encoder.begin_group :eyecatcher + encoder.tokens inserted_part + encoder.end_group :eyecatcher + end + encoder.tokens post + changed_lines_count -= 1 + if changed_lines_count > 0 + encoder.end_line :insert + encoder.text_token "\n", :space + end + end + + line_kind = :insert + + elsif match = scan(/.*/) + encoder.begin_line line_kind = :delete + encoder.text_token '-', :delete + if options[:highlight_code] + if deleted_lines_count == 1 + content_scanner_entry_state = content_scanner.state + end + content_scanner.tokenize match, :tokens => encoder unless match.empty? + if !match?(/\n-/) + if match?(/\n\+/) + content_scanner.state = content_scanner_entry_state || :initial + end + content_scanner_entry_state = nil + end + else + encoder.text_token match, :plain + end + end + next + elsif match = scan(/ .*/) + if options[:highlight_code] + content_scanner.tokenize match, :tokens => encoder + else + encoder.text_token match, :plain + end + next + elsif match = scan(/.+/) + encoder.begin_line line_kind = :comment + encoder.text_token match, :plain + else + raise_inspect 'else case rached' + end + + when :added + if match = scan(/ \+/) + encoder.begin_line line_kind = :insert + encoder.text_token match, :insert + next unless match = scan(/.+/) + encoder.text_token match, :plain + else + state = :initial + next + end + end + + end + + encoder.end_line line_kind if line_kind + + encoder + end + + private + + def diff a, b + # i will be the index of the leftmost difference from the left. + i_max = [a.size, b.size].min + i = 0 + i += 1 while i < i_max && a[i] == b[i] + # j_min will be the index of the leftmost difference from the right. + j_min = i - i_max + # j will be the index of the rightmost difference from the right which + # does not precede the leftmost one from the left. + j = -1 + j -= 1 while j >= j_min && a[j] == b[j] + return a[0...i], a[i..j], b[i..j], (j < -1) ? a[j+1..-1] : '' + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/erb.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/erb.rb new file mode 100644 index 0000000..727a993 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/erb.rb @@ -0,0 +1,81 @@ +module CodeRay +module Scanners + + load :html + load :ruby + + # Scanner for HTML ERB templates. + class ERB < Scanner + + register_for :erb + title 'HTML ERB Template' + + KINDS_NOT_LOC = HTML::KINDS_NOT_LOC + + ERB_RUBY_BLOCK = / + (<%(?!%)[-=\#]?) + ((?> + [^\-%]* # normal* + (?> # special + (?: %(?!>) | -(?!%>) ) + [^\-%]* # normal* + )* + )) + ((?: -?%> )?) + /x # :nodoc: + + START_OF_ERB = / + <%(?!%) + /x # :nodoc: + + protected + + def setup + @ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true + @html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true, :keep_state => true + end + + def reset_instance + super + @html_scanner.reset + end + + def scan_tokens encoder, options + + until eos? + + if (match = scan_until(/(?=#{START_OF_ERB})/o) || scan_rest) and not match.empty? + @html_scanner.tokenize match, :tokens => encoder + + elsif match = scan(/#{ERB_RUBY_BLOCK}/o) + start_tag = self[1] + code = self[2] + end_tag = self[3] + + encoder.begin_group :inline + encoder.text_token start_tag, :inline_delimiter + + if start_tag == '<%#' + encoder.text_token code, :comment + else + @ruby_scanner.tokenize code, :tokens => encoder + end unless code.empty? + + encoder.text_token end_tag, :inline_delimiter unless end_tag.empty? + encoder.end_group :inline + + else + raise_inspect 'else-case reached!', encoder + + end + + end + + encoder + + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/go.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/go.rb new file mode 100644 index 0000000..99fdd63 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/go.rb @@ -0,0 +1,208 @@ +module CodeRay +module Scanners + + class Go < Scanner + + register_for :go + file_extension 'go' + + # http://golang.org/ref/spec#Keywords + KEYWORDS = [ + 'break', 'default', 'func', 'interface', 'select', + 'case', 'defer', 'go', 'map', 'struct', + 'chan', 'else', 'goto', 'package', 'switch', + 'const', 'fallthrough', 'if', 'range', 'type', + 'continue', 'for', 'import', 'return', 'var', + ] # :nodoc: + + # http://golang.org/ref/spec#Types + PREDEFINED_TYPES = [ + 'bool', + 'uint8', 'uint16', 'uint32', 'uint64', + 'int8', 'int16', 'int32', 'int64', + 'float32', 'float64', + 'complex64', 'complex128', + 'byte', 'rune', 'string', 'error', + 'uint', 'int', 'uintptr', + ] # :nodoc: + + PREDEFINED_CONSTANTS = [ + 'nil', 'iota', + 'true', 'false', + ] # :nodoc: + + PREDEFINED_FUNCTIONS = %w[ + append cap close complex copy delete imag len + make new panic print println real recover + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(PREDEFINED_TYPES, :predefined_type). + add(PREDEFINED_CONSTANTS, :predefined_constant). + add(PREDEFINED_FUNCTIONS, :predefined) # :nodoc: + + ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: + + protected + + def scan_tokens encoder, options + + state = :initial + label_expected = true + case_expected = false + label_expected_before_preproc_line = nil + in_preproc_line = false + + until eos? + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + if in_preproc_line && match != "\\\n" && match.index(?\n) + in_preproc_line = false + case_expected = false + label_expected = label_expected_before_preproc_line + end + encoder.text_token match, :space + + elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) + encoder.text_token match, :comment + + elsif match = scan(/ ?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x) + if case_expected + label_expected = true if match == ':' + case_expected = false + end + encoder.text_token match, :operator + + elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) + kind = IDENT_KIND[match] + if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/) + kind = :label + label_expected = false + match << matched + else + label_expected = false + if kind == :keyword + case match + when 'case', 'default' + case_expected = true + end + end + end + encoder.text_token match, kind + + elsif match = scan(/L?"/) + encoder.begin_group :string + if match[0] == ?L + encoder.text_token 'L', :modifier + match = '"' + end + encoder.text_token match, :delimiter + state = :string + + elsif match = scan(/ ` ([^`]+)? (`)? /x) + encoder.begin_group :shell + encoder.text_token '`', :delimiter + encoder.text_token self[1], :content if self[1] + encoder.text_token self[2], :delimiter if self[2] + encoder.end_group :shell + + elsif match = scan(/ \# \s* if \s* 0 /x) + match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos? + encoder.text_token match, :comment + + elsif match = scan(/#[ \t]*(\w*)/) + encoder.text_token match, :preprocessor + in_preproc_line = true + label_expected_before_preproc_line = label_expected + state = :include_expected if self[1] == 'include' + + elsif match = scan(/ L?' (?: [^\'\n\\] | \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) )? '? /ox) + label_expected = false + encoder.text_token match, :char + + elsif match = scan(/\$/) + encoder.text_token match, :ident + + elsif match = scan(/-?\d*(\.\d*)?([eE][+-]?\d+)?i/) + label_expected = false + encoder.text_token match, :imaginary + + elsif match = scan(/-?0[xX][0-9A-Fa-f]+/) + label_expected = false + encoder.text_token match, :hex + + elsif match = scan(/-?(?:0[0-7]+)(?![89.eEfF])/) + label_expected = false + encoder.text_token match, :octal + + elsif match = scan(/-?(?:\d*\.\d+|\d+\.)(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+/) + label_expected = false + encoder.text_token match, :float + + elsif match = scan(/-?(?:\d+)(?![.eEfF])L?L?/) + label_expected = false + encoder.text_token match, :integer + + else + encoder.text_token getch, :error + + end + + when :string + if match = scan(/[^\\\n"]+/) + encoder.text_token match, :content + elsif match = scan(/"/) + encoder.text_token match, :delimiter + encoder.end_group :string + state = :initial + label_expected = false + elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + encoder.text_token match, :char + elsif match = scan(/ \\ /x) + encoder.text_token match, :error + elsif match = scan(/$/) + encoder.end_group :string + state = :initial + label_expected = false + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder + end + + when :include_expected + if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/) + encoder.text_token match, :include + state = :initial + + elsif match = scan(/\s+/) + encoder.text_token match, :space + state = :initial if match.index ?\n + + else + state = :initial + + end + + else + raise_inspect 'Unknown state', encoder + + end + + end + + if state == :string + encoder.end_group :string + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/groovy.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/groovy.rb new file mode 100644 index 0000000..c64454f --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/groovy.rb @@ -0,0 +1,268 @@ +module CodeRay +module Scanners + + load :java + + # Scanner for Groovy. + class Groovy < Java + + register_for :groovy + + # TODO: check list of keywords + GROOVY_KEYWORDS = %w[ + as assert def in + ] # :nodoc: + KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[ + case instanceof new return throw typeof while as assert in + ] # :nodoc: + GROOVY_MAGIC_VARIABLES = %w[ it ] # :nodoc: + + IDENT_KIND = Java::IDENT_KIND.dup. + add(GROOVY_KEYWORDS, :keyword). + add(GROOVY_MAGIC_VARIABLES, :local_variable) # :nodoc: + + ESCAPE = / [bfnrtv$\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x # :nodoc: no 4-byte unicode chars? U[a-fA-F0-9]{8} + REGEXP_ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} | \d | [bBdDsSwW\/] /x # :nodoc: + + # TODO: interpretation inside ', ", / + STRING_CONTENT_PATTERN = { + "'" => /(?>\\[^\\'\n]+|[^\\'\n]+)+/, + '"' => /[^\\$"\n]+/, + "'''" => /(?>[^\\']+|'(?!''))+/, + '"""' => /(?>[^\\$"]+|"(?!""))+/, + '/' => /[^\\$\/\n]+/, + } # :nodoc: + + protected + + def setup + @state = :initial + end + + def scan_tokens encoder, options + state = options[:state] || @state + inline_block_stack = [] + inline_block_paren_depth = nil + string_delimiter = nil + import_clause = class_name_follows = last_token = after_def = false + value_expected = true + + until eos? + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + encoder.text_token match, :space + if match.index ?\n + import_clause = after_def = false + value_expected = true unless value_expected + end + next + + elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) + value_expected = true + after_def = false + encoder.text_token match, :comment + + elsif bol? && match = scan(/ \#!.* /x) + encoder.text_token match, :doctype + + elsif import_clause && match = scan(/ (?!as) #{IDENT} (?: \. #{IDENT} )* (?: \.\* )? /ox) + after_def = value_expected = false + encoder.text_token match, :include + + elsif match = scan(/ #{IDENT} | \[\] /ox) + kind = IDENT_KIND[match] + value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match] + if last_token == '.' + kind = :ident + elsif class_name_follows + kind = :class + class_name_follows = false + elsif after_def && check(/\s*[({]/) + kind = :method + after_def = false + elsif kind == :ident && last_token != '?' && check(/:/) + kind = :key + else + class_name_follows = true if match == 'class' || (import_clause && match == 'as') + import_clause = match == 'import' + after_def = true if match == 'def' + end + encoder.text_token match, kind + + elsif match = scan(/;/) + import_clause = after_def = false + value_expected = true + encoder.text_token match, :operator + + elsif match = scan(/\{/) + class_name_follows = after_def = false + value_expected = true + encoder.text_token match, :operator + if !inline_block_stack.empty? + inline_block_paren_depth += 1 + end + + # TODO: ~'...', ~"..." and ~/.../ style regexps + elsif match = scan(/ \.\.] | \+\+ | + && | \|\| | \*\*=? | ==?~ | <=?>? | [-+*%^~&|>=!]=? | <<>>?=? /x) + value_expected = true + value_expected = :regexp if match == '~' + after_def = false + encoder.text_token match, :operator + + elsif match = scan(/ [)\]}] /x) + value_expected = after_def = false + if !inline_block_stack.empty? && match == '}' + inline_block_paren_depth -= 1 + if inline_block_paren_depth == 0 # closing brace of inline block reached + encoder.text_token match, :inline_delimiter + encoder.end_group :inline + state, string_delimiter, inline_block_paren_depth = inline_block_stack.pop + next + end + end + encoder.text_token match, :operator + + elsif check(/[\d.]/) + after_def = value_expected = false + if match = scan(/0[xX][0-9A-Fa-f]+/) + encoder.text_token match, :hex + elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/) + encoder.text_token match, :octal + elsif match = scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/) + encoder.text_token match, :float + elsif match = scan(/\d+[lLgG]?/) + encoder.text_token match, :integer + end + + elsif match = scan(/'''|"""/) + after_def = value_expected = false + state = :multiline_string + encoder.begin_group :string + string_delimiter = match + encoder.text_token match, :delimiter + + # TODO: record.'name' syntax + elsif match = scan(/["']/) + after_def = value_expected = false + state = match == '/' ? :regexp : :string + encoder.begin_group state + string_delimiter = match + encoder.text_token match, :delimiter + + elsif value_expected && match = scan(/\//) + after_def = value_expected = false + encoder.begin_group :regexp + state = :regexp + string_delimiter = '/' + encoder.text_token match, :delimiter + + elsif match = scan(/ @ #{IDENT} /ox) + after_def = value_expected = false + encoder.text_token match, :annotation + + elsif match = scan(/\//) + after_def = false + value_expected = true + encoder.text_token match, :operator + + else + encoder.text_token getch, :error + + end + + when :string, :regexp, :multiline_string + if match = scan(STRING_CONTENT_PATTERN[string_delimiter]) + encoder.text_token match, :content + + elsif match = scan(state == :multiline_string ? /'''|"""/ : /["'\/]/) + encoder.text_token match, :delimiter + if state == :regexp + # TODO: regexp modifiers? s, m, x, i? + modifiers = scan(/[ix]+/) + encoder.text_token modifiers, :modifier if modifiers && !modifiers.empty? + end + state = :string if state == :multiline_string + encoder.end_group state + string_delimiter = nil + after_def = value_expected = false + state = :initial + next + + elsif (state == :string || state == :multiline_string) && + (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)) + if string_delimiter[0] == ?' && !(match == "\\\\" || match == "\\'") + encoder.text_token match, :content + else + encoder.text_token match, :char + end + elsif state == :regexp && match = scan(/ \\ (?: #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + encoder.text_token match, :char + + elsif match = scan(/ \$ #{IDENT} /mox) + encoder.begin_group :inline + encoder.text_token '$', :inline_delimiter + match = match[1..-1] + encoder.text_token match, IDENT_KIND[match] + encoder.end_group :inline + next + elsif match = scan(/ \$ \{ /x) + encoder.begin_group :inline + encoder.text_token match, :inline_delimiter + inline_block_stack << [state, string_delimiter, inline_block_paren_depth] + inline_block_paren_depth = 1 + state = :initial + next + + elsif match = scan(/ \$ /mx) + encoder.text_token match, :content + + elsif match = scan(/ \\. /mx) + encoder.text_token match, :content # TODO: Shouldn't this be :error? + + elsif match = scan(/ \\ | \n /x) + encoder.end_group state == :regexp ? :regexp : :string + encoder.text_token match, :error + after_def = value_expected = false + state = :initial + + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder + + end + + else + raise_inspect 'Unknown state', encoder + + end + + last_token = match unless [:space, :comment, :doctype].include? kind + + end + + if [:multiline_string, :string, :regexp].include? state + encoder.end_group state == :regexp ? :regexp : :string + end + + if options[:keep_state] + @state = state + end + + until inline_block_stack.empty? + state, = *inline_block_stack.pop + encoder.end_group :inline + encoder.end_group state == :regexp ? :regexp : :string + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/haml.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/haml.rb new file mode 100644 index 0000000..5433790 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/haml.rb @@ -0,0 +1,168 @@ +module CodeRay +module Scanners + + load :ruby + load :html + load :java_script + + class HAML < Scanner + + register_for :haml + title 'HAML Template' + + KINDS_NOT_LOC = HTML::KINDS_NOT_LOC + + protected + + def setup + super + @ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true + @embedded_ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true, :state => @ruby_scanner.interpreted_string_state + @html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true + end + + def scan_tokens encoder, options + + match = nil + code = '' + + until eos? + + if bol? + if match = scan(/!!!.*/) + encoder.text_token match, :doctype + next + end + + if match = scan(/(?>( *)(\/(?!\[if)|-\#|:javascript|:ruby|:\w+) *)(?=\n)/) + encoder.text_token match, :comment + + code = self[2] + if match = scan(/(?:\n+#{self[1]} .*)+/) + case code + when '/', '-#' + encoder.text_token match, :comment + when ':javascript' + # TODO: recognize #{...} snippets inside JavaScript + @java_script_scanner ||= CodeRay.scanner :java_script, :tokens => @tokens, :keep_tokens => true + @java_script_scanner.tokenize match, :tokens => encoder + when ':ruby' + @ruby_scanner.tokenize match, :tokens => encoder + when /:\w+/ + encoder.text_token match, :comment + else + raise 'else-case reached: %p' % [code] + end + end + end + + if match = scan(/ +/) + encoder.text_token match, :space + end + + if match = scan(/\/.*/) + encoder.text_token match, :comment + next + end + + if match = scan(/\\/) + encoder.text_token match, :plain + if match = scan(/.+/) + @html_scanner.tokenize match, :tokens => encoder + end + next + end + + tag = false + + if match = scan(/%[\w:]+\/?/) + encoder.text_token match, :tag + # if match = scan(/( +)(.+)/) + # encoder.text_token self[1], :space + # @embedded_ruby_scanner.tokenize self[2], :tokens => encoder + # end + tag = true + end + + while match = scan(/([.#])[-\w]*\w/) + encoder.text_token match, self[1] == '#' ? :constant : :class + tag = true + end + + if tag && match = scan(/(\()([^)]+)?(\))?/) + # TODO: recognize title=@title, class="widget_#{@widget.number}" + encoder.text_token self[1], :plain + @html_scanner.tokenize self[2], :tokens => encoder, :state => :attribute if self[2] + encoder.text_token self[3], :plain if self[3] + end + + if tag && match = scan(/\{/) + encoder.text_token match, :plain + + code = '' + level = 1 + while true + code << scan(/([^\{\},\n]|, *\n?)*/) + case match = getch + when '{' + level += 1 + code << match + when '}' + level -= 1 + if level > 0 + code << match + else + break + end + when "\n", ",", nil + break + end + end + @ruby_scanner.tokenize code, :tokens => encoder unless code.empty? + + encoder.text_token match, :plain if match + end + + if tag && match = scan(/(\[)([^\]\n]+)?(\])?/) + encoder.text_token self[1], :plain + @ruby_scanner.tokenize self[2], :tokens => encoder if self[2] + encoder.text_token self[3], :plain if self[3] + end + + if tag && match = scan(/\//) + encoder.text_token match, :tag + end + + if scan(/(>? encoder + else + @ruby_scanner.tokenize self[4], :tokens => encoder + end + end + elsif match = scan(/((?:<|> encoder if self[2] + end + + elsif match = scan(/.+/) + @html_scanner.tokenize match, :tokens => encoder + + end + + if match = scan(/\n/) + encoder.text_token match, :space + end + end + + encoder + + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/html.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/html.rb new file mode 100644 index 0000000..ebe7b01 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/html.rb @@ -0,0 +1,275 @@ +module CodeRay +module Scanners + + # HTML Scanner + # + # Alias: +xhtml+ + # + # See also: Scanners::XML + class HTML < Scanner + + register_for :html + + KINDS_NOT_LOC = [ + :comment, :doctype, :preprocessor, + :tag, :attribute_name, :operator, + :attribute_value, :string, + :plain, :entity, :error, + ] # :nodoc: + + EVENT_ATTRIBUTES = %w( + onabort onafterprint onbeforeprint onbeforeunload onblur oncanplay + oncanplaythrough onchange onclick oncontextmenu oncuechange ondblclick + ondrag ondragdrop ondragend ondragenter ondragleave ondragover + ondragstart ondrop ondurationchange onemptied onended onerror onfocus + onformchange onforminput onhashchange oninput oninvalid onkeydown + onkeypress onkeyup onload onloadeddata onloadedmetadata onloadstart + onmessage onmousedown onmousemove onmouseout onmouseover onmouseup + onmousewheel onmove onoffline ononline onpagehide onpageshow onpause + onplay onplaying onpopstate onprogress onratechange onreadystatechange + onredo onreset onresize onscroll onseeked onseeking onselect onshow + onstalled onstorage onsubmit onsuspend ontimeupdate onundo onunload + onvolumechange onwaiting + ) + + IN_ATTRIBUTE = WordList::CaseIgnoring.new(nil). + add(EVENT_ATTRIBUTES, :script). + add(['style'], :style) + + ATTR_NAME = /[\w.:-]+/ # :nodoc: + TAG_END = /\/?>/ # :nodoc: + HEX = /[0-9a-fA-F]/ # :nodoc: + ENTITY = / + & + (?: + \w+ + | + \# + (?: + \d+ + | + x#{HEX}+ + ) + ) + ; + /ox # :nodoc: + + PLAIN_STRING_CONTENT = { + "'" => /[^&'>\n]+/, + '"' => /[^&">\n]+/, + } # :nodoc: + + def reset + super + @state = :initial + @plain_string_content = nil + end + + protected + + def setup + @state = :initial + @plain_string_content = nil + @in_tag = nil + end + + def scan_java_script encoder, code + if code && !code.empty? + @java_script_scanner ||= Scanners::JavaScript.new '', :keep_tokens => true + @java_script_scanner.tokenize code, :tokens => encoder + end + end + + def scan_css encoder, code, state = [:initial] + if code && !code.empty? + @css_scanner ||= Scanners::CSS.new '', :keep_tokens => true + @css_scanner.tokenize code, :tokens => encoder, :state => state + end + end + + def scan_tokens encoder, options + state = options[:state] || @state + plain_string_content = @plain_string_content + in_tag = @in_tag + in_attribute = nil + + encoder.begin_group :string if state == :attribute_value_string + + until eos? + + if state != :in_special_tag && match = scan(/\s+/m) + encoder.text_token match, :space + + else + + case state + + when :initial + if match = scan(//m) + encoder.text_token match[0..-4], :plain + encoder.text_token ']]>', :inline_delimiter + elsif match = scan(/.+/) + encoder.text_token match, :error + end + elsif match = scan(/|.*)/m) + encoder.text_token match, :comment + elsif match = scan(/|.*)|\]>/m) + encoder.text_token match, :doctype + elsif match = scan(/<\?xml(?:.*?\?>|.*)/m) + encoder.text_token match, :preprocessor + elsif match = scan(/<\?(?:.*?\?>|.*)/m) + encoder.text_token match, :comment + elsif match = scan(/<\/[-\w.:]*>?/m) + in_tag = nil + encoder.text_token match, :tag + elsif match = scan(/<(?:(script|style)|[-\w.:]+)(>)?/m) + encoder.text_token match, :tag + in_tag = self[1] + if self[2] + state = :in_special_tag if in_tag + else + state = :attribute + end + elsif match = scan(/[^<>&]+/) + encoder.text_token match, :plain + elsif match = scan(/#{ENTITY}/ox) + encoder.text_token match, :entity + elsif match = scan(/[<>&]/) + in_tag = nil + encoder.text_token match, :error + else + raise_inspect '[BUG] else-case reached with state %p' % [state], encoder + end + + when :attribute + if match = scan(/#{TAG_END}/o) + encoder.text_token match, :tag + in_attribute = nil + if in_tag + state = :in_special_tag + else + state = :initial + end + elsif match = scan(/#{ATTR_NAME}/o) + in_attribute = IN_ATTRIBUTE[match] + encoder.text_token match, :attribute_name + state = :attribute_equal + else + in_tag = nil + encoder.text_token getch, :error + end + + when :attribute_equal + if match = scan(/=/) #/ + encoder.text_token match, :operator + state = :attribute_value + else + state = :attribute + next + end + + when :attribute_value + if match = scan(/#{ATTR_NAME}/o) + encoder.text_token match, :attribute_value + state = :attribute + elsif match = scan(/["']/) + if in_attribute == :script || in_attribute == :style + encoder.begin_group :string + encoder.text_token match, :delimiter + if scan(/javascript:[ \t]*/) + encoder.text_token matched, :comment + end + code = scan_until(match == '"' ? /(?="|\z)/ : /(?='|\z)/) + if in_attribute == :script + scan_java_script encoder, code + else + scan_css encoder, code, [:block] + end + match = scan(/["']/) + encoder.text_token match, :delimiter if match + encoder.end_group :string + state = :attribute + in_attribute = nil + else + encoder.begin_group :string + state = :attribute_value_string + plain_string_content = PLAIN_STRING_CONTENT[match] + encoder.text_token match, :delimiter + end + elsif match = scan(/#{TAG_END}/o) + encoder.text_token match, :tag + state = :initial + else + encoder.text_token getch, :error + end + + when :attribute_value_string + if match = scan(plain_string_content) + encoder.text_token match, :content + elsif match = scan(/['"]/) + encoder.text_token match, :delimiter + encoder.end_group :string + state = :attribute + elsif match = scan(/#{ENTITY}/ox) + encoder.text_token match, :entity + elsif match = scan(/&/) + encoder.text_token match, :content + elsif match = scan(/[\n>]/) + encoder.end_group :string + state = :initial + encoder.text_token match, :error + end + + when :in_special_tag + case in_tag + when 'script', 'style' + encoder.text_token match, :space if match = scan(/[ \t]*\n/) + if scan(/(\s*)|(.*))/m) + code = self[2] || self[4] + closing = self[3] + encoder.text_token self[1], :comment + else + code = scan_until(/(?=(?:\n\s*)?<\/#{in_tag}>)|\z/) + closing = false + end + unless code.empty? + encoder.begin_group :inline + if in_tag == 'script' + scan_java_script encoder, code + else + scan_css encoder, code + end + encoder.end_group :inline + end + encoder.text_token closing, :comment if closing + state = :initial + else + raise 'unknown special tag: %p' % [in_tag] + end + + else + raise_inspect 'Unknown state: %p' % [state], encoder + + end + + end + + end + + if options[:keep_state] + @state = state + @plain_string_content = plain_string_content + @in_tag = in_tag + end + + encoder.end_group :string if state == :attribute_value_string + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java.rb new file mode 100644 index 0000000..b282864 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java.rb @@ -0,0 +1,174 @@ +module CodeRay +module Scanners + + # Scanner for Java. + class Java < Scanner + + register_for :java + + autoload :BuiltinTypes, CodeRay.coderay_path('scanners', 'java', 'builtin_types') + + # http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html + KEYWORDS = %w[ + assert break case catch continue default do else + finally for if instanceof import new package + return switch throw try typeof while + debugger export + ] # :nodoc: + RESERVED = %w[ const goto ] # :nodoc: + CONSTANTS = %w[ false null true ] # :nodoc: + MAGIC_VARIABLES = %w[ this super ] # :nodoc: + TYPES = %w[ + boolean byte char class double enum float int interface long + short void + ] << '[]' # :nodoc: because int[] should be highlighted as a type + DIRECTIVES = %w[ + abstract extends final implements native private protected public + static strictfp synchronized throws transient volatile + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(RESERVED, :reserved). + add(CONSTANTS, :predefined_constant). + add(MAGIC_VARIABLES, :local_variable). + add(TYPES, :type). + add(BuiltinTypes::List, :predefined_type). + add(BuiltinTypes::List.select { |builtin| builtin[/(Error|Exception)$/] }, :exception). + add(DIRECTIVES, :directive) # :nodoc: + + ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: + STRING_CONTENT_PATTERN = { + "'" => /[^\\']+/, + '"' => /[^\\"]+/, + '/' => /[^\\\/]+/, + } # :nodoc: + IDENT = /[a-zA-Z_][A-Za-z_0-9]*/ # :nodoc: + + protected + + def scan_tokens encoder, options + + state = :initial + string_delimiter = nil + package_name_expected = false + class_name_follows = false + last_token_dot = false + + until eos? + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + encoder.text_token match, :space + next + + elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) + encoder.text_token match, :comment + next + + elsif package_name_expected && match = scan(/ #{IDENT} (?: \. #{IDENT} )* /ox) + encoder.text_token match, package_name_expected + + elsif match = scan(/ #{IDENT} | \[\] /ox) + kind = IDENT_KIND[match] + if last_token_dot + kind = :ident + elsif class_name_follows + kind = :class + class_name_follows = false + else + case match + when 'import' + package_name_expected = :include + when 'package' + package_name_expected = :namespace + when 'class', 'interface' + class_name_follows = true + end + end + encoder.text_token match, kind + + elsif match = scan(/ \.(?!\d) | [,?:()\[\]}] | -- | \+\+ | && | \|\| | \*\*=? | [-+*\/%^~&|<>=!]=? | <<>>?=? /x) + encoder.text_token match, :operator + + elsif match = scan(/;/) + package_name_expected = false + encoder.text_token match, :operator + + elsif match = scan(/\{/) + class_name_follows = false + encoder.text_token match, :operator + + elsif check(/[\d.]/) + if match = scan(/0[xX][0-9A-Fa-f]+/) + encoder.text_token match, :hex + elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/) + encoder.text_token match, :octal + elsif match = scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/) + encoder.text_token match, :float + elsif match = scan(/\d+[lL]?/) + encoder.text_token match, :integer + end + + elsif match = scan(/["']/) + state = :string + encoder.begin_group state + string_delimiter = match + encoder.text_token match, :delimiter + + elsif match = scan(/ @ #{IDENT} /ox) + encoder.text_token match, :annotation + + else + encoder.text_token getch, :error + + end + + when :string + if match = scan(STRING_CONTENT_PATTERN[string_delimiter]) + encoder.text_token match, :content + elsif match = scan(/["'\/]/) + encoder.text_token match, :delimiter + encoder.end_group state + state = :initial + string_delimiter = nil + elsif state == :string && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)) + if string_delimiter == "'" && !(match == "\\\\" || match == "\\'") + encoder.text_token match, :content + else + encoder.text_token match, :char + end + elsif match = scan(/\\./m) + encoder.text_token match, :content + elsif match = scan(/ \\ | $ /x) + encoder.end_group state + state = :initial + encoder.text_token match, :error unless match.empty? + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder + end + + else + raise_inspect 'Unknown state', encoder + + end + + last_token_dot = match == '.' + + end + + if state == :string + encoder.end_group state + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java/builtin_types.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java/builtin_types.rb new file mode 100644 index 0000000..d1b8b73 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java/builtin_types.rb @@ -0,0 +1,421 @@ +module CodeRay +module Scanners + + module Java::BuiltinTypes # :nodoc: + + #:nocov: + List = %w[ + AbstractAction AbstractBorder AbstractButton AbstractCellEditor AbstractCollection + AbstractColorChooserPanel AbstractDocument AbstractExecutorService AbstractInterruptibleChannel + AbstractLayoutCache AbstractList AbstractListModel AbstractMap AbstractMethodError AbstractPreferences + AbstractQueue AbstractQueuedSynchronizer AbstractSelectableChannel AbstractSelectionKey AbstractSelector + AbstractSequentialList AbstractSet AbstractSpinnerModel AbstractTableModel AbstractUndoableEdit + AbstractWriter AccessControlContext AccessControlException AccessController AccessException Accessible + AccessibleAction AccessibleAttributeSequence AccessibleBundle AccessibleComponent AccessibleContext + AccessibleEditableText AccessibleExtendedComponent AccessibleExtendedTable AccessibleExtendedText + AccessibleHyperlink AccessibleHypertext AccessibleIcon AccessibleKeyBinding AccessibleObject + AccessibleRelation AccessibleRelationSet AccessibleResourceBundle AccessibleRole AccessibleSelection + AccessibleState AccessibleStateSet AccessibleStreamable AccessibleTable AccessibleTableModelChange + AccessibleText AccessibleTextSequence AccessibleValue AccountException AccountExpiredException + AccountLockedException AccountNotFoundException Acl AclEntry AclNotFoundException Action ActionEvent + ActionListener ActionMap ActionMapUIResource Activatable ActivateFailedException ActivationDesc + ActivationException ActivationGroup ActivationGroupDesc ActivationGroupID ActivationGroup_Stub + ActivationID ActivationInstantiator ActivationMonitor ActivationSystem Activator ActiveEvent + ActivityCompletedException ActivityRequiredException Adjustable AdjustmentEvent AdjustmentListener + Adler32 AffineTransform AffineTransformOp AlgorithmParameterGenerator AlgorithmParameterGeneratorSpi + AlgorithmParameters AlgorithmParameterSpec AlgorithmParametersSpi AllPermission AlphaComposite + AlreadyBoundException AlreadyConnectedException AncestorEvent AncestorListener AnnotatedElement + Annotation AnnotationFormatError AnnotationTypeMismatchException AppConfigurationEntry Appendable Applet + AppletContext AppletInitializer AppletStub Arc2D Area AreaAveragingScaleFilter ArithmeticException Array + ArrayBlockingQueue ArrayIndexOutOfBoundsException ArrayList Arrays ArrayStoreException ArrayType + AssertionError AsyncBoxView AsynchronousCloseException AtomicBoolean AtomicInteger AtomicIntegerArray + AtomicIntegerFieldUpdater AtomicLong AtomicLongArray AtomicLongFieldUpdater AtomicMarkableReference + AtomicReference AtomicReferenceArray AtomicReferenceFieldUpdater AtomicStampedReference Attribute + AttributeChangeNotification AttributeChangeNotificationFilter AttributedCharacterIterator + AttributedString AttributeException AttributeInUseException AttributeList AttributeModificationException + AttributeNotFoundException Attributes AttributeSet AttributeSetUtilities AttributeValueExp AudioClip + AudioFileFormat AudioFileReader AudioFileWriter AudioFormat AudioInputStream AudioPermission AudioSystem + AuthenticationException AuthenticationNotSupportedException Authenticator AuthorizeCallback + AuthPermission AuthProvider Autoscroll AWTError AWTEvent AWTEventListener AWTEventListenerProxy + AWTEventMulticaster AWTException AWTKeyStroke AWTPermission BackingStoreException + BadAttributeValueExpException BadBinaryOpValueExpException BadLocationException BadPaddingException + BadStringOperationException BandCombineOp BandedSampleModel BaseRowSet BasicArrowButton BasicAttribute + BasicAttributes BasicBorders BasicButtonListener BasicButtonUI BasicCheckBoxMenuItemUI BasicCheckBoxUI + BasicColorChooserUI BasicComboBoxEditor BasicComboBoxRenderer BasicComboBoxUI BasicComboPopup + BasicControl BasicDesktopIconUI BasicDesktopPaneUI BasicDirectoryModel BasicEditorPaneUI + BasicFileChooserUI BasicFormattedTextFieldUI BasicGraphicsUtils BasicHTML BasicIconFactory + BasicInternalFrameTitlePane BasicInternalFrameUI BasicLabelUI BasicListUI BasicLookAndFeel + BasicMenuBarUI BasicMenuItemUI BasicMenuUI BasicOptionPaneUI BasicPanelUI BasicPasswordFieldUI + BasicPermission BasicPopupMenuSeparatorUI BasicPopupMenuUI BasicProgressBarUI BasicRadioButtonMenuItemUI + BasicRadioButtonUI BasicRootPaneUI BasicScrollBarUI BasicScrollPaneUI BasicSeparatorUI BasicSliderUI + BasicSpinnerUI BasicSplitPaneDivider BasicSplitPaneUI BasicStroke BasicTabbedPaneUI BasicTableHeaderUI + BasicTableUI BasicTextAreaUI BasicTextFieldUI BasicTextPaneUI BasicTextUI BasicToggleButtonUI + BasicToolBarSeparatorUI BasicToolBarUI BasicToolTipUI BasicTreeUI BasicViewportUI BatchUpdateException + BeanContext BeanContextChild BeanContextChildComponentProxy BeanContextChildSupport + BeanContextContainerProxy BeanContextEvent BeanContextMembershipEvent BeanContextMembershipListener + BeanContextProxy BeanContextServiceAvailableEvent BeanContextServiceProvider + BeanContextServiceProviderBeanInfo BeanContextServiceRevokedEvent BeanContextServiceRevokedListener + BeanContextServices BeanContextServicesListener BeanContextServicesSupport BeanContextSupport + BeanDescriptor BeanInfo Beans BevelBorder Bidi BigDecimal BigInteger BinaryRefAddr BindException Binding + BitSet Blob BlockingQueue BlockView BMPImageWriteParam Book Boolean BooleanControl Border BorderFactory + BorderLayout BorderUIResource BoundedRangeModel Box BoxLayout BoxView BreakIterator + BrokenBarrierException Buffer BufferCapabilities BufferedImage BufferedImageFilter BufferedImageOp + BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter BufferOverflowException + BufferStrategy BufferUnderflowException Button ButtonGroup ButtonModel ButtonUI Byte + ByteArrayInputStream ByteArrayOutputStream ByteBuffer ByteChannel ByteLookupTable ByteOrder CachedRowSet + CacheRequest CacheResponse Calendar Callable CallableStatement Callback CallbackHandler + CancelablePrintJob CancellationException CancelledKeyException CannotProceedException + CannotRedoException CannotUndoException Canvas CardLayout Caret CaretEvent CaretListener CellEditor + CellEditorListener CellRendererPane Certificate CertificateEncodingException CertificateException + CertificateExpiredException CertificateFactory CertificateFactorySpi CertificateNotYetValidException + CertificateParsingException CertPath CertPathBuilder CertPathBuilderException CertPathBuilderResult + CertPathBuilderSpi CertPathParameters CertPathTrustManagerParameters CertPathValidator + CertPathValidatorException CertPathValidatorResult CertPathValidatorSpi CertSelector CertStore + CertStoreException CertStoreParameters CertStoreSpi ChangedCharSetException ChangeEvent ChangeListener + Channel Channels Character CharacterCodingException CharacterIterator CharArrayReader CharArrayWriter + CharBuffer CharConversionException CharSequence Charset CharsetDecoder CharsetEncoder CharsetProvider + Checkbox CheckboxGroup CheckboxMenuItem CheckedInputStream CheckedOutputStream Checksum Choice + ChoiceCallback ChoiceFormat Chromaticity Cipher CipherInputStream CipherOutputStream CipherSpi Class + ClassCastException ClassCircularityError ClassDefinition ClassDesc ClassFileTransformer ClassFormatError + ClassLoader ClassLoaderRepository ClassLoadingMXBean ClassNotFoundException Clip Clipboard + ClipboardOwner Clob Cloneable CloneNotSupportedException Closeable ClosedByInterruptException + ClosedChannelException ClosedSelectorException CMMException CoderMalfunctionError CoderResult CodeSigner + CodeSource CodingErrorAction CollationElementIterator CollationKey Collator Collection + CollectionCertStoreParameters Collections Color ColorChooserComponentFactory ColorChooserUI + ColorConvertOp ColorModel ColorSelectionModel ColorSpace ColorSupported ColorType ColorUIResource + ComboBoxEditor ComboBoxModel ComboBoxUI ComboPopup CommunicationException Comparable Comparator + CompilationMXBean Compiler CompletionService Component ComponentAdapter ComponentColorModel + ComponentEvent ComponentInputMap ComponentInputMapUIResource ComponentListener ComponentOrientation + ComponentSampleModel ComponentUI ComponentView Composite CompositeContext CompositeData + CompositeDataSupport CompositeName CompositeType CompositeView CompoundBorder CompoundControl + CompoundEdit CompoundName Compression ConcurrentHashMap ConcurrentLinkedQueue ConcurrentMap + ConcurrentModificationException Condition Configuration ConfigurationException ConfirmationCallback + ConnectException ConnectIOException Connection ConnectionEvent ConnectionEventListener + ConnectionPendingException ConnectionPoolDataSource ConsoleHandler Constructor Container + ContainerAdapter ContainerEvent ContainerListener ContainerOrderFocusTraversalPolicy ContentHandler + ContentHandlerFactory ContentModel Context ContextNotEmptyException ContextualRenderedImageFactory + Control ControlFactory ControllerEventListener ConvolveOp CookieHandler Copies CopiesSupported + CopyOnWriteArrayList CopyOnWriteArraySet CountDownLatch CounterMonitor CounterMonitorMBean CRC32 + CredentialException CredentialExpiredException CredentialNotFoundException CRL CRLException CRLSelector + CropImageFilter CSS CubicCurve2D Currency Cursor Customizer CyclicBarrier DatabaseMetaData DataBuffer + DataBufferByte DataBufferDouble DataBufferFloat DataBufferInt DataBufferShort DataBufferUShort + DataFlavor DataFormatException DatagramChannel DatagramPacket DatagramSocket DatagramSocketImpl + DatagramSocketImplFactory DataInput DataInputStream DataLine DataOutput DataOutputStream DataSource + DataTruncation DatatypeConfigurationException DatatypeConstants DatatypeFactory Date DateFormat + DateFormatSymbols DateFormatter DateTimeAtCompleted DateTimeAtCreation DateTimeAtProcessing + DateTimeSyntax DebugGraphics DecimalFormat DecimalFormatSymbols DefaultBoundedRangeModel + DefaultButtonModel DefaultCaret DefaultCellEditor DefaultColorSelectionModel DefaultComboBoxModel + DefaultDesktopManager DefaultEditorKit DefaultFocusManager DefaultFocusTraversalPolicy DefaultFormatter + DefaultFormatterFactory DefaultHighlighter DefaultKeyboardFocusManager DefaultListCellRenderer + DefaultListModel DefaultListSelectionModel DefaultLoaderRepository DefaultMenuLayout DefaultMetalTheme + DefaultMutableTreeNode DefaultPersistenceDelegate DefaultSingleSelectionModel DefaultStyledDocument + DefaultTableCellRenderer DefaultTableColumnModel DefaultTableModel DefaultTextUI DefaultTreeCellEditor + DefaultTreeCellRenderer DefaultTreeModel DefaultTreeSelectionModel Deflater DeflaterOutputStream Delayed + DelayQueue DelegationPermission Deprecated Descriptor DescriptorAccess DescriptorSupport DESedeKeySpec + DesignMode DESKeySpec DesktopIconUI DesktopManager DesktopPaneUI Destination Destroyable + DestroyFailedException DGC DHGenParameterSpec DHKey DHParameterSpec DHPrivateKey DHPrivateKeySpec + DHPublicKey DHPublicKeySpec Dialog Dictionary DigestException DigestInputStream DigestOutputStream + Dimension Dimension2D DimensionUIResource DirContext DirectColorModel DirectoryManager DirObjectFactory + DirStateFactory DisplayMode DnDConstants Doc DocAttribute DocAttributeSet DocFlavor DocPrintJob Document + DocumentBuilder DocumentBuilderFactory Documented DocumentEvent DocumentFilter DocumentListener + DocumentName DocumentParser DomainCombiner DOMLocator DOMResult DOMSource Double DoubleBuffer + DragGestureEvent DragGestureListener DragGestureRecognizer DragSource DragSourceAdapter + DragSourceContext DragSourceDragEvent DragSourceDropEvent DragSourceEvent DragSourceListener + DragSourceMotionListener Driver DriverManager DriverPropertyInfo DropTarget DropTargetAdapter + DropTargetContext DropTargetDragEvent DropTargetDropEvent DropTargetEvent DropTargetListener DSAKey + DSAKeyPairGenerator DSAParameterSpec DSAParams DSAPrivateKey DSAPrivateKeySpec DSAPublicKey + DSAPublicKeySpec DTD DTDConstants DuplicateFormatFlagsException Duration DynamicMBean ECField ECFieldF2m + ECFieldFp ECGenParameterSpec ECKey ECParameterSpec ECPoint ECPrivateKey ECPrivateKeySpec ECPublicKey + ECPublicKeySpec EditorKit Element ElementIterator ElementType Ellipse2D EllipticCurve EmptyBorder + EmptyStackException EncodedKeySpec Encoder EncryptedPrivateKeyInfo Entity Enum + EnumConstantNotPresentException EnumControl Enumeration EnumMap EnumSet EnumSyntax EOFException Error + ErrorListener ErrorManager EtchedBorder Event EventContext EventDirContext EventHandler EventListener + EventListenerList EventListenerProxy EventObject EventQueue EventSetDescriptor Exception + ExceptionInInitializerError ExceptionListener Exchanger ExecutionException Executor + ExecutorCompletionService Executors ExecutorService ExemptionMechanism ExemptionMechanismException + ExemptionMechanismSpi ExpandVetoException ExportException Expression ExtendedRequest ExtendedResponse + Externalizable FactoryConfigurationError FailedLoginException FeatureDescriptor Fidelity Field + FieldPosition FieldView File FileCacheImageInputStream FileCacheImageOutputStream FileChannel + FileChooserUI FileDescriptor FileDialog FileFilter FileHandler FileImageInputStream + FileImageOutputStream FileInputStream FileLock FileLockInterruptionException FilenameFilter FileNameMap + FileNotFoundException FileOutputStream FilePermission FileReader FileSystemView FileView FileWriter + Filter FilteredImageSource FilteredRowSet FilterInputStream FilterOutputStream FilterReader FilterWriter + Finishings FixedHeightLayoutCache FlatteningPathIterator FlavorEvent FlavorException FlavorListener + FlavorMap FlavorTable Float FloatBuffer FloatControl FlowLayout FlowView Flushable FocusAdapter + FocusEvent FocusListener FocusManager FocusTraversalPolicy Font FontFormatException FontMetrics + FontRenderContext FontUIResource Format FormatConversionProvider FormatFlagsConversionMismatchException + Formattable FormattableFlags Formatter FormatterClosedException FormSubmitEvent FormView Frame Future + FutureTask GapContent GarbageCollectorMXBean GatheringByteChannel GaugeMonitor GaugeMonitorMBean + GeneralPath GeneralSecurityException GenericArrayType GenericDeclaration GenericSignatureFormatError + GlyphJustificationInfo GlyphMetrics GlyphVector GlyphView GradientPaint GraphicAttribute Graphics + Graphics2D GraphicsConfigTemplate GraphicsConfiguration GraphicsDevice GraphicsEnvironment GrayFilter + GregorianCalendar GridBagConstraints GridBagLayout GridLayout Group Guard GuardedObject GZIPInputStream + GZIPOutputStream Handler HandshakeCompletedEvent HandshakeCompletedListener HasControls HashAttributeSet + HashDocAttributeSet HashMap HashPrintJobAttributeSet HashPrintRequestAttributeSet + HashPrintServiceAttributeSet HashSet Hashtable HeadlessException HierarchyBoundsAdapter + HierarchyBoundsListener HierarchyEvent HierarchyListener Highlighter HostnameVerifier HTML HTMLDocument + HTMLEditorKit HTMLFrameHyperlinkEvent HTMLWriter HttpRetryException HttpsURLConnection HttpURLConnection + HyperlinkEvent HyperlinkListener ICC_ColorSpace ICC_Profile ICC_ProfileGray ICC_ProfileRGB Icon + IconUIResource IconView Identity IdentityHashMap IdentityScope IIOByteBuffer IIOException IIOImage + IIOInvalidTreeException IIOMetadata IIOMetadataController IIOMetadataFormat IIOMetadataFormatImpl + IIOMetadataNode IIOParam IIOParamController IIOReadProgressListener IIOReadUpdateListener + IIOReadWarningListener IIORegistry IIOServiceProvider IIOWriteProgressListener IIOWriteWarningListener + IllegalAccessError IllegalAccessException IllegalArgumentException IllegalBlockingModeException + IllegalBlockSizeException IllegalCharsetNameException IllegalClassFormatException + IllegalComponentStateException IllegalFormatCodePointException IllegalFormatConversionException + IllegalFormatException IllegalFormatFlagsException IllegalFormatPrecisionException + IllegalFormatWidthException IllegalMonitorStateException IllegalPathStateException + IllegalSelectorException IllegalStateException IllegalThreadStateException Image ImageCapabilities + ImageConsumer ImageFilter ImageGraphicAttribute ImageIcon ImageInputStream ImageInputStreamImpl + ImageInputStreamSpi ImageIO ImageObserver ImageOutputStream ImageOutputStreamImpl ImageOutputStreamSpi + ImageProducer ImageReader ImageReaderSpi ImageReaderWriterSpi ImageReadParam ImageTranscoder + ImageTranscoderSpi ImageTypeSpecifier ImageView ImageWriteParam ImageWriter ImageWriterSpi + ImagingOpException IncompatibleClassChangeError IncompleteAnnotationException IndexColorModel + IndexedPropertyChangeEvent IndexedPropertyDescriptor IndexOutOfBoundsException Inet4Address Inet6Address + InetAddress InetSocketAddress Inflater InflaterInputStream InheritableThreadLocal Inherited + InitialContext InitialContextFactory InitialContextFactoryBuilder InitialDirContext InitialLdapContext + InlineView InputContext InputEvent InputMap InputMapUIResource InputMethod InputMethodContext + InputMethodDescriptor InputMethodEvent InputMethodHighlight InputMethodListener InputMethodRequests + InputMismatchException InputStream InputStreamReader InputSubset InputVerifier Insets InsetsUIResource + InstanceAlreadyExistsException InstanceNotFoundException InstantiationError InstantiationException + Instrument Instrumentation InsufficientResourcesException IntBuffer Integer IntegerSyntax InternalError + InternalFrameAdapter InternalFrameEvent InternalFrameFocusTraversalPolicy InternalFrameListener + InternalFrameUI InternationalFormatter InterruptedException InterruptedIOException + InterruptedNamingException InterruptibleChannel IntrospectionException Introspector + InvalidActivityException InvalidAlgorithmParameterException InvalidApplicationException + InvalidAttributeIdentifierException InvalidAttributesException InvalidAttributeValueException + InvalidClassException InvalidDnDOperationException InvalidKeyException InvalidKeySpecException + InvalidMarkException InvalidMidiDataException InvalidNameException InvalidObjectException + InvalidOpenTypeException InvalidParameterException InvalidParameterSpecException + InvalidPreferencesFormatException InvalidPropertiesFormatException InvalidRelationIdException + InvalidRelationServiceException InvalidRelationTypeException InvalidRoleInfoException + InvalidRoleValueException InvalidSearchControlsException InvalidSearchFilterException + InvalidTargetObjectTypeException InvalidTransactionException InvocationEvent InvocationHandler + InvocationTargetException IOException ItemEvent ItemListener ItemSelectable Iterable Iterator + IvParameterSpec JApplet JarEntry JarException JarFile JarInputStream JarOutputStream JarURLConnection + JButton JCheckBox JCheckBoxMenuItem JColorChooser JComboBox JComponent JdbcRowSet JDesktopPane JDialog + JEditorPane JFileChooser JFormattedTextField JFrame JInternalFrame JLabel JLayeredPane JList JMenu + JMenuBar JMenuItem JMException JMRuntimeException JMXAuthenticator JMXConnectionNotification + JMXConnector JMXConnectorFactory JMXConnectorProvider JMXConnectorServer JMXConnectorServerFactory + JMXConnectorServerMBean JMXConnectorServerProvider JMXPrincipal JMXProviderException + JMXServerErrorException JMXServiceURL JobAttributes JobHoldUntil JobImpressions JobImpressionsCompleted + JobImpressionsSupported JobKOctets JobKOctetsProcessed JobKOctetsSupported JobMediaSheets + JobMediaSheetsCompleted JobMediaSheetsSupported JobMessageFromOperator JobName JobOriginatingUserName + JobPriority JobPrioritySupported JobSheets JobState JobStateReason JobStateReasons Joinable JoinRowSet + JOptionPane JPanel JPasswordField JPEGHuffmanTable JPEGImageReadParam JPEGImageWriteParam JPEGQTable + JPopupMenu JProgressBar JRadioButton JRadioButtonMenuItem JRootPane JScrollBar JScrollPane JSeparator + JSlider JSpinner JSplitPane JTabbedPane JTable JTableHeader JTextArea JTextComponent JTextField + JTextPane JToggleButton JToolBar JToolTip JTree JViewport JWindow KerberosKey KerberosPrincipal + KerberosTicket Kernel Key KeyAdapter KeyAgreement KeyAgreementSpi KeyAlreadyExistsException + KeyboardFocusManager KeyEvent KeyEventDispatcher KeyEventPostProcessor KeyException KeyFactory + KeyFactorySpi KeyGenerator KeyGeneratorSpi KeyListener KeyManagementException KeyManager + KeyManagerFactory KeyManagerFactorySpi Keymap KeyPair KeyPairGenerator KeyPairGeneratorSpi KeyRep + KeySpec KeyStore KeyStoreBuilderParameters KeyStoreException KeyStoreSpi KeyStroke Label LabelUI + LabelView LanguageCallback LastOwnerException LayeredHighlighter LayoutFocusTraversalPolicy + LayoutManager LayoutManager2 LayoutQueue LDAPCertStoreParameters LdapContext LdapName + LdapReferralException Lease Level LimitExceededException Line Line2D LineBorder LineBreakMeasurer + LineEvent LineListener LineMetrics LineNumberInputStream LineNumberReader LineUnavailableException + LinkageError LinkedBlockingQueue LinkedHashMap LinkedHashSet LinkedList LinkException LinkLoopException + LinkRef List ListCellRenderer ListDataEvent ListDataListener ListenerNotFoundException ListIterator + ListModel ListResourceBundle ListSelectionEvent ListSelectionListener ListSelectionModel ListUI ListView + LoaderHandler Locale LocateRegistry Lock LockSupport Logger LoggingMXBean LoggingPermission LoginContext + LoginException LoginModule LogManager LogRecord LogStream Long LongBuffer LookAndFeel LookupOp + LookupTable Mac MacSpi MalformedInputException MalformedLinkException MalformedObjectNameException + MalformedParameterizedTypeException MalformedURLException ManagementFactory ManagementPermission + ManageReferralControl ManagerFactoryParameters Manifest Map MappedByteBuffer MarshalException + MarshalledObject MaskFormatter Matcher MatchResult Math MathContext MatteBorder MBeanAttributeInfo + MBeanConstructorInfo MBeanException MBeanFeatureInfo MBeanInfo MBeanNotificationInfo MBeanOperationInfo + MBeanParameterInfo MBeanPermission MBeanRegistration MBeanRegistrationException MBeanServer + MBeanServerBuilder MBeanServerConnection MBeanServerDelegate MBeanServerDelegateMBean MBeanServerFactory + MBeanServerForwarder MBeanServerInvocationHandler MBeanServerNotification MBeanServerNotificationFilter + MBeanServerPermission MBeanTrustPermission Media MediaName MediaPrintableArea MediaSize MediaSizeName + MediaTracker MediaTray Member MemoryCacheImageInputStream MemoryCacheImageOutputStream MemoryHandler + MemoryImageSource MemoryManagerMXBean MemoryMXBean MemoryNotificationInfo MemoryPoolMXBean MemoryType + MemoryUsage Menu MenuBar MenuBarUI MenuComponent MenuContainer MenuDragMouseEvent MenuDragMouseListener + MenuElement MenuEvent MenuItem MenuItemUI MenuKeyEvent MenuKeyListener MenuListener MenuSelectionManager + MenuShortcut MessageDigest MessageDigestSpi MessageFormat MetaEventListener MetalBorders MetalButtonUI + MetalCheckBoxIcon MetalCheckBoxUI MetalComboBoxButton MetalComboBoxEditor MetalComboBoxIcon + MetalComboBoxUI MetalDesktopIconUI MetalFileChooserUI MetalIconFactory MetalInternalFrameTitlePane + MetalInternalFrameUI MetalLabelUI MetalLookAndFeel MetalMenuBarUI MetalPopupMenuSeparatorUI + MetalProgressBarUI MetalRadioButtonUI MetalRootPaneUI MetalScrollBarUI MetalScrollButton + MetalScrollPaneUI MetalSeparatorUI MetalSliderUI MetalSplitPaneUI MetalTabbedPaneUI MetalTextFieldUI + MetalTheme MetalToggleButtonUI MetalToolBarUI MetalToolTipUI MetalTreeUI MetaMessage Method + MethodDescriptor MGF1ParameterSpec MidiChannel MidiDevice MidiDeviceProvider MidiEvent MidiFileFormat + MidiFileReader MidiFileWriter MidiMessage MidiSystem MidiUnavailableException MimeTypeParseException + MinimalHTMLWriter MissingFormatArgumentException MissingFormatWidthException MissingResourceException + Mixer MixerProvider MLet MLetMBean ModelMBean ModelMBeanAttributeInfo ModelMBeanConstructorInfo + ModelMBeanInfo ModelMBeanInfoSupport ModelMBeanNotificationBroadcaster ModelMBeanNotificationInfo + ModelMBeanOperationInfo ModificationItem Modifier Monitor MonitorMBean MonitorNotification + MonitorSettingException MouseAdapter MouseDragGestureRecognizer MouseEvent MouseInfo MouseInputAdapter + MouseInputListener MouseListener MouseMotionAdapter MouseMotionListener MouseWheelEvent + MouseWheelListener MultiButtonUI MulticastSocket MultiColorChooserUI MultiComboBoxUI MultiDesktopIconUI + MultiDesktopPaneUI MultiDoc MultiDocPrintJob MultiDocPrintService MultiFileChooserUI + MultiInternalFrameUI MultiLabelUI MultiListUI MultiLookAndFeel MultiMenuBarUI MultiMenuItemUI + MultiOptionPaneUI MultiPanelUI MultiPixelPackedSampleModel MultipleDocumentHandling MultipleMaster + MultiPopupMenuUI MultiProgressBarUI MultiRootPaneUI MultiScrollBarUI MultiScrollPaneUI MultiSeparatorUI + MultiSliderUI MultiSpinnerUI MultiSplitPaneUI MultiTabbedPaneUI MultiTableHeaderUI MultiTableUI + MultiTextUI MultiToolBarUI MultiToolTipUI MultiTreeUI MultiViewportUI MutableAttributeSet + MutableComboBoxModel MutableTreeNode Name NameAlreadyBoundException NameCallback NameClassPair + NameNotFoundException NameParser NamespaceChangeListener NamespaceContext Naming NamingEnumeration + NamingEvent NamingException NamingExceptionEvent NamingListener NamingManager NamingSecurityException + NavigationFilter NegativeArraySizeException NetPermission NetworkInterface NoClassDefFoundError + NoConnectionPendingException NodeChangeEvent NodeChangeListener NoInitialContextException + NoninvertibleTransformException NonReadableChannelException NonWritableChannelException + NoPermissionException NoRouteToHostException NoSuchAlgorithmException NoSuchAttributeException + NoSuchElementException NoSuchFieldError NoSuchFieldException NoSuchMethodError NoSuchMethodException + NoSuchObjectException NoSuchPaddingException NoSuchProviderException NotActiveException + NotBoundException NotCompliantMBeanException NotContextException Notification NotificationBroadcaster + NotificationBroadcasterSupport NotificationEmitter NotificationFilter NotificationFilterSupport + NotificationListener NotificationResult NotOwnerException NotSerializableException NotYetBoundException + NotYetConnectedException NullCipher NullPointerException Number NumberFormat NumberFormatException + NumberFormatter NumberOfDocuments NumberOfInterveningJobs NumberUp NumberUpSupported NumericShaper + OAEPParameterSpec Object ObjectChangeListener ObjectFactory ObjectFactoryBuilder ObjectInput + ObjectInputStream ObjectInputValidation ObjectInstance ObjectName ObjectOutput ObjectOutputStream + ObjectStreamClass ObjectStreamConstants ObjectStreamException ObjectStreamField ObjectView ObjID + Observable Observer OceanTheme OpenDataException OpenMBeanAttributeInfo OpenMBeanAttributeInfoSupport + OpenMBeanConstructorInfo OpenMBeanConstructorInfoSupport OpenMBeanInfo OpenMBeanInfoSupport + OpenMBeanOperationInfo OpenMBeanOperationInfoSupport OpenMBeanParameterInfo + OpenMBeanParameterInfoSupport OpenType OperatingSystemMXBean Operation OperationNotSupportedException + OperationsException Option OptionalDataException OptionPaneUI OrientationRequested OutOfMemoryError + OutputDeviceAssigned OutputKeys OutputStream OutputStreamWriter OverlappingFileLockException + OverlayLayout Override Owner Pack200 Package PackedColorModel Pageable PageAttributes + PagedResultsControl PagedResultsResponseControl PageFormat PageRanges PagesPerMinute PagesPerMinuteColor + Paint PaintContext PaintEvent Panel PanelUI Paper ParagraphView ParameterBlock ParameterDescriptor + ParameterizedType ParameterMetaData ParseException ParsePosition Parser ParserConfigurationException + ParserDelegator PartialResultException PasswordAuthentication PasswordCallback PasswordView Patch + PathIterator Pattern PatternSyntaxException PBEKey PBEKeySpec PBEParameterSpec PDLOverrideSupported + Permission PermissionCollection Permissions PersistenceDelegate PersistentMBean PhantomReference Pipe + PipedInputStream PipedOutputStream PipedReader PipedWriter PixelGrabber PixelInterleavedSampleModel + PKCS8EncodedKeySpec PKIXBuilderParameters PKIXCertPathBuilderResult PKIXCertPathChecker + PKIXCertPathValidatorResult PKIXParameters PlainDocument PlainView Point Point2D PointerInfo Policy + PolicyNode PolicyQualifierInfo Polygon PooledConnection Popup PopupFactory PopupMenu PopupMenuEvent + PopupMenuListener PopupMenuUI Port PortableRemoteObject PortableRemoteObjectDelegate + PortUnreachableException Position Predicate PreferenceChangeEvent PreferenceChangeListener Preferences + PreferencesFactory PreparedStatement PresentationDirection Principal Printable PrinterAbortException + PrinterException PrinterGraphics PrinterInfo PrinterIOException PrinterIsAcceptingJobs PrinterJob + PrinterLocation PrinterMakeAndModel PrinterMessageFromOperator PrinterMoreInfo + PrinterMoreInfoManufacturer PrinterName PrinterResolution PrinterState PrinterStateReason + PrinterStateReasons PrinterURI PrintEvent PrintException PrintGraphics PrintJob PrintJobAdapter + PrintJobAttribute PrintJobAttributeEvent PrintJobAttributeListener PrintJobAttributeSet PrintJobEvent + PrintJobListener PrintQuality PrintRequestAttribute PrintRequestAttributeSet PrintService + PrintServiceAttribute PrintServiceAttributeEvent PrintServiceAttributeListener PrintServiceAttributeSet + PrintServiceLookup PrintStream PrintWriter PriorityBlockingQueue PriorityQueue PrivateClassLoader + PrivateCredentialPermission PrivateKey PrivateMLet PrivilegedAction PrivilegedActionException + PrivilegedExceptionAction Process ProcessBuilder ProfileDataException ProgressBarUI ProgressMonitor + ProgressMonitorInputStream Properties PropertyChangeEvent PropertyChangeListener + PropertyChangeListenerProxy PropertyChangeSupport PropertyDescriptor PropertyEditor + PropertyEditorManager PropertyEditorSupport PropertyPermission PropertyResourceBundle + PropertyVetoException ProtectionDomain ProtocolException Provider ProviderException Proxy ProxySelector + PSource PSSParameterSpec PublicKey PushbackInputStream PushbackReader QName QuadCurve2D Query QueryEval + QueryExp Queue QueuedJobCount Random RandomAccess RandomAccessFile Raster RasterFormatException RasterOp + RC2ParameterSpec RC5ParameterSpec Rdn Readable ReadableByteChannel Reader ReadOnlyBufferException + ReadWriteLock RealmCallback RealmChoiceCallback Receiver Rectangle Rectangle2D RectangularShape + ReentrantLock ReentrantReadWriteLock Ref RefAddr Reference Referenceable ReferenceQueue + ReferenceUriSchemesSupported ReferralException ReflectionException ReflectPermission Refreshable + RefreshFailedException Region RegisterableService Registry RegistryHandler RejectedExecutionException + RejectedExecutionHandler Relation RelationException RelationNotFoundException RelationNotification + RelationService RelationServiceMBean RelationServiceNotRegisteredException RelationSupport + RelationSupportMBean RelationType RelationTypeNotFoundException RelationTypeSupport Remote RemoteCall + RemoteException RemoteObject RemoteObjectInvocationHandler RemoteRef RemoteServer RemoteStub + RenderableImage RenderableImageOp RenderableImageProducer RenderContext RenderedImage + RenderedImageFactory Renderer RenderingHints RepaintManager ReplicateScaleFilter RequestingUserName + RequiredModelMBean RescaleOp ResolutionSyntax Resolver ResolveResult ResourceBundle ResponseCache Result + ResultSet ResultSetMetaData Retention RetentionPolicy ReverbType RGBImageFilter RMIClassLoader + RMIClassLoaderSpi RMIClientSocketFactory RMIConnection RMIConnectionImpl RMIConnectionImpl_Stub + RMIConnector RMIConnectorServer RMIFailureHandler RMIIIOPServerImpl RMIJRMPServerImpl + RMISecurityException RMISecurityManager RMIServer RMIServerImpl RMIServerImpl_Stub + RMIServerSocketFactory RMISocketFactory Robot Role RoleInfo RoleInfoNotFoundException RoleList + RoleNotFoundException RoleResult RoleStatus RoleUnresolved RoleUnresolvedList RootPaneContainer + RootPaneUI RoundingMode RoundRectangle2D RowMapper RowSet RowSetEvent RowSetInternal RowSetListener + RowSetMetaData RowSetMetaDataImpl RowSetReader RowSetWarning RowSetWriter RSAKey RSAKeyGenParameterSpec + RSAMultiPrimePrivateCrtKey RSAMultiPrimePrivateCrtKeySpec RSAOtherPrimeInfo RSAPrivateCrtKey + RSAPrivateCrtKeySpec RSAPrivateKey RSAPrivateKeySpec RSAPublicKey RSAPublicKeySpec RTFEditorKit + RuleBasedCollator Runnable Runtime RuntimeErrorException RuntimeException RuntimeMBeanException + RuntimeMXBean RuntimeOperationsException RuntimePermission SampleModel Sasl SaslClient SaslClientFactory + SaslException SaslServer SaslServerFactory Savepoint SAXParser SAXParserFactory SAXResult SAXSource + SAXTransformerFactory Scanner ScatteringByteChannel ScheduledExecutorService ScheduledFuture + ScheduledThreadPoolExecutor Schema SchemaFactory SchemaFactoryLoader SchemaViolationException Scrollable + Scrollbar ScrollBarUI ScrollPane ScrollPaneAdjustable ScrollPaneConstants ScrollPaneLayout ScrollPaneUI + SealedObject SearchControls SearchResult SecretKey SecretKeyFactory SecretKeyFactorySpi SecretKeySpec + SecureCacheResponse SecureClassLoader SecureRandom SecureRandomSpi Security SecurityException + SecurityManager SecurityPermission Segment SelectableChannel SelectionKey Selector SelectorProvider + Semaphore SeparatorUI Sequence SequenceInputStream Sequencer SerialArray SerialBlob SerialClob + SerialDatalink SerialException Serializable SerializablePermission SerialJavaObject SerialRef + SerialStruct ServerCloneException ServerError ServerException ServerNotActiveException ServerRef + ServerRuntimeException ServerSocket ServerSocketChannel ServerSocketFactory ServiceNotFoundException + ServicePermission ServiceRegistry ServiceUI ServiceUIFactory ServiceUnavailableException Set + SetOfIntegerSyntax Severity Shape ShapeGraphicAttribute SheetCollate Short ShortBuffer + ShortBufferException ShortLookupTable ShortMessage Sides Signature SignatureException SignatureSpi + SignedObject Signer SimpleAttributeSet SimpleBeanInfo SimpleDateFormat SimpleDoc SimpleFormatter + SimpleTimeZone SimpleType SinglePixelPackedSampleModel SingleSelectionModel Size2DSyntax + SizeLimitExceededException SizeRequirements SizeSequence Skeleton SkeletonMismatchException + SkeletonNotFoundException SliderUI Socket SocketAddress SocketChannel SocketException SocketFactory + SocketHandler SocketImpl SocketImplFactory SocketOptions SocketPermission SocketSecurityException + SocketTimeoutException SoftBevelBorder SoftReference SortControl SortedMap SortedSet + SortingFocusTraversalPolicy SortKey SortResponseControl Soundbank SoundbankReader SoundbankResource + Source SourceDataLine SourceLocator SpinnerDateModel SpinnerListModel SpinnerModel SpinnerNumberModel + SpinnerUI SplitPaneUI Spring SpringLayout SQLData SQLException SQLInput SQLInputImpl SQLOutput + SQLOutputImpl SQLPermission SQLWarning SSLContext SSLContextSpi SSLEngine SSLEngineResult SSLException + SSLHandshakeException SSLKeyException SSLPeerUnverifiedException SSLPermission SSLProtocolException + SslRMIClientSocketFactory SslRMIServerSocketFactory SSLServerSocket SSLServerSocketFactory SSLSession + SSLSessionBindingEvent SSLSessionBindingListener SSLSessionContext SSLSocket SSLSocketFactory Stack + StackOverflowError StackTraceElement StandardMBean StartTlsRequest StartTlsResponse StateEdit + StateEditable StateFactory Statement StreamCorruptedException StreamHandler StreamPrintService + StreamPrintServiceFactory StreamResult StreamSource StreamTokenizer StrictMath String StringBuffer + StringBufferInputStream StringBuilder StringCharacterIterator StringContent + StringIndexOutOfBoundsException StringMonitor StringMonitorMBean StringReader StringRefAddr + StringSelection StringTokenizer StringValueExp StringWriter Stroke Struct Stub StubDelegate + StubNotFoundException Style StyleConstants StyleContext StyledDocument StyledEditorKit StyleSheet + Subject SubjectDelegationPermission SubjectDomainCombiner SupportedValuesAttribute SuppressWarnings + SwingConstants SwingPropertyChangeSupport SwingUtilities SyncFactory SyncFactoryException + SyncFailedException SynchronousQueue SyncProvider SyncProviderException SyncResolver SynthConstants + SynthContext Synthesizer SynthGraphicsUtils SynthLookAndFeel SynthPainter SynthStyle SynthStyleFactory + SysexMessage System SystemColor SystemFlavorMap TabableView TabbedPaneUI TabExpander TableCellEditor + TableCellRenderer TableColumn TableColumnModel TableColumnModelEvent TableColumnModelListener + TableHeaderUI TableModel TableModelEvent TableModelListener TableUI TableView TabSet TabStop TabularData + TabularDataSupport TabularType TagElement Target TargetDataLine TargetedNotification Templates + TemplatesHandler TextAction TextArea TextAttribute TextComponent TextEvent TextField TextHitInfo + TextInputCallback TextLayout TextListener TextMeasurer TextOutputCallback TextSyntax TextUI TexturePaint + Thread ThreadDeath ThreadFactory ThreadGroup ThreadInfo ThreadLocal ThreadMXBean ThreadPoolExecutor + Throwable Tie TileObserver Time TimeLimitExceededException TimeoutException Timer + TimerAlarmClockNotification TimerMBean TimerNotification TimerTask Timestamp TimeUnit TimeZone + TitledBorder ToolBarUI Toolkit ToolTipManager ToolTipUI TooManyListenersException Track + TransactionalWriter TransactionRequiredException TransactionRolledbackException Transferable + TransferHandler TransformAttribute Transformer TransformerConfigurationException TransformerException + TransformerFactory TransformerFactoryConfigurationError TransformerHandler Transmitter Transparency + TreeCellEditor TreeCellRenderer TreeExpansionEvent TreeExpansionListener TreeMap TreeModel + TreeModelEvent TreeModelListener TreeNode TreePath TreeSelectionEvent TreeSelectionListener + TreeSelectionModel TreeSet TreeUI TreeWillExpandListener TrustAnchor TrustManager TrustManagerFactory + TrustManagerFactorySpi Type TypeInfoProvider TypeNotPresentException Types TypeVariable UID UIDefaults + UIManager UIResource UndeclaredThrowableException UndoableEdit UndoableEditEvent UndoableEditListener + UndoableEditSupport UndoManager UnexpectedException UnicastRemoteObject UnknownError + UnknownFormatConversionException UnknownFormatFlagsException UnknownGroupException UnknownHostException + UnknownObjectException UnknownServiceException UnmappableCharacterException UnmarshalException + UnmodifiableClassException UnmodifiableSetException UnrecoverableEntryException + UnrecoverableKeyException Unreferenced UnresolvedAddressException UnresolvedPermission + UnsatisfiedLinkError UnsolicitedNotification UnsolicitedNotificationEvent + UnsolicitedNotificationListener UnsupportedAddressTypeException UnsupportedAudioFileException + UnsupportedCallbackException UnsupportedCharsetException UnsupportedClassVersionError + UnsupportedEncodingException UnsupportedFlavorException UnsupportedLookAndFeelException + UnsupportedOperationException URI URIException URIResolver URISyntax URISyntaxException URL + URLClassLoader URLConnection URLDecoder URLEncoder URLStreamHandler URLStreamHandlerFactory + UTFDataFormatException Util UtilDelegate Utilities UUID Validator ValidatorHandler ValueExp ValueHandler + ValueHandlerMultiFormat VariableHeightLayoutCache Vector VerifyError VetoableChangeListener + VetoableChangeListenerProxy VetoableChangeSupport View ViewFactory ViewportLayout ViewportUI + VirtualMachineError Visibility VMID VoiceStatus Void VolatileImage WeakHashMap WeakReference WebRowSet + WildcardType Window WindowAdapter WindowConstants WindowEvent WindowFocusListener WindowListener + WindowStateListener WrappedPlainView WritableByteChannel WritableRaster WritableRenderedImage + WriteAbortedException Writer X500Principal X500PrivateCredential X509Certificate X509CertSelector + X509CRL X509CRLEntry X509CRLSelector X509EncodedKeySpec X509ExtendedKeyManager X509Extension + X509KeyManager X509TrustManager XAConnection XADataSource XAException XAResource Xid XMLConstants + XMLDecoder XMLEncoder XMLFormatter XMLGregorianCalendar XMLParseException XmlReader XmlWriter XPath + XPathConstants XPathException XPathExpression XPathExpressionException XPathFactory + XPathFactoryConfigurationException XPathFunction XPathFunctionException XPathFunctionResolver + XPathVariableResolver ZipEntry ZipException ZipFile ZipInputStream ZipOutputStream ZoneView + ] + #:nocov: + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java_script.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java_script.rb new file mode 100644 index 0000000..9eb0a0a --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java_script.rb @@ -0,0 +1,237 @@ +module CodeRay +module Scanners + + # Scanner for JavaScript. + # + # Aliases: +ecmascript+, +ecma_script+, +javascript+ + class JavaScript < Scanner + + register_for :java_script + file_extension 'js' + + # The actual JavaScript keywords. + KEYWORDS = %w[ + break case catch continue default delete do else + finally for function if in instanceof new + return switch throw try typeof var void while with + ] # :nodoc: + PREDEFINED_CONSTANTS = %w[ + false null true undefined NaN Infinity + ] # :nodoc: + + MAGIC_VARIABLES = %w[ this arguments ] # :nodoc: arguments was introduced in JavaScript 1.4 + + KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[ + case delete in instanceof new return throw typeof with + ] # :nodoc: + + # Reserved for future use. + RESERVED_WORDS = %w[ + abstract boolean byte char class debugger double enum export extends + final float goto implements import int interface long native package + private protected public short static super synchronized throws transient + volatile + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(RESERVED_WORDS, :reserved). + add(PREDEFINED_CONSTANTS, :predefined_constant). + add(MAGIC_VARIABLES, :local_variable). + add(KEYWORDS, :keyword) # :nodoc: + + ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: + REGEXP_ESCAPE = / [bBdDsSwW] /x # :nodoc: + STRING_CONTENT_PATTERN = { + "'" => /[^\\']+/, + '"' => /[^\\"]+/, + '/' => /[^\\\/]+/, + } # :nodoc: + KEY_CHECK_PATTERN = { + "'" => / (?> [^\\']* (?: \\. [^\\']* )* ) ' \s* : /mx, + '"' => / (?> [^\\"]* (?: \\. [^\\"]* )* ) " \s* : /mx, + } # :nodoc: + + protected + + def setup + @state = :initial + end + + def scan_tokens encoder, options + + state, string_delimiter = options[:state] || @state + if string_delimiter + encoder.begin_group state + end + + value_expected = true + key_expected = false + function_expected = false + + until eos? + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + value_expected = true if !value_expected && match.index(?\n) + encoder.text_token match, :space + + elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .*() ) !mx) + value_expected = true + encoder.text_token match, :comment + state = :open_multi_line_comment if self[1] + + elsif check(/\.?\d/) + key_expected = value_expected = false + if match = scan(/0[xX][0-9A-Fa-f]+/) + encoder.text_token match, :hex + elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/) + encoder.text_token match, :octal + elsif match = scan(/\d+[fF]|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/) + encoder.text_token match, :float + elsif match = scan(/\d+/) + encoder.text_token match, :integer + end + + elsif value_expected && match = scan(/<([[:alpha:]]\w*) (?: [^\/>]*\/> | .*?<\/\1>)/xim) + # TODO: scan over nested tags + xml_scanner.tokenize match, :tokens => encoder + value_expected = false + next + + elsif match = scan(/ [-+*=<>?:;,!&^|(\[{~%]+ | \.(?!\d) /x) + value_expected = true + last_operator = match[-1] + key_expected = (last_operator == ?{) || (last_operator == ?,) + function_expected = false + encoder.text_token match, :operator + + elsif match = scan(/ [)\]}]+ /x) + function_expected = key_expected = value_expected = false + encoder.text_token match, :operator + + elsif match = scan(/ [$a-zA-Z_][A-Za-z_0-9$]* /x) + kind = IDENT_KIND[match] + value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match] + # TODO: labels + if kind == :ident + if match.index(?$) # $ allowed inside an identifier + kind = :predefined + elsif function_expected + kind = :function + elsif check(/\s*[=:]\s*function\b/) + kind = :function + elsif key_expected && check(/\s*:/) + kind = :key + end + end + function_expected = (kind == :keyword) && (match == 'function') + key_expected = false + encoder.text_token match, kind + + elsif match = scan(/["']/) + if key_expected && check(KEY_CHECK_PATTERN[match]) + state = :key + else + state = :string + end + encoder.begin_group state + string_delimiter = match + encoder.text_token match, :delimiter + + elsif value_expected && (match = scan(/\//)) + encoder.begin_group :regexp + state = :regexp + string_delimiter = '/' + encoder.text_token match, :delimiter + + elsif match = scan(/ \/ /x) + value_expected = true + key_expected = false + encoder.text_token match, :operator + + else + encoder.text_token getch, :error + + end + + when :string, :regexp, :key + if match = scan(STRING_CONTENT_PATTERN[string_delimiter]) + encoder.text_token match, :content + elsif match = scan(/["'\/]/) + encoder.text_token match, :delimiter + if state == :regexp + modifiers = scan(/[gim]+/) + encoder.text_token modifiers, :modifier if modifiers && !modifiers.empty? + end + encoder.end_group state + string_delimiter = nil + key_expected = value_expected = false + state = :initial + elsif state != :regexp && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)) + if string_delimiter == "'" && !(match == "\\\\" || match == "\\'") + encoder.text_token match, :content + else + encoder.text_token match, :char + end + elsif state == :regexp && match = scan(/ \\ (?: #{ESCAPE} | #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + encoder.text_token match, :char + elsif match = scan(/\\./m) + encoder.text_token match, :content + elsif match = scan(/ \\ | $ /x) + encoder.end_group state + encoder.text_token match, :error unless match.empty? + string_delimiter = nil + key_expected = value_expected = false + state = :initial + else + raise_inspect "else case #{string_delimiter} reached; %p not handled." % peek(1), encoder + end + + when :open_multi_line_comment + if match = scan(%r! .*? \*/ !mx) + state = :initial + else + match = scan(%r! .+ !mx) + end + value_expected = true + encoder.text_token match, :comment if match + + else + #:nocov: + raise_inspect 'Unknown state: %p' % [state], encoder + #:nocov: + + end + + end + + if options[:keep_state] + @state = state, string_delimiter + end + + if [:string, :regexp].include? state + encoder.end_group state + end + + encoder + end + + protected + + def reset_instance + super + @xml_scanner.reset if defined? @xml_scanner + end + + def xml_scanner + @xml_scanner ||= CodeRay.scanner :xml, :tokens => @tokens, :keep_tokens => true, :keep_state => false + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/json.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/json.rb new file mode 100644 index 0000000..b09970c --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/json.rb @@ -0,0 +1,98 @@ +module CodeRay +module Scanners + + # Scanner for JSON (JavaScript Object Notation). + class JSON < Scanner + + register_for :json + file_extension 'json' + + KINDS_NOT_LOC = [ + :float, :char, :content, :delimiter, + :error, :integer, :operator, :value, + ] # :nodoc: + + ESCAPE = / [bfnrt\\"\/] /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x # :nodoc: + KEY = / (?> (?: [^\\"]+ | \\. )* ) " \s* : /x + + protected + + def setup + @state = :initial + end + + # See http://json.org/ for a definition of the JSON lexic/grammar. + def scan_tokens encoder, options + state = options[:state] || @state + + if [:string, :key].include? state + encoder.begin_group state + end + + until eos? + + case state + + when :initial + if match = scan(/ \s+ /x) + encoder.text_token match, :space + elsif match = scan(/"/) + state = check(/#{KEY}/o) ? :key : :string + encoder.begin_group state + encoder.text_token match, :delimiter + elsif match = scan(/ [:,\[{\]}] /x) + encoder.text_token match, :operator + elsif match = scan(/ true | false | null /x) + encoder.text_token match, :value + elsif match = scan(/ -? (?: 0 | [1-9]\d* ) /x) + if scan(/ \.\d+ (?:[eE][-+]?\d+)? | [eE][-+]? \d+ /x) + match << matched + encoder.text_token match, :float + else + encoder.text_token match, :integer + end + else + encoder.text_token getch, :error + end + + when :string, :key + if match = scan(/[^\\"]+/) + encoder.text_token match, :content + elsif match = scan(/"/) + encoder.text_token match, :delimiter + encoder.end_group state + state = :initial + elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + encoder.text_token match, :char + elsif match = scan(/\\./m) + encoder.text_token match, :content + elsif match = scan(/ \\ | $ /x) + encoder.end_group state + encoder.text_token match, :error unless match.empty? + state = :initial + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder + end + + else + raise_inspect 'Unknown state: %p' % [state], encoder + + end + end + + if options[:keep_state] + @state = state + end + + if [:string, :key].include? state + encoder.end_group state + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/lua.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/lua.rb new file mode 100644 index 0000000..fb1e45a --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/lua.rb @@ -0,0 +1,280 @@ +# encoding: utf-8 + +module CodeRay +module Scanners + + # Scanner for the Lua[http://lua.org] programming lanuage. + # + # The language’s complete syntax is defined in + # {the Lua manual}[http://www.lua.org/manual/5.2/manual.html], + # which is what this scanner tries to conform to. + class Lua < Scanner + + register_for :lua + file_extension 'lua' + title 'Lua' + + # Keywords used in Lua. + KEYWORDS = %w[and break do else elseif end + for function goto if in + local not or repeat return + then until while + ] + + # Constants set by the Lua core. + PREDEFINED_CONSTANTS = %w[false true nil] + + # The expressions contained in this array are parts of Lua’s `basic' + # library. Although it’s not entirely necessary to load that library, + # it is highly recommended and one would have to provide own implementations + # of some of these expressions if one does not do so. They however aren’t + # keywords, neither are they constants, but nearly predefined, so they + # get tagged as `predefined' rather than anything else. + # + # This list excludes values of form `_UPPERCASE' because the Lua manual + # requires such identifiers to be reserved by Lua anyway and they are + # highlighted directly accordingly, without the need for specific + # identifiers to be listed here. + PREDEFINED_EXPRESSIONS = %w[ + assert collectgarbage dofile error getmetatable + ipairs load loadfile next pairs pcall print + rawequal rawget rawlen rawset select setmetatable + tonumber tostring type xpcall + ] + + # Automatic token kind selection for normal words. + IDENT_KIND = CodeRay::WordList.new(:ident). + add(KEYWORDS, :keyword). + add(PREDEFINED_CONSTANTS, :predefined_constant). + add(PREDEFINED_EXPRESSIONS, :predefined) + + protected + + # Scanner initialization. + def setup + @state = :initial + @brace_depth = 0 + end + + # CodeRay entry hook. Starts parsing. + def scan_tokens(encoder, options) + state = options[:state] || @state + brace_depth = @brace_depth + num_equals = nil + + until eos? + case state + + when :initial + if match = scan(/\-\-\[\=*\[/) #--[[ long (possibly multiline) comment ]] + num_equals = match.count("=") # Number must match for comment end + encoder.begin_group(:comment) + encoder.text_token(match, :delimiter) + state = :long_comment + + elsif match = scan(/--.*$/) # --Lua comment + encoder.text_token(match, :comment) + + elsif match = scan(/\[=*\[/) # [[ long (possibly multiline) string ]] + num_equals = match.count("=") # Number must match for comment end + encoder.begin_group(:string) + encoder.text_token(match, :delimiter) + state = :long_string + + elsif match = scan(/::\s*[a-zA-Z_][a-zA-Z0-9_]+\s*::/) # ::goto_label:: + encoder.text_token(match, :label) + + elsif match = scan(/_[A-Z]+/) # _UPPERCASE are names reserved for Lua + encoder.text_token(match, :predefined) + + elsif match = scan(/[a-zA-Z_][a-zA-Z0-9_]*/) # Normal letters (or letters followed by digits) + kind = IDENT_KIND[match] + + # Extra highlighting for entities following certain keywords + if kind == :keyword and match == "function" + state = :function_expected + elsif kind == :keyword and match == "goto" + state = :goto_label_expected + elsif kind == :keyword and match == "local" + state = :local_var_expected + end + + encoder.text_token(match, kind) + + elsif match = scan(/\{/) # Opening table brace { + encoder.begin_group(:map) + encoder.text_token(match, brace_depth >= 1 ? :inline_delimiter : :delimiter) + brace_depth += 1 + state = :map + + elsif match = scan(/\}/) # Closing table brace } + if brace_depth == 1 + brace_depth = 0 + encoder.text_token(match, :delimiter) + encoder.end_group(:map) + elsif brace_depth == 0 # Mismatched brace + encoder.text_token(match, :error) + else + brace_depth -= 1 + encoder.text_token(match, :inline_delimiter) + encoder.end_group(:map) + state = :map + end + + elsif match = scan(/["']/) # String delimiters " and ' + encoder.begin_group(:string) + encoder.text_token(match, :delimiter) + start_delim = match + state = :string + + # ↓Prefix hex number ←|→ decimal number + elsif match = scan(/-? (?:0x\h* \. \h+ (?:p[+\-]?\d+)? | \d*\.\d+ (?:e[+\-]?\d+)?)/ix) # hexadecimal constants have no E power, decimal ones no P power + encoder.text_token(match, :float) + + # ↓Prefix hex number ←|→ decimal number + elsif match = scan(/-? (?:0x\h+ (?:p[+\-]?\d+)? | \d+ (?:e[+\-]?\d+)?)/ix) # hexadecimal constants have no E power, decimal ones no P power + encoder.text_token(match, :integer) + + elsif match = scan(/[\+\-\*\/%^\#=~<>\(\)\[\]:;,] | \.(?!\d)/x) # Operators + encoder.text_token(match, :operator) + + elsif match = scan(/\s+/) # Space + encoder.text_token(match, :space) + + else # Invalid stuff. Note that Lua doesn’t accept multibyte chars outside of strings, hence these are also errors. + encoder.text_token(getch, :error) + end + + # It may be that we’re scanning a full-blown subexpression of a table + # (tables can contain full expressions in parts). + # If this is the case, return to :map scanning state. + state = :map if state == :initial && brace_depth >= 1 + + when :function_expected + if match = scan(/\(.*?\)/m) # x = function() # "Anonymous" function without explicit name + encoder.text_token(match, :operator) + state = :initial + elsif match = scan(/[a-zA-Z_] (?:[a-zA-Z0-9_\.] (?!\.\d))* [\.\:]/x) # function tbl.subtbl.foo() | function tbl:foo() # Colon only allowed as last separator + encoder.text_token(match, :ident) + elsif match = scan(/[a-zA-Z_][a-zA-Z0-9_]*/) # function foo() + encoder.text_token(match, :function) + state = :initial + elsif match = scan(/\s+/) # Between the `function' keyword and the ident may be any amount of whitespace + encoder.text_token(match, :space) + else + encoder.text_token(getch, :error) + state = :initial + end + + when :goto_label_expected + if match = scan(/[a-zA-Z_][a-zA-Z0-9_]*/) + encoder.text_token(match, :label) + state = :initial + elsif match = scan(/\s+/) # Between the `goto' keyword and the label may be any amount of whitespace + encoder.text_token(match, :space) + else + encoder.text_token(getch, :error) + end + + when :local_var_expected + if match = scan(/function/) # local function ... + encoder.text_token(match, :keyword) + state = :function_expected + elsif match = scan(/[a-zA-Z_][a-zA-Z0-9_]*/) + encoder.text_token(match, :local_variable) + elsif match = scan(/,/) + encoder.text_token(match, :operator) + elsif match = scan(/\=/) + encoder.text_token(match, :operator) + # After encountering the equal sign, arbitrary expressions are + # allowed again, so just return to the main state for further + # parsing. + state = :initial + elsif match = scan(/\n/) + encoder.text_token(match, :space) + state = :initial + elsif match = scan(/\s+/) + encoder.text_token(match, :space) + else + encoder.text_token(getch, :error) + end + + when :long_comment + if match = scan(/.*?(?=\]={#{num_equals}}\])/m) + encoder.text_token(match, :content) + + delim = scan(/\]={#{num_equals}}\]/) + encoder.text_token(delim, :delimiter) + else # No terminator found till EOF + encoder.text_token(rest, :error) + terminate + end + encoder.end_group(:comment) + state = :initial + + when :long_string + if match = scan(/.*?(?=\]={#{num_equals}}\])/m) # Long strings do not interpret any escape sequences + encoder.text_token(match, :content) + + delim = scan(/\]={#{num_equals}}\]/) + encoder.text_token(delim, :delimiter) + else # No terminator found till EOF + encoder.text_token(rest, :error) + terminate + end + encoder.end_group(:string) + state = :initial + + when :string + if match = scan(/[^\\#{start_delim}\n]+/) # Everything except \ and the start delimiter character is string content (newlines are only allowed if preceeded by \ or \z) + encoder.text_token(match, :content) + elsif match = scan(/\\(?:['"abfnrtv\\]|z\s*|x\h\h|\d{1,3}|\n)/m) + encoder.text_token(match, :char) + elsif match = scan(Regexp.compile(start_delim)) + encoder.text_token(match, :delimiter) + encoder.end_group(:string) + state = :initial + elsif match = scan(/\n/) # Lua forbids unescaped newlines in normal non-long strings + encoder.text_token("\\n\n", :error) # Visually appealing error indicator--otherwise users may wonder whether the highlighter cannot highlight multine strings + encoder.end_group(:string) + state = :initial + else + encoder.text_token(getch, :error) + end + + when :map + if match = scan(/[,;]/) + encoder.text_token(match, :operator) + elsif match = scan(/[a-zA-Z_][a-zA-Z0-9_]* (?=\s*=)/x) + encoder.text_token(match, :key) + encoder.text_token(scan(/\s+/), :space) if check(/\s+/) + encoder.text_token(scan(/\=/), :operator) + state = :initial + elsif match = scan(/\s+/m) + encoder.text_token(match, :space) + else + # Note this clause doesn’t advance the scan pointer, it’s a kind of + # "retry with other options" (the :initial state then of course + # advances the pointer). + state = :initial + end + else + raise + end + + end + + if options[:keep_state] + @state = state + end + + encoder.end_group :string if [:string].include? state + brace_depth.times { encoder.end_group :map } + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/php.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/php.rb new file mode 100644 index 0000000..7a8d75d --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/php.rb @@ -0,0 +1,527 @@ +# encoding: utf-8 +module CodeRay +module Scanners + + load :html + + # Scanner for PHP. + # + # Original by Stefan Walk. + class PHP < Scanner + + register_for :php + file_extension 'php' + + KINDS_NOT_LOC = HTML::KINDS_NOT_LOC + + protected + + def setup + @html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true, :keep_state => true + end + + def reset_instance + super + @html_scanner.reset + end + + module Words # :nodoc: + + # according to http://www.php.net/manual/en/reserved.keywords.php + KEYWORDS = %w[ + abstract and array as break case catch class clone const continue declare default do else elseif + enddeclare endfor endforeach endif endswitch endwhile extends final for foreach function global + goto if implements interface instanceof namespace new or private protected public static switch + throw try use var while xor + cfunction old_function + ] + + TYPES = %w[ int integer float double bool boolean string array object resource ] + + LANGUAGE_CONSTRUCTS = %w[ + die echo empty exit eval include include_once isset list + require require_once return print unset + ] + + CLASSES = %w[ Directory stdClass __PHP_Incomplete_Class exception php_user_filter Closure ] + + # according to http://php.net/quickref.php on 2009-04-21; + # all functions with _ excluded (module functions) and selected additional functions + BUILTIN_FUNCTIONS = %w[ + abs acos acosh addcslashes addslashes aggregate array arsort ascii2ebcdic asin asinh asort assert atan atan2 + atanh basename bcadd bccomp bcdiv bcmod bcmul bcpow bcpowmod bcscale bcsqrt bcsub bin2hex bindec + bindtextdomain bzclose bzcompress bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite + calculhmac ceil chdir checkdate checkdnsrr chgrp chmod chop chown chr chroot clearstatcache closedir closelog + compact constant copy cos cosh count crc32 crypt current date dcgettext dcngettext deaggregate decbin dechex + decoct define defined deg2rad delete dgettext die dirname diskfreespace dl dngettext doubleval each + ebcdic2ascii echo empty end ereg eregi escapeshellarg escapeshellcmd eval exec exit exp explode expm1 extract + fclose feof fflush fgetc fgetcsv fgets fgetss file fileatime filectime filegroup fileinode filemtime fileowner + fileperms filepro filesize filetype floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv + fputs fread frenchtojd fscanf fseek fsockopen fstat ftell ftok ftruncate fwrite getallheaders getcwd getdate + getenv gethostbyaddr gethostbyname gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid + getmyuid getopt getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext + gettimeofday gettype glob gmdate gmmktime gmstrftime gregoriantojd gzclose gzcompress gzdecode gzdeflate + gzencode gzeof gzfile gzgetc gzgets gzgetss gzinflate gzopen gzpassthru gzputs gzread gzrewind gzseek gztell + gzuncompress gzwrite hash header hebrev hebrevc hexdec htmlentities htmlspecialchars hypot iconv idate + implode include intval ip2long iptcembed iptcparse isset + jddayofweek jdmonthname jdtofrench jdtogregorian jdtojewish jdtojulian jdtounix jewishtojd join jpeg2wbmp + juliantojd key krsort ksort lcfirst lchgrp lchown levenshtein link linkinfo list localeconv localtime log + log10 log1p long2ip lstat ltrim mail main max md5 metaphone mhash microtime min mkdir mktime msql natcasesort + natsort next ngettext nl2br nthmac octdec opendir openlog + ord overload pack passthru pathinfo pclose pfsockopen phpcredits phpinfo phpversion pi png2wbmp popen pos pow + prev print printf putenv quotemeta rad2deg rand range rawurldecode rawurlencode readdir readfile readgzfile + readline readlink realpath recode rename require reset rewind rewinddir rmdir round rsort rtrim scandir + serialize setcookie setlocale setrawcookie settype sha1 shuffle signeurlpaiement sin sinh sizeof sleep snmpget + snmpgetnext snmprealwalk snmpset snmpwalk snmpwalkoid sort soundex split spliti sprintf sqrt srand sscanf stat + strcasecmp strchr strcmp strcoll strcspn strftime stripcslashes stripos stripslashes stristr strlen + strnatcasecmp strnatcmp strncasecmp strncmp strpbrk strpos strptime strrchr strrev strripos strrpos strspn + strstr strtok strtolower strtotime strtoupper strtr strval substr symlink syslog system tan tanh tempnam + textdomain time tmpfile touch trim uasort ucfirst ucwords uksort umask uniqid unixtojd unlink unpack + unserialize unset urldecode urlencode usleep usort vfprintf virtual vprintf vsprintf wordwrap + array_change_key_case array_chunk array_combine array_count_values array_diff array_diff_assoc + array_diff_key array_diff_uassoc array_diff_ukey array_fill array_fill_keys array_filter array_flip + array_intersect array_intersect_assoc array_intersect_key array_intersect_uassoc array_intersect_ukey + array_key_exists array_keys array_map array_merge array_merge_recursive array_multisort array_pad + array_pop array_product array_push array_rand array_reduce array_reverse array_search array_shift + array_slice array_splice array_sum array_udiff array_udiff_assoc array_udiff_uassoc array_uintersect + array_uintersect_assoc array_uintersect_uassoc array_unique array_unshift array_values array_walk + array_walk_recursive + assert_options base_convert base64_decode base64_encode + chunk_split class_exists class_implements class_parents + count_chars debug_backtrace debug_print_backtrace debug_zval_dump + error_get_last error_log error_reporting extension_loaded + file_exists file_get_contents file_put_contents load_file + func_get_arg func_get_args func_num_args function_exists + get_browser get_called_class get_cfg_var get_class get_class_methods get_class_vars + get_current_user get_declared_classes get_declared_interfaces get_defined_constants + get_defined_functions get_defined_vars get_extension_funcs get_headers get_html_translation_table + get_include_path get_included_files get_loaded_extensions get_magic_quotes_gpc get_magic_quotes_runtime + get_meta_tags get_object_vars get_parent_class get_required_filesget_resource_type + gc_collect_cycles gc_disable gc_enable gc_enabled + halt_compiler headers_list headers_sent highlight_file highlight_string + html_entity_decode htmlspecialchars_decode + in_array include_once inclued_get_data + is_a is_array is_binary is_bool is_buffer is_callable is_dir is_double is_executable is_file is_finite + is_float is_infinite is_int is_integer is_link is_long is_nan is_null is_numeric is_object is_readable + is_real is_resource is_scalar is_soap_fault is_string is_subclass_of is_unicode is_uploaded_file + is_writable is_writeable + locale_get_default locale_set_default + number_format override_function parse_str parse_url + php_check_syntax php_ini_loaded_file php_ini_scanned_files php_logo_guid php_sapi_name + php_strip_whitespace php_uname + preg_filter preg_grep preg_last_error preg_match preg_match_all preg_quote preg_replace + preg_replace_callback preg_split print_r + require_once register_shutdown_function register_tick_function + set_error_handler set_exception_handler set_file_buffer set_include_path + set_magic_quotes_runtime set_time_limit shell_exec + str_getcsv str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split str_word_count + strip_tags substr_compare substr_count substr_replace + time_nanosleep time_sleep_until + token_get_all token_name trigger_error + unregister_tick_function use_soap_error_handler user_error + utf8_decode utf8_encode var_dump var_export + version_compare + zend_logo_guid zend_thread_id zend_version + create_function call_user_func_array + posix_access posix_ctermid posix_get_last_error posix_getcwd posix_getegid + posix_geteuid posix_getgid posix_getgrgid posix_getgrnam posix_getgroups + posix_getlogin posix_getpgid posix_getpgrp posix_getpid posix_getppid + posix_getpwnam posix_getpwuid posix_getrlimit posix_getsid posix_getuid + posix_initgroups posix_isatty posix_kill posix_mkfifo posix_mknod + posix_setegid posix_seteuid posix_setgid posix_setpgid posix_setsid + posix_setuid posix_strerror posix_times posix_ttyname posix_uname + pcntl_alarm pcntl_exec pcntl_fork pcntl_getpriority pcntl_setpriority + pcntl_signal pcntl_signal_dispatch pcntl_sigprocmask pcntl_sigtimedwait + pcntl_sigwaitinfo pcntl_wait pcntl_waitpid pcntl_wexitstatus pcntl_wifexited + pcntl_wifsignaled pcntl_wifstopped pcntl_wstopsig pcntl_wtermsig + ] + # TODO: more built-in PHP functions? + + EXCEPTIONS = %w[ + E_ERROR E_WARNING E_PARSE E_NOTICE E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING + E_USER_ERROR E_USER_WARNING E_USER_NOTICE E_DEPRECATED E_USER_DEPRECATED E_ALL E_STRICT + ] + + CONSTANTS = %w[ + null true false self parent + __LINE__ __DIR__ __FILE__ __LINE__ + __CLASS__ __NAMESPACE__ __METHOD__ __FUNCTION__ + PHP_VERSION PHP_MAJOR_VERSION PHP_MINOR_VERSION PHP_RELEASE_VERSION PHP_VERSION_ID PHP_EXTRA_VERSION PHP_ZTS + PHP_DEBUG PHP_MAXPATHLEN PHP_OS PHP_SAPI PHP_EOL PHP_INT_MAX PHP_INT_SIZE DEFAULT_INCLUDE_PATH + PEAR_INSTALL_DIR PEAR_EXTENSION_DIR PHP_EXTENSION_DIR PHP_PREFIX PHP_BINDIR PHP_LIBDIR PHP_DATADIR + PHP_SYSCONFDIR PHP_LOCALSTATEDIR PHP_CONFIG_FILE_PATH PHP_CONFIG_FILE_SCAN_DIR PHP_SHLIB_SUFFIX + PHP_OUTPUT_HANDLER_START PHP_OUTPUT_HANDLER_CONT PHP_OUTPUT_HANDLER_END + __COMPILER_HALT_OFFSET__ + EXTR_OVERWRITE EXTR_SKIP EXTR_PREFIX_SAME EXTR_PREFIX_ALL EXTR_PREFIX_INVALID EXTR_PREFIX_IF_EXISTS + EXTR_IF_EXISTS SORT_ASC SORT_DESC SORT_REGULAR SORT_NUMERIC SORT_STRING CASE_LOWER CASE_UPPER COUNT_NORMAL + COUNT_RECURSIVE ASSERT_ACTIVE ASSERT_CALLBACK ASSERT_BAIL ASSERT_WARNING ASSERT_QUIET_EVAL CONNECTION_ABORTED + CONNECTION_NORMAL CONNECTION_TIMEOUT INI_USER INI_PERDIR INI_SYSTEM INI_ALL M_E M_LOG2E M_LOG10E M_LN2 M_LN10 + M_PI M_PI_2 M_PI_4 M_1_PI M_2_PI M_2_SQRTPI M_SQRT2 M_SQRT1_2 CRYPT_SALT_LENGTH CRYPT_STD_DES CRYPT_EXT_DES + CRYPT_MD5 CRYPT_BLOWFISH DIRECTORY_SEPARATOR SEEK_SET SEEK_CUR SEEK_END LOCK_SH LOCK_EX LOCK_UN LOCK_NB + HTML_SPECIALCHARS HTML_ENTITIES ENT_COMPAT ENT_QUOTES ENT_NOQUOTES INFO_GENERAL INFO_CREDITS + INFO_CONFIGURATION INFO_MODULES INFO_ENVIRONMENT INFO_VARIABLES INFO_LICENSE INFO_ALL CREDITS_GROUP + CREDITS_GENERAL CREDITS_SAPI CREDITS_MODULES CREDITS_DOCS CREDITS_FULLPAGE CREDITS_QA CREDITS_ALL STR_PAD_LEFT + STR_PAD_RIGHT STR_PAD_BOTH PATHINFO_DIRNAME PATHINFO_BASENAME PATHINFO_EXTENSION PATH_SEPARATOR CHAR_MAX + LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_ALL LC_MESSAGES ABDAY_1 ABDAY_2 ABDAY_3 ABDAY_4 ABDAY_5 + ABDAY_6 ABDAY_7 DAY_1 DAY_2 DAY_3 DAY_4 DAY_5 DAY_6 DAY_7 ABMON_1 ABMON_2 ABMON_3 ABMON_4 ABMON_5 ABMON_6 + ABMON_7 ABMON_8 ABMON_9 ABMON_10 ABMON_11 ABMON_12 MON_1 MON_2 MON_3 MON_4 MON_5 MON_6 MON_7 MON_8 MON_9 + MON_10 MON_11 MON_12 AM_STR PM_STR D_T_FMT D_FMT T_FMT T_FMT_AMPM ERA ERA_YEAR ERA_D_T_FMT ERA_D_FMT ERA_T_FMT + ALT_DIGITS INT_CURR_SYMBOL CURRENCY_SYMBOL CRNCYSTR MON_DECIMAL_POINT MON_THOUSANDS_SEP MON_GROUPING + POSITIVE_SIGN NEGATIVE_SIGN INT_FRAC_DIGITS FRAC_DIGITS P_CS_PRECEDES P_SEP_BY_SPACE N_CS_PRECEDES + N_SEP_BY_SPACE P_SIGN_POSN N_SIGN_POSN DECIMAL_POINT RADIXCHAR THOUSANDS_SEP THOUSEP GROUPING YESEXPR NOEXPR + YESSTR NOSTR CODESET LOG_EMERG LOG_ALERT LOG_CRIT LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_DEBUG LOG_KERN + LOG_USER LOG_MAIL LOG_DAEMON LOG_AUTH LOG_SYSLOG LOG_LPR LOG_NEWS LOG_UUCP LOG_CRON LOG_AUTHPRIV LOG_LOCAL0 + LOG_LOCAL1 LOG_LOCAL2 LOG_LOCAL3 LOG_LOCAL4 LOG_LOCAL5 LOG_LOCAL6 LOG_LOCAL7 LOG_PID LOG_CONS LOG_ODELAY + LOG_NDELAY LOG_NOWAIT LOG_PERROR + ] + + PREDEFINED = %w[ + $GLOBALS $_SERVER $_GET $_POST $_FILES $_REQUEST $_SESSION $_ENV + $_COOKIE $php_errormsg $HTTP_RAW_POST_DATA $http_response_header + $argc $argv + ] + + IDENT_KIND = WordList::CaseIgnoring.new(:ident). + add(KEYWORDS, :keyword). + add(TYPES, :predefined_type). + add(LANGUAGE_CONSTRUCTS, :keyword). + add(BUILTIN_FUNCTIONS, :predefined). + add(CLASSES, :predefined_constant). + add(EXCEPTIONS, :exception). + add(CONSTANTS, :predefined_constant) + + VARIABLE_KIND = WordList.new(:local_variable). + add(PREDEFINED, :predefined) + end + + module RE # :nodoc: + + PHP_START = / + ]*?language\s*=\s*"php"[^>]*?> | + ]*?language\s*=\s*'php'[^>]*?> | + <\?php\d? | + <\?(?!xml) + /xi + + PHP_END = %r! + | + \?> + !xi + + HTML_INDICATOR = / ]/i + + IDENTIFIER = 'ä'[/[[:alpha:]]/] == 'ä' ? Regexp.new('[[:alpha:]_[^\0-\177]][[:alnum:]_[^\0-\177]]*') : Regexp.new('[a-z_\x7f-\xFF][a-z0-9_\x7f-\xFF]*', true) + VARIABLE = /\$#{IDENTIFIER}/ + + OPERATOR = / + \.(?!\d)=? | # dot that is not decimal point, string concatenation + && | \|\| | # logic + :: | -> | => | # scope, member, dictionary + \\(?!\n) | # namespace + \+\+ | -- | # increment, decrement + [,;?:()\[\]{}] | # simple delimiters + [-+*\/%&|^]=? | # ordinary math, binary logic, assignment shortcuts + [~$] | # whatever + =& | # reference assignment + [=!]=?=? | <> | # comparison and assignment + <<=? | >>=? | [<>]=? # comparison and shift + /x + + end + + protected + + def scan_tokens encoder, options + + if check(RE::PHP_START) || # starts with #{RE::IDENTIFIER}/o) + encoder.begin_group :inline + encoder.text_token match, :local_variable + encoder.text_token scan(/->/), :operator + encoder.text_token scan(/#{RE::IDENTIFIER}/o), :ident + encoder.end_group :inline + elsif check(/->/) + match << scan(/->/) + encoder.text_token match, :error + else + encoder.text_token match, :local_variable + end + elsif match = scan(/\{/) + if check(/\$/) + encoder.begin_group :inline + states[-1] = [states.last, delimiter] + delimiter = nil + states.push :php_inline + encoder.text_token match, :delimiter + else + encoder.text_token match, :content + end + elsif match = scan(/\$\{#{RE::IDENTIFIER}\}/o) + encoder.text_token match, :local_variable + elsif match = scan(/\$/) + encoder.text_token match, :content + else + encoder.end_group :string + states.pop + end + + when :class_expected + if match = scan(/\s+/) + encoder.text_token match, :space + elsif match = scan(/#{RE::IDENTIFIER}/o) + encoder.text_token match, :class + states.pop + else + states.pop + end + + when :function_expected + if match = scan(/\s+/) + encoder.text_token match, :space + elsif match = scan(/&/) + encoder.text_token match, :operator + elsif match = scan(/#{RE::IDENTIFIER}/o) + encoder.text_token match, :function + states.pop + else + states.pop + end + + else + raise_inspect 'Unknown state!', encoder, states + end + + end + + while state = states.pop + encoder.end_group :string if [:sqstring, :dqstring].include? state + if state.is_a? Array + encoder.end_group :inline + encoder.end_group :string if [:sqstring, :dqstring].include? state.first + end + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/python.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/python.rb new file mode 100644 index 0000000..09c8b6e --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/python.rb @@ -0,0 +1,287 @@ +module CodeRay +module Scanners + + # Scanner for Python. Supports Python 3. + # + # Based on pygments' PythonLexer, see + # http://dev.pocoo.org/projects/pygments/browser/pygments/lexers/agile.py. + class Python < Scanner + + register_for :python + file_extension 'py' + + KEYWORDS = [ + 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', + 'del', 'elif', 'else', 'except', 'finally', 'for', + 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', + 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield', + 'nonlocal', # new in Python 3 + ] # :nodoc: + + OLD_KEYWORDS = [ + 'exec', 'print', # gone in Python 3 + ] # :nodoc: + + PREDEFINED_METHODS_AND_TYPES = %w[ + __import__ abs all any apply basestring bin bool buffer + bytearray bytes callable chr classmethod cmp coerce compile + complex delattr dict dir divmod enumerate eval execfile exit + file filter float frozenset getattr globals hasattr hash hex id + input int intern isinstance issubclass iter len list locals + long map max min next object oct open ord pow property range + raw_input reduce reload repr reversed round set setattr slice + sorted staticmethod str sum super tuple type unichr unicode + vars xrange zip + ] # :nodoc: + + PREDEFINED_EXCEPTIONS = %w[ + ArithmeticError AssertionError AttributeError + BaseException DeprecationWarning EOFError EnvironmentError + Exception FloatingPointError FutureWarning GeneratorExit IOError + ImportError ImportWarning IndentationError IndexError KeyError + KeyboardInterrupt LookupError MemoryError NameError + NotImplemented NotImplementedError OSError OverflowError + OverflowWarning PendingDeprecationWarning ReferenceError + RuntimeError RuntimeWarning StandardError StopIteration + SyntaxError SyntaxWarning SystemError SystemExit TabError + TypeError UnboundLocalError UnicodeDecodeError + UnicodeEncodeError UnicodeError UnicodeTranslateError + UnicodeWarning UserWarning ValueError Warning ZeroDivisionError + ] # :nodoc: + + PREDEFINED_VARIABLES_AND_CONSTANTS = [ + 'False', 'True', 'None', # "keywords" since Python 3 + 'self', 'Ellipsis', 'NotImplemented', + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(OLD_KEYWORDS, :old_keyword). + add(PREDEFINED_METHODS_AND_TYPES, :predefined). + add(PREDEFINED_VARIABLES_AND_CONSTANTS, :predefined_constant). + add(PREDEFINED_EXCEPTIONS, :exception) # :nodoc: + + NAME = / [[:alpha:]_] \w* /x # :nodoc: + ESCAPE = / [abfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} | N\{[-\w ]+\} /x # :nodoc: + + OPERATOR = / + \.\.\. | # ellipsis + \.(?!\d) | # dot but not decimal point + [,;:()\[\]{}] | # simple delimiters + \/\/=? | \*\*=? | # special math + [-+*\/%&|^]=? | # ordinary math and binary logic + [~`] | # binary complement and inspection + <<=? | >>=? | [<>=]=? | != # comparison and assignment + /x # :nodoc: + + STRING_DELIMITER_REGEXP = Hash.new { |h, delimiter| + h[delimiter] = Regexp.union delimiter # :nodoc: + } + + STRING_CONTENT_REGEXP = Hash.new { |h, delimiter| + h[delimiter] = / [^\\\n]+? (?= \\ | $ | #{Regexp.escape(delimiter)} ) /x # :nodoc: + } + + DEF_NEW_STATE = WordList.new(:initial). + add(%w(def), :def_expected). + add(%w(import from), :include_expected). + add(%w(class), :class_expected) # :nodoc: + + DESCRIPTOR = / + #{NAME} + (?: \. #{NAME} )* + | \* + /x # :nodoc: + + DOCSTRING_COMING = / + [ \t]* u?r? ("""|''') + /x # :nodoc: + + protected + + def scan_tokens encoder, options + + state = :initial + string_delimiter = nil + string_raw = false + string_type = nil + docstring_coming = match?(/#{DOCSTRING_COMING}/o) + last_token_dot = false + unicode = string.respond_to?(:encoding) && string.encoding.name == 'UTF-8' + from_import_state = [] + + until eos? + + if state == :string + if match = scan(STRING_DELIMITER_REGEXP[string_delimiter]) + encoder.text_token match, :delimiter + encoder.end_group string_type + string_type = nil + state = :initial + next + elsif string_delimiter.size == 3 && match = scan(/\n/) + encoder.text_token match, :content + elsif match = scan(STRING_CONTENT_REGEXP[string_delimiter]) + encoder.text_token match, :content + elsif !string_raw && match = scan(/ \\ #{ESCAPE} /ox) + encoder.text_token match, :char + elsif match = scan(/ \\ #{UNICODE_ESCAPE} /ox) + encoder.text_token match, :char + elsif match = scan(/ \\ . /x) + encoder.text_token match, :content + elsif match = scan(/ \\ | $ /x) + encoder.end_group string_type + string_type = nil + encoder.text_token match, :error unless match.empty? + state = :initial + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder, state + end + + elsif match = scan(/ [ \t]+ | \\?\n /x) + encoder.text_token match, :space + if match == "\n" + state = :initial if state == :include_expected + docstring_coming = true if match?(/#{DOCSTRING_COMING}/o) + end + next + + elsif match = scan(/ \# [^\n]* /mx) + encoder.text_token match, :comment + next + + elsif state == :initial + + if match = scan(/#{OPERATOR}/o) + encoder.text_token match, :operator + + elsif match = scan(/(u?r?|b)?("""|"|'''|')/i) + modifiers = self[1] + string_delimiter = self[2] + string_type = docstring_coming ? :docstring : (modifiers == 'b' ? :binary : :string) + docstring_coming = false if docstring_coming + encoder.begin_group string_type + string_raw = false + unless modifiers.empty? + string_raw = !!modifiers.index(?r) + encoder.text_token modifiers, :modifier + match = string_delimiter + end + state = :string + encoder.text_token match, :delimiter + + # TODO: backticks + + elsif match = scan(unicode ? /#{NAME}/uo : /#{NAME}/o) + kind = IDENT_KIND[match] + # TODO: keyword arguments + kind = :ident if last_token_dot + if kind == :old_keyword + kind = check(/\(/) ? :ident : :keyword + elsif kind == :predefined && check(/ *=/) + kind = :ident + elsif kind == :keyword + state = DEF_NEW_STATE[match] + from_import_state << match.to_sym if state == :include_expected + end + encoder.text_token match, kind + + elsif match = scan(/@[a-zA-Z0-9_.]+[lL]?/) + encoder.text_token match, :decorator + + elsif match = scan(/0[xX][0-9A-Fa-f]+[lL]?/) + encoder.text_token match, :hex + + elsif match = scan(/0[bB][01]+[lL]?/) + encoder.text_token match, :binary + + elsif match = scan(/(?:\d*\.\d+|\d+\.\d*)(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+/) + if scan(/[jJ]/) + match << matched + encoder.text_token match, :imaginary + else + encoder.text_token match, :float + end + + elsif match = scan(/0[oO][0-7]+|0[0-7]+(?![89.eE])[lL]?/) + encoder.text_token match, :octal + + elsif match = scan(/\d+([lL])?/) + if self[1] == nil && scan(/[jJ]/) + match << matched + encoder.text_token match, :imaginary + else + encoder.text_token match, :integer + end + + else + encoder.text_token getch, :error + + end + + elsif state == :def_expected + state = :initial + if match = scan(unicode ? /#{NAME}/uo : /#{NAME}/o) + encoder.text_token match, :method + else + next + end + + elsif state == :class_expected + state = :initial + if match = scan(unicode ? /#{NAME}/uo : /#{NAME}/o) + encoder.text_token match, :class + else + next + end + + elsif state == :include_expected + if match = scan(unicode ? /#{DESCRIPTOR}/uo : /#{DESCRIPTOR}/o) + if match == 'as' + encoder.text_token match, :keyword + from_import_state << :as + elsif from_import_state.first == :from && match == 'import' + encoder.text_token match, :keyword + from_import_state << :import + elsif from_import_state.last == :as + # encoder.text_token match, match[0,1][unicode ? /[[:upper:]]/u : /[[:upper:]]/] ? :class : :method + encoder.text_token match, :ident + from_import_state.pop + elsif IDENT_KIND[match] == :keyword + unscan + match = nil + state = :initial + next + else + encoder.text_token match, :include + end + elsif match = scan(/,/) + from_import_state.pop if from_import_state.last == :as + encoder.text_token match, :operator + else + from_import_state = [] + state = :initial + next + end + + else + raise_inspect 'Unknown state', encoder, state + + end + + last_token_dot = match == '.' + + end + + if state == :string + encoder.end_group string_type + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/raydebug.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/raydebug.rb new file mode 100644 index 0000000..1effdc8 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/raydebug.rb @@ -0,0 +1,75 @@ +require 'set' + +module CodeRay +module Scanners + + # = Raydebug Scanner + # + # Highlights the output of the Encoders::Debug encoder. + class Raydebug < Scanner + + register_for :raydebug + file_extension 'raydebug' + title 'CodeRay Token Dump' + + protected + + def setup + super + @known_token_kinds = TokenKinds.keys.map(&:to_s).to_set + end + + def scan_tokens encoder, options + + opened_tokens = [] + + until eos? + + if match = scan(/\s+/) + encoder.text_token match, :space + + elsif match = scan(/ (\w+) \( ( [^\)\\]* ( \\. [^\)\\]* )* ) /x) + kind = self[1] + encoder.text_token kind, :class + encoder.text_token '(', :operator + match = self[2] + unless match.empty? + if @known_token_kinds.include? kind + encoder.text_token match, kind.to_sym + else + encoder.text_token match, :plain + end + end + encoder.text_token match, :operator if match = scan(/\)/) + + elsif match = scan(/ (\w+) ([<\[]) /x) + encoder.text_token self[1], :class + if @known_token_kinds.include? self[1] + kind = self[1].to_sym + else + kind = :unknown + end + opened_tokens << kind + encoder.begin_group kind + encoder.text_token self[2], :operator + + elsif !opened_tokens.empty? && match = scan(/ [>\]] /x) + encoder.text_token match, :operator + encoder.end_group opened_tokens.pop + + else + encoder.text_token getch, :space + + end + + end + + encoder.end_group opened_tokens.pop until opened_tokens.empty? + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby.rb new file mode 100644 index 0000000..80165ca --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby.rb @@ -0,0 +1,470 @@ +module CodeRay +module Scanners + + # This scanner is really complex, since Ruby _is_ a complex language! + # + # It tries to highlight 100% of all common code, + # and 90% of strange codes. + # + # It is optimized for HTML highlighting, and is not very useful for + # parsing or pretty printing. + class Ruby < Scanner + + register_for :ruby + file_extension 'rb' + + autoload :Patterns, CodeRay.coderay_path('scanners', 'ruby', 'patterns') + autoload :StringState, CodeRay.coderay_path('scanners', 'ruby', 'string_state') + + def interpreted_string_state + StringState.new :string, true, '"' + end + + protected + + def setup + @state = :initial + end + + def scan_tokens encoder, options + state, heredocs = options[:state] || @state + heredocs = heredocs.dup if heredocs.is_a?(Array) + + if state && state.instance_of?(StringState) + encoder.begin_group state.type + end + + last_state = nil + + method_call_expected = false + value_expected = true + + inline_block_stack = nil + inline_block_curly_depth = 0 + + if heredocs + state = heredocs.shift + encoder.begin_group state.type + heredocs = nil if heredocs.empty? + end + + # def_object_stack = nil + # def_object_paren_depth = 0 + + patterns = Patterns # avoid constant lookup + + unicode = string.respond_to?(:encoding) && string.encoding.name == 'UTF-8' + + until eos? + + if state.instance_of? ::Symbol + + if match = scan(/[ \t\f\v]+/) + encoder.text_token match, :space + + elsif match = scan(/\n/) + if heredocs + unscan # heredoc scanning needs \n at start + state = heredocs.shift + encoder.begin_group state.type + heredocs = nil if heredocs.empty? + else + state = :initial if state == :undef_comma_expected + encoder.text_token match, :space + value_expected = true + end + + elsif match = scan(bol? ? / \#(!)?.* | #{patterns::RUBYDOC_OR_DATA} /ox : /\#.*/) + encoder.text_token match, self[1] ? :doctype : :comment + + elsif match = scan(/\\\n/) + if heredocs + unscan # heredoc scanning needs \n at start + encoder.text_token scan(/\\/), :space + state = heredocs.shift + encoder.begin_group state.type + heredocs = nil if heredocs.empty? + else + encoder.text_token match, :space + end + + elsif state == :initial + + # IDENTS # + if !method_call_expected && + match = scan(unicode ? /#{patterns::METHOD_NAME}/uo : + /#{patterns::METHOD_NAME}/o) + + kind = patterns::IDENT_KIND[match] + if value_expected != :colon_expected && scan(/:(?!:)/) + value_expected = true + encoder.text_token match, :key + encoder.text_token ':', :operator + else + value_expected = false + if kind == :ident + if match[/\A[A-Z]/] && !(match[/[!?]$/] || match?(/\(/)) + kind = :constant + end + elsif kind == :keyword + state = patterns::KEYWORD_NEW_STATE[match] + if patterns::KEYWORDS_EXPECTING_VALUE[match] + value_expected = match == 'when' ? :colon_expected : true + end + end + value_expected = true if !value_expected && check(/#{patterns::VALUE_FOLLOWS}/o) + encoder.text_token match, kind + end + + elsif method_call_expected && + match = scan(unicode ? /#{patterns::METHOD_AFTER_DOT}/uo : + /#{patterns::METHOD_AFTER_DOT}/o) + if method_call_expected == '::' && match[/\A[A-Z]/] && !match?(/\(/) + encoder.text_token match, :constant + else + encoder.text_token match, :ident + end + method_call_expected = false + value_expected = check(/#{patterns::VALUE_FOLLOWS}/o) + + # OPERATORS # + elsif !method_call_expected && match = scan(/ (\.(?!\.)|::) | ( \.\.\.? | ==?=? | [,\(\[\{] ) | [\)\]\}] /x) + method_call_expected = self[1] + value_expected = !method_call_expected && !!self[2] + if inline_block_stack + case match + when '{' + inline_block_curly_depth += 1 + when '}' + inline_block_curly_depth -= 1 + if inline_block_curly_depth == 0 # closing brace of inline block reached + state, inline_block_curly_depth, heredocs = inline_block_stack.pop + inline_block_stack = nil if inline_block_stack.empty? + heredocs = nil if heredocs && heredocs.empty? + encoder.text_token match, :inline_delimiter + encoder.end_group :inline + next + end + end + end + encoder.text_token match, :operator + + elsif match = scan(unicode ? /#{patterns::SYMBOL}/uo : + /#{patterns::SYMBOL}/o) + case delim = match[1] + when ?', ?" + encoder.begin_group :symbol + encoder.text_token ':', :symbol + match = delim.chr + encoder.text_token match, :delimiter + state = self.class::StringState.new :symbol, delim == ?", match + else + encoder.text_token match, :symbol + value_expected = false + end + + elsif match = scan(/ ' (?:(?>[^'\\]*) ')? | " (?:(?>[^"\\\#]*) ")? /mx) + encoder.begin_group :string + if match.size == 1 + encoder.text_token match, :delimiter + state = self.class::StringState.new :string, match == '"', match # important for streaming + else + encoder.text_token match[0,1], :delimiter + encoder.text_token match[1..-2], :content if match.size > 2 + encoder.text_token match[-1,1], :delimiter + encoder.end_group :string + value_expected = false + end + + elsif match = scan(unicode ? /#{patterns::INSTANCE_VARIABLE}/uo : + /#{patterns::INSTANCE_VARIABLE}/o) + value_expected = false + encoder.text_token match, :instance_variable + + elsif value_expected && match = scan(/\//) + encoder.begin_group :regexp + encoder.text_token match, :delimiter + state = self.class::StringState.new :regexp, true, '/' + + elsif match = scan(value_expected ? /[-+]?#{patterns::NUMERIC}/o : /#{patterns::NUMERIC}/o) + if method_call_expected + encoder.text_token match, :error + method_call_expected = false + else + encoder.text_token match, self[1] ? :float : :integer # TODO: send :hex/:octal/:binary + end + value_expected = false + + elsif match = scan(/ [-+!~^\/]=? | [:;] | [*|&]{1,2}=? | >>? /x) + value_expected = true + encoder.text_token match, :operator + + elsif value_expected && match = scan(/#{patterns::HEREDOC_OPEN}/o) + quote = self[3] + delim = self[quote ? 4 : 2] + kind = patterns::QUOTE_TO_TYPE[quote] + encoder.begin_group kind + encoder.text_token match, :delimiter + encoder.end_group kind + heredocs ||= [] # create heredocs if empty + heredocs << self.class::StringState.new(kind, quote != "'", delim, + self[1] == '-' ? :indented : :linestart) + value_expected = false + + elsif value_expected && match = scan(/#{patterns::FANCY_STRING_START}/o) + kind = patterns::FANCY_STRING_KIND[self[1]] + encoder.begin_group kind + state = self.class::StringState.new kind, patterns::FANCY_STRING_INTERPRETED[self[1]], self[2] + encoder.text_token match, :delimiter + + elsif value_expected && match = scan(/#{patterns::CHARACTER}/o) + value_expected = false + encoder.text_token match, :integer + + elsif match = scan(/ %=? | <(?:<|=>?)? | \? /x) + value_expected = match == '?' ? :colon_expected : true + encoder.text_token match, :operator + + elsif match = scan(/`/) + encoder.begin_group :shell + encoder.text_token match, :delimiter + state = self.class::StringState.new :shell, true, match + + elsif match = scan(unicode ? /#{patterns::GLOBAL_VARIABLE}/uo : + /#{patterns::GLOBAL_VARIABLE}/o) + encoder.text_token match, :global_variable + value_expected = false + + elsif match = scan(unicode ? /#{patterns::CLASS_VARIABLE}/uo : + /#{patterns::CLASS_VARIABLE}/o) + encoder.text_token match, :class_variable + value_expected = false + + elsif match = scan(/\\\z/) + encoder.text_token match, :space + + else + if method_call_expected + method_call_expected = false + next + end + unless unicode + # check for unicode + $DEBUG_BEFORE, $DEBUG = $DEBUG, false + begin + if check(/./mu).size > 1 + # seems like we should try again with unicode + unicode = true + end + rescue + # bad unicode char; use getch + ensure + $DEBUG = $DEBUG_BEFORE + end + next if unicode + end + + encoder.text_token getch, :error + + end + + if last_state + state = last_state unless state.is_a?(StringState) # otherwise, a simple 'def"' results in unclosed tokens + last_state = nil + end + + elsif state == :def_expected + if match = scan(unicode ? /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/uo : + /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/o) + encoder.text_token match, :method + state = :initial + else + last_state = :dot_expected + state = :initial + end + + elsif state == :dot_expected + if match = scan(/\.|::/) + # invalid definition + state = :def_expected + encoder.text_token match, :operator + else + state = :initial + end + + elsif state == :module_expected + if match = scan(/<#{patterns::METHOD_NAME_EX})(?!\.|::)/uo : + /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/o) + encoder.text_token match, :method + elsif match = scan(/#{patterns::SYMBOL}/o) + case delim = match[1] + when ?', ?" + encoder.begin_group :symbol + encoder.text_token ':', :symbol + match = delim.chr + encoder.text_token match, :delimiter + state = self.class::StringState.new :symbol, delim == ?", match + state.next_state = :undef_comma_expected + else + encoder.text_token match, :symbol + end + else + state = :initial + end + + elsif state == :undef_comma_expected + if match = scan(/,/) + encoder.text_token match, :operator + state = :undef_expected + else + state = :initial + end + + elsif state == :alias_expected + match = scan(unicode ? /(#{patterns::METHOD_NAME_OR_SYMBOL})([ \t]+)(#{patterns::METHOD_NAME_OR_SYMBOL})/uo : + /(#{patterns::METHOD_NAME_OR_SYMBOL})([ \t]+)(#{patterns::METHOD_NAME_OR_SYMBOL})/o) + + if match + encoder.text_token self[1], (self[1][0] == ?: ? :symbol : :method) + encoder.text_token self[2], :space + encoder.text_token self[3], (self[3][0] == ?: ? :symbol : :method) + end + state = :initial + + else + #:nocov: + raise_inspect 'Unknown state: %p' % [state], encoder + #:nocov: + end + + else # StringState + + match = scan_until(state.pattern) || scan_rest + unless match.empty? + encoder.text_token match, :content + break if eos? + end + + if state.heredoc && self[1] # end of heredoc + match = getch + match << scan_until(/$/) unless eos? + encoder.text_token match, :delimiter unless match.empty? + encoder.end_group state.type + state = state.next_state + next + end + + case match = getch + + when state.delim + if state.paren_depth + state.paren_depth -= 1 + if state.paren_depth > 0 + encoder.text_token match, :content + next + end + end + encoder.text_token match, :delimiter + if state.type == :regexp && !eos? + match = scan(/#{patterns::REGEXP_MODIFIERS}/o) + encoder.text_token match, :modifier unless match.empty? + end + encoder.end_group state.type + value_expected = false + state = state.next_state + + when '\\' + if state.interpreted + if esc = scan(/#{patterns::ESCAPE}/o) + encoder.text_token match + esc, :char + else + encoder.text_token match, :error + end + else + case esc = getch + when nil + encoder.text_token match, :content + when state.delim, '\\' + encoder.text_token match + esc, :char + else + encoder.text_token match + esc, :content + end + end + + when '#' + case peek(1) + when '{' + inline_block_stack ||= [] + inline_block_stack << [state, inline_block_curly_depth, heredocs] + value_expected = true + state = :initial + inline_block_curly_depth = 1 + encoder.begin_group :inline + encoder.text_token match + getch, :inline_delimiter + when '$', '@' + encoder.text_token match, :escape + last_state = state + state = :initial + else + #:nocov: + raise_inspect 'else-case # reached; #%p not handled' % [peek(1)], encoder + #:nocov: + end + + when state.opening_paren + state.paren_depth += 1 + encoder.text_token match, :content + + else + #:nocov + raise_inspect 'else-case " reached; %p not handled, state = %p' % [match, state], encoder + #:nocov: + + end + + end + + end + + # cleaning up + if state.is_a? StringState + encoder.end_group state.type + end + + if options[:keep_state] + if state.is_a?(StringState) && state.heredoc + (heredocs ||= []).unshift state + state = :initial + elsif heredocs && heredocs.empty? + heredocs = nil + end + @state = state, heredocs + end + + if inline_block_stack + until inline_block_stack.empty? + state, = *inline_block_stack.pop + encoder.end_group :inline + encoder.end_group state.type + end + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/patterns.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/patterns.rb new file mode 100644 index 0000000..0b36e13 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/patterns.rb @@ -0,0 +1,178 @@ +# encoding: utf-8 +module CodeRay +module Scanners + + module Ruby::Patterns # :nodoc: all + + KEYWORDS = %w[ + and def end in or unless begin + defined? ensure module redo super until + BEGIN break do next rescue then + when END case else for retry + while alias class elsif if not return + undef yield + ] + + # See http://murfy.de/ruby-constants. + PREDEFINED_CONSTANTS = %w[ + nil true false self + DATA ARGV ARGF ENV + FALSE TRUE NIL + STDERR STDIN STDOUT + TOPLEVEL_BINDING + RUBY_COPYRIGHT RUBY_DESCRIPTION RUBY_ENGINE RUBY_PATCHLEVEL + RUBY_PLATFORM RUBY_RELEASE_DATE RUBY_REVISION RUBY_VERSION + __FILE__ __LINE__ __ENCODING__ + ] + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(PREDEFINED_CONSTANTS, :predefined_constant) + + KEYWORD_NEW_STATE = WordList.new(:initial). + add(%w[ def ], :def_expected). + add(%w[ undef ], :undef_expected). + add(%w[ alias ], :alias_expected). + add(%w[ class module ], :module_expected) + + IDENT = 'ä'[/[[:alpha:]]/] == 'ä' ? Regexp.new('[[:alpha:]_[^\0-\177]][[:alnum:]_[^\0-\177]]*') : /[^\W\d]\w*/ + + METHOD_NAME = / #{IDENT} [?!]? /ox + METHOD_NAME_OPERATOR = / + \*\*? # multiplication and power + | [-+~]@? # plus, minus, tilde with and without at sign + | [\/%&|^`] # division, modulo or format strings, and, or, xor, system + | \[\]=? # array getter and setter + | << | >> # append or shift left, shift right + | <=?>? | >=? # comparison, rocket operator + | ===? | =~ # simple equality, case equality, match + | ![~=@]? # negation with and without at sign, not-equal and not-match + /ox + METHOD_SUFFIX = / (?: [?!] | = (?![~>]|=(?!>)) ) /x + METHOD_NAME_EX = / #{IDENT} #{METHOD_SUFFIX}? | #{METHOD_NAME_OPERATOR} /ox + METHOD_AFTER_DOT = / #{IDENT} [?!]? | #{METHOD_NAME_OPERATOR} /ox + INSTANCE_VARIABLE = / @ #{IDENT} /ox + CLASS_VARIABLE = / @@ #{IDENT} /ox + OBJECT_VARIABLE = / @@? #{IDENT} /ox + GLOBAL_VARIABLE = / \$ (?: #{IDENT} | [1-9]\d* | 0\w* | [~&+`'=\/,;_.<>!@$?*":\\] | -[a-zA-Z_0-9] ) /ox + PREFIX_VARIABLE = / #{GLOBAL_VARIABLE} | #{OBJECT_VARIABLE} /ox + VARIABLE = / @?@? #{IDENT} | #{GLOBAL_VARIABLE} /ox + + QUOTE_TO_TYPE = { + '`' => :shell, + '/'=> :regexp, + } + QUOTE_TO_TYPE.default = :string + + REGEXP_MODIFIERS = /[mousenix]*/ + + DECIMAL = /\d+(?:_\d+)*/ + OCTAL = /0_?[0-7]+(?:_[0-7]+)*/ + HEXADECIMAL = /0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*/ + BINARY = /0b[01]+(?:_[01]+)*/ + + EXPONENT = / [eE] [+-]? #{DECIMAL} /ox + FLOAT_SUFFIX = / #{EXPONENT} | \. #{DECIMAL} #{EXPONENT}? /ox + FLOAT_OR_INT = / #{DECIMAL} (?: #{FLOAT_SUFFIX} () )? /ox + NUMERIC = / (?: (?=0) (?: #{OCTAL} | #{HEXADECIMAL} | #{BINARY} ) | #{FLOAT_OR_INT} ) /ox + + SYMBOL = / + : + (?: + #{METHOD_NAME_EX} + | #{PREFIX_VARIABLE} + | ['"] + ) + /ox + METHOD_NAME_OR_SYMBOL = / #{METHOD_NAME_EX} | #{SYMBOL} /ox + + SIMPLE_ESCAPE = / + [abefnrstv] + | [0-7]{1,3} + | x[0-9A-Fa-f]{1,2} + | . + /mx + + CONTROL_META_ESCAPE = / + (?: M-|C-|c ) + (?: \\ (?: M-|C-|c ) )* + (?: [^\\] | \\ #{SIMPLE_ESCAPE} )? + /mox + + ESCAPE = / + #{CONTROL_META_ESCAPE} | #{SIMPLE_ESCAPE} + /mox + + CHARACTER = / + \? + (?: + [^\s\\] + | \\ #{ESCAPE} + ) + /mox + + # NOTE: This is not completely correct, but + # nobody needs heredoc delimiters ending with \n. + HEREDOC_OPEN = / + << (-)? # $1 = float + (?: + ( [A-Za-z_0-9]+ ) # $2 = delim + | + ( ["'`\/] ) # $3 = quote, type + ( [^\n]*? ) \3 # $4 = delim + ) + /mx + + RUBYDOC = / + =begin (?!\S) + .*? + (?: \Z | ^=end (?!\S) [^\n]* ) + /mx + + DATA = / + __END__$ + .*? + (?: \Z | (?=^\#CODE) ) + /mx + + RUBYDOC_OR_DATA = / #{RUBYDOC} | #{DATA} /xo + + # Checks for a valid value to follow. This enables + # value_expected in method calls without parentheses. + VALUE_FOLLOWS = / + (?>[ \t\f\v]+) + (?: + [%\/][^\s=] + | <<-?\S + | [-+] \d + | #{CHARACTER} + ) + /ox + KEYWORDS_EXPECTING_VALUE = WordList.new.add(%w[ + and end in or unless begin + defined? ensure redo super until + break do next rescue then + when case else for retry + while elsif if not return + yield + ]) + + FANCY_STRING_START = / % ( [iIqQrswWx] | (?![a-zA-Z0-9]) ) ([^a-zA-Z0-9]) /x + FANCY_STRING_KIND = Hash.new(:string).merge({ + 'i' => :symbol, + 'I' => :symbol, + 'r' => :regexp, + 's' => :symbol, + 'x' => :shell, + }) + FANCY_STRING_INTERPRETED = Hash.new(true).merge({ + 'i' => false, + 'q' => false, + 's' => false, + 'w' => false, + }) + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/string_state.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/string_state.rb new file mode 100644 index 0000000..28ddd6c --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/string_state.rb @@ -0,0 +1,71 @@ +# encoding: utf-8 +module CodeRay +module Scanners + + class Ruby + + class StringState < Struct.new :type, :interpreted, :delim, :heredoc, + :opening_paren, :paren_depth, :pattern, :next_state # :nodoc: all + + CLOSING_PAREN = Hash[ *%w[ + ( ) + [ ] + < > + { } + ] ].each { |k,v| k.freeze; v.freeze } # debug, if I try to change it with << + + STRING_PATTERN = Hash.new do |h, k| + delim, interpreted = *k + delim_pattern = Regexp.escape(delim) + if closing_paren = CLOSING_PAREN[delim] + delim_pattern << Regexp.escape(closing_paren) + end + delim_pattern << '\\\\' unless delim == '\\' + + # special_escapes = + # case interpreted + # when :regexp_symbols + # '| [|?*+(){}\[\].^$]' + # end + + if interpreted && delim != '#' + / (?= [#{delim_pattern}] | \# [{$@] ) /mx + else + / (?= [#{delim_pattern}] ) /mx + end.tap do |pattern| + h[k] = pattern if (delim.respond_to?(:ord) ? delim.ord : delim[0]) < 256 + end + end + + def initialize kind, interpreted, delim, heredoc = false + if heredoc + pattern = heredoc_pattern delim, interpreted, heredoc == :indented + delim = nil + else + pattern = STRING_PATTERN[ [delim, interpreted] ] + if closing_paren = CLOSING_PAREN[delim] + opening_paren = delim + delim = closing_paren + paren_depth = 1 + end + end + super kind, interpreted, delim, heredoc, opening_paren, paren_depth, pattern, :initial + end + + def heredoc_pattern delim, interpreted, indented + # delim = delim.dup # workaround for old Ruby + delim_pattern = Regexp.escape(delim) + delim_pattern = / (?:\A|\n) #{ '(?>[ \t]*)' if indented } #{ Regexp.new delim_pattern } $ /x + if interpreted + / (?= #{delim_pattern}() | \\ | \# [{$@] ) /mx # $1 set == end of heredoc + else + / (?= #{delim_pattern}() | \\ ) /mx + end + end + + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sass.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sass.rb new file mode 100644 index 0000000..e3296b9 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sass.rb @@ -0,0 +1,232 @@ +module CodeRay +module Scanners + + # A scanner for Sass. + class Sass < CSS + + register_for :sass + file_extension 'sass' + + protected + + def setup + @state = :initial + end + + def scan_tokens encoder, options + states = Array(options[:state] || @state).dup + + encoder.begin_group :string if states.last == :sqstring || states.last == :dqstring + + until eos? + + if bol? && (match = scan(/(?>( +)?(\/[\*\/])(.+)?)(?=\n)/)) + encoder.text_token self[1], :space if self[1] + encoder.begin_group :comment + encoder.text_token self[2], :delimiter + encoder.text_token self[3], :content if self[3] + if match = scan(/(?:\n+#{self[1]} .*)+/) + encoder.text_token match, :content + end + encoder.end_group :comment + elsif match = scan(/\n|[^\n\S]+\n?/) + encoder.text_token match, :space + if match.index(/\n/) + value_expected = false + states.pop if states.last == :include + end + + elsif states.last == :sass_inline && (match = scan(/\}/)) + encoder.text_token match, :inline_delimiter + encoder.end_group :inline + states.pop + + elsif case states.last + when :initial, :media, :sass_inline + if match = scan(/(?>#{RE::Ident})(?!\()/ox) + encoder.text_token match, value_expected ? :value : (check(/.*:(?![a-z])/) ? :key : :tag) + next + elsif !value_expected && (match = scan(/\*/)) + encoder.text_token match, :tag + next + elsif match = scan(RE::Class) + encoder.text_token match, :class + next + elsif match = scan(RE::Id) + encoder.text_token match, :id + next + elsif match = scan(RE::PseudoClass) + encoder.text_token match, :pseudo_class + next + elsif match = scan(RE::AttributeSelector) + # TODO: Improve highlighting inside of attribute selectors. + encoder.text_token match[0,1], :operator + encoder.text_token match[1..-2], :attribute_name if match.size > 2 + encoder.text_token match[-1,1], :operator if match[-1] == ?] + next + elsif match = scan(/(\=|@mixin +)#{RE::Ident}/o) + encoder.text_token match, :function + next + elsif match = scan(/@import\b/) + encoder.text_token match, :directive + states << :include + next + elsif match = scan(/@media\b/) + encoder.text_token match, :directive + # states.push :media_before_name + next + end + + when :block + if match = scan(/(?>#{RE::Ident})(?!\()/ox) + if value_expected + encoder.text_token match, :value + else + encoder.text_token match, :key + end + next + end + + when :sqstring, :dqstring + if match = scan(states.last == :sqstring ? /(?:[^\n\'\#]+|\\\n|#{RE::Escape}|#(?!\{))+/o : /(?:[^\n\"\#]+|\\\n|#{RE::Escape}|#(?!\{))+/o) + encoder.text_token match, :content + elsif match = scan(/['"]/) + encoder.text_token match, :delimiter + encoder.end_group :string + states.pop + elsif match = scan(/#\{/) + encoder.begin_group :inline + encoder.text_token match, :inline_delimiter + states.push :sass_inline + elsif match = scan(/ \\ | $ /x) + encoder.end_group states.last + encoder.text_token match, :error unless match.empty? + states.pop + else + raise_inspect "else case #{states.last} reached; %p not handled." % peek(1), encoder + end + + when :include + if match = scan(/[^\s'",]+/) + encoder.text_token match, :include + next + end + + else + #:nocov: + raise_inspect 'Unknown state: %p' % [states.last], encoder + #:nocov: + + end + + elsif match = scan(/\$#{RE::Ident}/o) + encoder.text_token match, :variable + next + + elsif match = scan(/&/) + encoder.text_token match, :local_variable + + elsif match = scan(/\+#{RE::Ident}/o) + encoder.text_token match, :include + value_expected = true + + elsif match = scan(/\/\*(?:.*?\*\/|.*)|\/\/.*/) + encoder.text_token match, :comment + + elsif match = scan(/#\{/) + encoder.begin_group :inline + encoder.text_token match, :inline_delimiter + states.push :sass_inline + + elsif match = scan(/\{/) + value_expected = false + encoder.text_token match, :operator + states.push :block + + elsif match = scan(/\}/) + value_expected = false + encoder.text_token match, :operator + if states.last == :block || states.last == :media + states.pop + end + + elsif match = scan(/['"]/) + encoder.begin_group :string + encoder.text_token match, :delimiter + if states.include? :sass_inline + # no nesting, just scan the string until delimiter + content = scan_until(/(?=#{match}|\}|\z)/) + encoder.text_token content, :content unless content.empty? + encoder.text_token match, :delimiter if scan(/#{match}/) + encoder.end_group :string + else + states.push match == "'" ? :sqstring : :dqstring + end + + elsif match = scan(/#{RE::Function}/o) + encoder.begin_group :function + start = match[/^[-\w]+\(/] + encoder.text_token start, :delimiter + if match[-1] == ?) + encoder.text_token match[start.size..-2], :content + encoder.text_token ')', :delimiter + else + encoder.text_token match[start.size..-1], :content if start.size < match.size + end + encoder.end_group :function + + elsif match = scan(/[a-z][-a-z_]*(?=\()/o) + encoder.text_token match, :predefined + + elsif match = scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox) + encoder.text_token match, :float + + elsif match = scan(/#{RE::HexColor}/o) + encoder.text_token match, :color + + elsif match = scan(/! *(?:important|optional)/) + encoder.text_token match, :important + + elsif match = scan(/(?:rgb|hsl)a?\([^()\n]*\)?/) + encoder.text_token match, :color + + elsif match = scan(/@else if\b|#{RE::AtKeyword}/o) + encoder.text_token match, :directive + value_expected = true + + elsif match = scan(/ == | != | [-+*\/>~:;,.=()] /x) + if match == ':' + value_expected = true + elsif match == ';' + value_expected = false + end + encoder.text_token match, :operator + + else + encoder.text_token getch, :error + + end + + end + + states.pop if states.last == :include + + if options[:keep_state] + @state = states.dup + end + + while state = states.pop + if state == :sass_inline + encoder.end_group :inline + elsif state == :sqstring || state == :dqstring + encoder.end_group :string + end + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sql.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sql.rb new file mode 100644 index 0000000..93aeaf3 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sql.rb @@ -0,0 +1,177 @@ +module CodeRay +module Scanners + + # by Josh Goebel + class SQL < Scanner + + register_for :sql + + KEYWORDS = %w( + all and any as before begin between by case check collate + each else end exists + for foreign from full group having if in inner is join + like not of on or order outer over references + then to union using values when where + left right distinct + ) + + OBJECTS = %w( + database databases table tables column columns fields index constraint + constraints transaction function procedure row key view trigger + ) + + COMMANDS = %w( + add alter comment create delete drop grant insert into select update set + show prompt begin commit rollback replace truncate + ) + + PREDEFINED_TYPES = %w( + char varchar varchar2 enum binary text tinytext mediumtext + longtext blob tinyblob mediumblob longblob timestamp + date time datetime year double decimal float int + integer tinyint mediumint bigint smallint unsigned bit + bool boolean hex bin oct + ) + + PREDEFINED_FUNCTIONS = %w( sum cast substring abs pi count min max avg now ) + + DIRECTIVES = %w( + auto_increment unique default charset initially deferred + deferrable cascade immediate read write asc desc after + primary foreign return engine + ) + + PREDEFINED_CONSTANTS = %w( null true false ) + + IDENT_KIND = WordList::CaseIgnoring.new(:ident). + add(KEYWORDS, :keyword). + add(OBJECTS, :type). + add(COMMANDS, :class). + add(PREDEFINED_TYPES, :predefined_type). + add(PREDEFINED_CONSTANTS, :predefined_constant). + add(PREDEFINED_FUNCTIONS, :predefined). + add(DIRECTIVES, :directive) + + ESCAPE = / [rbfntv\n\\\/'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} | . /mx + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x + + STRING_PREFIXES = /[xnb]|_\w+/i + + def scan_tokens encoder, options + + state = :initial + string_type = nil + string_content = '' + name_expected = false + + until eos? + + if state == :initial + + if match = scan(/ \s+ | \\\n /x) + encoder.text_token match, :space + + elsif match = scan(/(?:--\s?|#).*/) + encoder.text_token match, :comment + + elsif match = scan(%r( /\* (!)? (?: .*? \*/ | .* ) )mx) + encoder.text_token match, self[1] ? :directive : :comment + + elsif match = scan(/ [*\/=<>:;,!&^|()\[\]{}~%] | [-+\.](?!\d) /x) + name_expected = true if match == '.' && check(/[A-Za-z_]/) + encoder.text_token match, :operator + + elsif match = scan(/(#{STRING_PREFIXES})?([`"'])/o) + prefix = self[1] + string_type = self[2] + encoder.begin_group :string + encoder.text_token prefix, :modifier if prefix + match = string_type + state = :string + encoder.text_token match, :delimiter + + elsif match = scan(/ @? [A-Za-z_][A-Za-z_0-9]* /x) + encoder.text_token match, name_expected ? :ident : (match[0] == ?@ ? :variable : IDENT_KIND[match]) + name_expected = false + + elsif match = scan(/0[xX][0-9A-Fa-f]+/) + encoder.text_token match, :hex + + elsif match = scan(/0[0-7]+(?![89.eEfF])/) + encoder.text_token match, :octal + + elsif match = scan(/[-+]?(?>\d+)(?![.eEfF])/) + encoder.text_token match, :integer + + elsif match = scan(/[-+]?(?:\d[fF]|\d*\.\d+(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+)/) + encoder.text_token match, :float + + elsif match = scan(/\\N/) + encoder.text_token match, :predefined_constant + + else + encoder.text_token getch, :error + + end + + elsif state == :string + if match = scan(/[^\\"'`]+/) + string_content << match + next + elsif match = scan(/["'`]/) + if string_type == match + if peek(1) == string_type # doubling means escape + string_content << string_type << getch + next + end + unless string_content.empty? + encoder.text_token string_content, :content + string_content = '' + end + encoder.text_token match, :delimiter + encoder.end_group :string + state = :initial + string_type = nil + else + string_content << match + end + elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + unless string_content.empty? + encoder.text_token string_content, :content + string_content = '' + end + encoder.text_token match, :char + elsif match = scan(/ \\ . /mox) + string_content << match + next + elsif match = scan(/ \\ | $ /x) + unless string_content.empty? + encoder.text_token string_content, :content + string_content = '' + end + encoder.text_token match, :error unless match.empty? + encoder.end_group :string + state = :initial + else + raise "else case \" reached; %p not handled." % peek(1), encoder + end + + else + raise 'else-case reached', encoder + + end + + end + + if state == :string + encoder.end_group state + end + + encoder + + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/taskpaper.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/taskpaper.rb new file mode 100644 index 0000000..42670bc --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/taskpaper.rb @@ -0,0 +1,36 @@ +module CodeRay +module Scanners + + class Taskpaper < Scanner + + register_for :taskpaper + file_extension 'taskpaper' + + protected + + def scan_tokens encoder, options + until eos? + if match = scan(/\S.*:.*$/) # project + encoder.text_token(match, :namespace) + elsif match = scan(/-.+@done.*/) # completed task + encoder.text_token(match, :done) + elsif match = scan(/-(?:[^@\n]+|@(?!due))*/) # task + encoder.text_token(match, :plain) + elsif match = scan(/@due.*/) # comment + encoder.text_token(match, :important) + elsif match = scan(/.+/) # comment + encoder.text_token(match, :comment) + elsif match = scan(/\s+/) # space + encoder.text_token(match, :space) + else # other + encoder.text_token getch, :error + end + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/text.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/text.rb new file mode 100644 index 0000000..bde9029 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/text.rb @@ -0,0 +1,26 @@ +module CodeRay + module Scanners + + # Scanner for plain text. + # + # Yields just one token of the kind :plain. + # + # Alias: +plaintext+, +plain+ + class Text < Scanner + + register_for :text + title 'Plain text' + + KINDS_NOT_LOC = [:plain] # :nodoc: + + protected + + def scan_tokens encoder, options + encoder.text_token string, :plain + encoder + end + + end + + end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/xml.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/xml.rb new file mode 100644 index 0000000..947f16e --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/xml.rb @@ -0,0 +1,17 @@ +module CodeRay +module Scanners + + load :html + + # Scanner for XML. + # + # Currently this is the same scanner as Scanners::HTML. + class XML < HTML + + register_for :xml + file_extension 'xml' + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/yaml.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/yaml.rb new file mode 100644 index 0000000..32c8e2c --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/yaml.rb @@ -0,0 +1,140 @@ +module CodeRay +module Scanners + + # Scanner for YAML. + # + # Based on the YAML scanner from Syntax by Jamis Buck. + class YAML < Scanner + + register_for :yaml + file_extension 'yml' + + KINDS_NOT_LOC = :all + + protected + + def scan_tokens encoder, options + + state = :initial + key_indent = string_indent = 0 + + until eos? + + key_indent = nil if bol? + + if match = scan(/ +[\t ]*/) + encoder.text_token match, :space + + elsif match = scan(/\n+/) + encoder.text_token match, :space + state = :initial if match.index(?\n) + + elsif match = scan(/#.*/) + encoder.text_token match, :comment + + elsif bol? and case + when match = scan(/---|\.\.\./) + encoder.begin_group :head + encoder.text_token match, :head + encoder.end_group :head + next + when match = scan(/%.*/) + encoder.text_token match, :doctype + next + end + + elsif state == :value and case + when !check(/(?:"[^"]*")(?=: |:$)/) && match = scan(/"/) + encoder.begin_group :string + encoder.text_token match, :delimiter + encoder.text_token match, :content if (match = scan(/ [^"\\]* (?: \\. [^"\\]* )* /mx)) && !match.empty? + encoder.text_token match, :delimiter if match = scan(/"/) + encoder.end_group :string + next + when match = scan(/[|>][-+]?/) + encoder.begin_group :string + encoder.text_token match, :delimiter + string_indent = key_indent || column(pos - match.size) - 1 + encoder.text_token matched, :content if scan(/(?:\n+ {#{string_indent + 1}}.*)+/) + encoder.end_group :string + next + when match = scan(/(?![!"*&]).+?(?=$|\s+#)/) + encoder.begin_group :string + encoder.text_token match, :content + string_indent = key_indent || column(pos - match.size) - 1 + encoder.text_token matched, :content if scan(/(?:\n+ {#{string_indent + 1}}.*)+/) + encoder.end_group :string + next + end + + elsif case + when match = scan(/[-:](?= |$)/) + state = :value if state == :colon && (match == ':' || match == '-') + state = :value if state == :initial && match == '-' + encoder.text_token match, :operator + next + when match = scan(/[,{}\[\]]/) + encoder.text_token match, :operator + next + when state == :initial && match = scan(/[-\w.()\/ ]*\S(?= *:(?: |$))/) + encoder.text_token match, :key + key_indent = column(pos - match.size) - 1 + state = :colon + next + when match = scan(/(?:"[^"\n]*"|'[^'\n]*')(?= *:(?: |$))/) + encoder.begin_group :key + encoder.text_token match[0,1], :delimiter + encoder.text_token match[1..-2], :content if match.size > 2 + encoder.text_token match[-1,1], :delimiter + encoder.end_group :key + key_indent = column(pos - match.size) - 1 + state = :colon + next + when match = scan(/(![\w\/]+)(:([\w:]+))?/) + encoder.text_token self[1], :type + if self[2] + encoder.text_token ':', :operator + encoder.text_token self[3], :class + end + next + when match = scan(/&\S+/) + encoder.text_token match, :variable + next + when match = scan(/\*\w+/) + encoder.text_token match, :global_variable + next + when match = scan(/< 'debug', # highlight for debugging (white on blue background) + + :annotation => 'annotation', # Groovy, Java + :attribute_name => 'attribute-name', # HTML, CSS + :attribute_value => 'attribute-value', # HTML + :binary => 'binary', # Python, Ruby + :char => 'char', # most scanners, also inside of strings + :class => 'class', # lots of scanners, for different purposes also in CSS + :class_variable => 'class-variable', # Ruby, YAML + :color => 'color', # CSS + :comment => 'comment', # most scanners + :constant => 'constant', # PHP, Ruby + :content => 'content', # inside of strings, most scanners + :decorator => 'decorator', # Python + :definition => 'definition', # CSS + :delimiter => 'delimiter', # inside strings, comments and other types + :directive => 'directive', # lots of scanners + :doctype => 'doctype', # Goorvy, HTML, Ruby, YAML + :docstring => 'docstring', # Python + :done => 'done', # Taskpaper + :entity => 'entity', # HTML + :error => 'error', # invalid token, most scanners + :escape => 'escape', # Ruby (string inline variables like #$foo, #@bar) + :exception => 'exception', # Java, PHP, Python + :filename => 'filename', # Diff + :float => 'float', # most scanners + :function => 'function', # CSS, JavaScript, PHP + :global_variable => 'global-variable', # Ruby, YAML + :hex => 'hex', # hexadecimal number; lots of scanners + :id => 'id', # CSS + :imaginary => 'imaginary', # Python + :important => 'important', # CSS, Taskpaper + :include => 'include', # C, Groovy, Java, Python, Sass + :inline => 'inline', # nested code, eg. inline string evaluation; lots of scanners + :inline_delimiter => 'inline-delimiter', # used instead of :inline > :delimiter FIXME: Why use inline_delimiter? + :instance_variable => 'instance-variable', # Ruby + :integer => 'integer', # most scanners + :key => 'key', # lots of scanners, used together with :value + :keyword => 'keyword', # reserved word that's actually implemented; most scanners + :label => 'label', # C, PHP + :local_variable => 'local-variable', # local and magic variables; some scanners + :map => 'map', # Lua tables + :modifier => 'modifier', # used inside on strings; lots of scanners + :namespace => 'namespace', # Clojure, Java, Taskpaper + :octal => 'octal', # lots of scanners + :predefined => 'predefined', # predefined function: lots of scanners + :predefined_constant => 'predefined-constant',# lots of scanners + :predefined_type => 'predefined-type', # C, Java, PHP + :preprocessor => 'preprocessor', # C, Delphi, HTML + :pseudo_class => 'pseudo-class', # CSS + :regexp => 'regexp', # Groovy, JavaScript, Ruby + :reserved => 'reserved', # most scanners + :shell => 'shell', # Ruby + :string => 'string', # most scanners + :symbol => 'symbol', # Clojure, Ruby, YAML + :tag => 'tag', # CSS, HTML + :type => 'type', # CSS, Java, SQL, YAML + :value => 'value', # used together with :key; CSS, JSON, YAML + :variable => 'variable', # Sass, SQL, YAML + + :change => 'change', # Diff + :delete => 'delete', # Diff + :head => 'head', # Diff, YAML + :insert => 'insert', # Diff + :eyecatcher => 'eyecatcher', # Diff + + :ident => false, # almost all scanners + :operator => false, # almost all scanners + + :space => false, # almost all scanners + :plain => false # almost all scanners + ) + + TokenKinds[:method] = TokenKinds[:function] + TokenKinds[:unknown] = TokenKinds[:plain] +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens.rb new file mode 100644 index 0000000..e7bffce --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens.rb @@ -0,0 +1,161 @@ +module CodeRay + + # The Tokens class represents a list of tokens returned from + # a Scanner. It's actually just an Array with a few helper methods. + # + # A token itself is not a special object, just two elements in an Array: + # * the _token_ _text_ (the original source of the token in a String) or + # a _token_ _action_ (begin_group, end_group, begin_line, end_line) + # * the _token_ _kind_ (a Symbol representing the type of the token) + # + # It looks like this: + # + # ..., '# It looks like this', :comment, ... + # ..., '3.1415926', :float, ... + # ..., '$^', :error, ... + # + # Some scanners also yield sub-tokens, represented by special + # token actions, for example :begin_group and :end_group. + # + # The Ruby scanner, for example, splits "a string" into: + # + # [ + # :begin_group, :string, + # '"', :delimiter, + # 'a string', :content, + # '"', :delimiter, + # :end_group, :string + # ] + # + # Tokens can be used to save the output of a Scanners in a simple + # Ruby object that can be send to an Encoder later: + # + # tokens = CodeRay.scan('price = 2.59', :ruby).tokens + # tokens.encode(:html) + # tokens.html + # CodeRay.encoder(:html).encode_tokens(tokens) + # + # Tokens gives you the power to handle pre-scanned code very easily: + # You can serialize it to a JSON string and store it in a database, pass it + # around to encode it more than once, send it to other algorithms... + class Tokens < Array + + # The Scanner instance that created the tokens. + attr_accessor :scanner + + # Encode the tokens using encoder. + # + # encoder can be + # * a plugin name like :html oder 'statistic' + # * an Encoder object + # + # options are passed to the encoder. + def encode encoder, options = {} + encoder = Encoders[encoder].new options if encoder.respond_to? :to_sym + encoder.encode_tokens self, options + end + + # Turn tokens into a string by concatenating them. + def to_s + encode CodeRay::Encoders::Encoder.new + end + + # Redirects unknown methods to encoder calls. + # + # For example, if you call +tokens.html+, the HTML encoder + # is used to highlight the tokens. + def method_missing meth, options = {} + encode meth, options + rescue PluginHost::PluginNotFound + super + end + + # Split the tokens into parts of the given +sizes+. + # + # The result will be an Array of Tokens objects. The parts have + # the text size specified by the parameter. In addition, each + # part closes all opened tokens. This is useful to insert tokens + # betweem them. + # + # This method is used by @Scanner#tokenize@ when called with an Array + # of source strings. The Diff encoder uses it for inline highlighting. + def split_into_parts *sizes + return Array.new(sizes.size) { Tokens.new } if size == 2 && first == '' + parts = [] + opened = [] + content = nil + part = Tokens.new + part_size = 0 + size = sizes.first + i = 0 + for item in self + case content + when nil + content = item + when String + if size && part_size + content.size > size # token must be cut + if part_size < size # some part of the token goes into this part + content = content.dup # content may no be safe to change + part << content.slice!(0, size - part_size) << item + end + # close all open groups and lines... + closing = opened.reverse.flatten.map do |content_or_kind| + case content_or_kind + when :begin_group + :end_group + when :begin_line + :end_line + else + content_or_kind + end + end + part.concat closing + begin + parts << part + part = Tokens.new + size = sizes[i += 1] + end until size.nil? || size > 0 + # ...and open them again. + part.concat opened.flatten + part_size = 0 + redo unless content.empty? + else + part << content << item + part_size += content.size + end + content = nil + when Symbol + case content + when :begin_group, :begin_line + opened << [content, item] + when :end_group, :end_line + opened.pop + else + raise ArgumentError, 'Unknown token action: %p, kind = %p' % [content, item] + end + part << content << item + content = nil + else + raise ArgumentError, 'Token input junk: %p, kind = %p' % [content, item] + end + end + parts << part + parts << Tokens.new while parts.size < sizes.size + parts + end + + # Return the actual number of tokens. + def count + size / 2 + end + + alias text_token push + def begin_group kind; push :begin_group, kind end + def end_group kind; push :end_group, kind end + def begin_line kind; push :begin_line, kind end + def end_line kind; push :end_line, kind end + alias tokens concat + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens_proxy.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens_proxy.rb new file mode 100644 index 0000000..31ff39b --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens_proxy.rb @@ -0,0 +1,55 @@ +module CodeRay + + # The result of a scan operation is a TokensProxy, but should act like Tokens. + # + # This proxy makes it possible to use the classic CodeRay.scan.encode API + # while still providing the benefits of direct streaming. + class TokensProxy + + attr_accessor :input, :lang, :options, :block + + # Create a new TokensProxy with the arguments of CodeRay.scan. + def initialize input, lang, options = {}, block = nil + @input = input + @lang = lang + @options = options + @block = block + end + + # Call CodeRay.encode if +encoder+ is a Symbol; + # otherwise, convert the receiver to tokens and call encoder.encode_tokens. + def encode encoder, options = {} + if encoder.respond_to? :to_sym + CodeRay.encode(input, lang, encoder, options) + else + encoder.encode_tokens tokens, options + end + end + + # Tries to call encode; + # delegates to tokens otherwise. + def method_missing method, *args, &blk + encode method.to_sym, *args + rescue PluginHost::PluginNotFound + tokens.send(method, *args, &blk) + end + + # The (cached) result of the tokenized input; a Tokens instance. + def tokens + @tokens ||= scanner.tokenize(input) + end + + # A (cached) scanner instance to use for the scan task. + def scanner + @scanner ||= CodeRay.scanner(lang, options, &block) + end + + # Overwrite Struct#each. + def each *args, &blk + tokens.each(*args, &blk) + self + end + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/version.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/version.rb new file mode 100644 index 0000000..4b4f085 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/version.rb @@ -0,0 +1,3 @@ +module CodeRay + VERSION = '1.1.0' +end diff --git a/vendor/bundle/gems/coderay-1.1.0/test/functional/basic.rb b/vendor/bundle/gems/coderay-1.1.0/test/functional/basic.rb new file mode 100755 index 0000000..752d4ba --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/test/functional/basic.rb @@ -0,0 +1,318 @@ +# encoding: utf-8 +require 'test/unit' +require File.expand_path('../../lib/assert_warning', __FILE__) + +$:.unshift File.expand_path('../../../lib', __FILE__) +require 'coderay' + +class BasicTest < Test::Unit::TestCase + + def test_version + assert_nothing_raised do + assert_match(/\A\d\.\d\.\d?\z/, CodeRay::VERSION) + end + end + + def with_empty_load_path + old_load_path = $:.dup + $:.clear + yield + ensure + $:.replace old_load_path + end + + def test_autoload + with_empty_load_path do + assert_nothing_raised do + CodeRay::Scanners::Java::BuiltinTypes + end + end + end + + RUBY_TEST_CODE = 'puts "Hello, World!"' + + RUBY_TEST_TOKENS = [ + ['puts', :ident], + [' ', :space], + [:begin_group, :string], + ['"', :delimiter], + ['Hello, World!', :content], + ['"', :delimiter], + [:end_group, :string] + ].flatten + def test_simple_scan + assert_nothing_raised do + assert_equal RUBY_TEST_TOKENS, CodeRay.scan(RUBY_TEST_CODE, :ruby).tokens + end + end + + RUBY_TEST_HTML = 'puts "' + + 'Hello, World!"' + def test_simple_highlight + assert_nothing_raised do + assert_equal RUBY_TEST_HTML, CodeRay.scan(RUBY_TEST_CODE, :ruby).html + end + end + + def test_scan_file + CodeRay.scan_file __FILE__ + end + + def test_encode + assert_equal 1, CodeRay.encode('test', :python, :count) + end + + def test_encode_tokens + assert_equal 1, CodeRay.encode_tokens(CodeRay::Tokens['test', :string], :count) + end + + def test_encode_file + assert_equal File.read(__FILE__), CodeRay.encode_file(__FILE__, :text) + end + + def test_highlight + assert_match '
test
', CodeRay.highlight('test', :python) + end + + def test_highlight_file + assert_match "require 'test/unit'\n", CodeRay.highlight_file(__FILE__) + end + + def test_duo + assert_equal(RUBY_TEST_CODE, + CodeRay::Duo[:plain, :text].highlight(RUBY_TEST_CODE)) + assert_equal(RUBY_TEST_CODE, + CodeRay::Duo[:plain => :text].highlight(RUBY_TEST_CODE)) + end + + def test_duo_stream + assert_equal(RUBY_TEST_CODE, + CodeRay::Duo[:plain, :text].highlight(RUBY_TEST_CODE, :stream => true)) + end + + def test_comment_filter + assert_equal <<-EXPECTED, CodeRay.scan(<<-INPUT, :ruby).comment_filter.text +#!/usr/bin/env ruby + +code + +more code + EXPECTED +#!/usr/bin/env ruby +=begin +A multi-line comment. +=end +code +# A single-line comment. +more code # and another comment, in-line. + INPUT + end + + def test_lines_of_code + assert_equal 2, CodeRay.scan(<<-INPUT, :ruby).lines_of_code +#!/usr/bin/env ruby +=begin +A multi-line comment. +=end +code +# A single-line comment. +more code # and another comment, in-line. + INPUT + rHTML = <<-RHTML + + + + + + <%= controller.controller_name.titleize %>: <%= controller.action_name %> + <%= stylesheet_link_tag 'scaffold' %> + + + +

<%= flash[:notice] %>

+ +
+ <%= yield %> +
+ + + + RHTML + assert_equal 0, CodeRay.scan(rHTML, :html).lines_of_code + assert_equal 0, CodeRay.scan(rHTML, :php).lines_of_code + assert_equal 0, CodeRay.scan(rHTML, :yaml).lines_of_code + assert_equal 4, CodeRay.scan(rHTML, :erb).lines_of_code + end + + def test_list_of_encoders + assert_kind_of(Array, CodeRay::Encoders.list) + assert CodeRay::Encoders.list.include?(:count) + end + + def test_list_of_scanners + assert_kind_of(Array, CodeRay::Scanners.list) + assert CodeRay::Scanners.list.include?(:text) + end + + def test_token_kinds + assert_kind_of Hash, CodeRay::TokenKinds + for kind, css_class in CodeRay::TokenKinds + assert_kind_of Symbol, kind + if css_class != false + assert_kind_of String, css_class, "TokenKinds[%p] == %p" % [kind, css_class] + end + end + assert_equal 'reserved', CodeRay::TokenKinds[:reserved] + assert_equal false, CodeRay::TokenKinds[:shibboleet] + end + + class Milk < CodeRay::Encoders::Encoder + FILE_EXTENSION = 'cocoa' + end + + class HoneyBee < CodeRay::Encoders::Encoder + end + + def test_encoder_file_extension + assert_nothing_raised do + assert_equal 'html', CodeRay::Encoders::Page::FILE_EXTENSION + assert_equal 'cocoa', Milk::FILE_EXTENSION + assert_equal 'cocoa', Milk.new.file_extension + assert_equal 'honeybee', HoneyBee::FILE_EXTENSION + assert_equal 'honeybee', HoneyBee.new.file_extension + end + assert_raise NameError do + HoneyBee::MISSING_CONSTANT + end + end + + def test_encoder_tokens + encoder = CodeRay::Encoders::Encoder.new + encoder.send :setup, {} + assert_raise(ArgumentError) { encoder.token :strange, '' } + encoder.token 'test', :debug + end + + def test_encoder_deprecated_interface + encoder = CodeRay::Encoders::Encoder.new + encoder.send :setup, {} + assert_warning 'Using old Tokens#<< interface.' do + encoder << ['test', :content] + end + assert_raise ArgumentError do + encoder << [:strange, :input] + end + assert_raise ArgumentError do + encoder.encode_tokens [['test', :token]] + end + end + + def encoder_token_interface_deprecation_warning_given + CodeRay::Encoders::Encoder.send :class_variable_get, :@@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN + end + + def test_scanner_file_extension + assert_equal 'rb', CodeRay::Scanners::Ruby.file_extension + assert_equal 'rb', CodeRay::Scanners::Ruby.new.file_extension + assert_equal 'java', CodeRay::Scanners::Java.file_extension + assert_equal 'java', CodeRay::Scanners::Java.new.file_extension + end + + def test_scanner_lang + assert_equal :ruby, CodeRay::Scanners::Ruby.lang + assert_equal :ruby, CodeRay::Scanners::Ruby.new.lang + assert_equal :java, CodeRay::Scanners::Java.lang + assert_equal :java, CodeRay::Scanners::Java.new.lang + end + + def test_scanner_tokenize + assert_equal ['foo', :plain], CodeRay::Scanners::Plain.new.tokenize('foo') + assert_equal [['foo', :plain], ['bar', :plain]], CodeRay::Scanners::Plain.new.tokenize(['foo', 'bar']) + CodeRay::Scanners::Plain.new.tokenize 42 + end + + def test_scanner_tokens + scanner = CodeRay::Scanners::Plain.new + scanner.tokenize('foo') + assert_equal ['foo', :plain], scanner.tokens + scanner.string = '' + assert_equal ['', :plain], scanner.tokens + end + + def test_scanner_line_and_column + scanner = CodeRay::Scanners::Plain.new "foo\nbär+quux" + assert_equal 0, scanner.pos + assert_equal 1, scanner.line + assert_equal 1, scanner.column + scanner.scan(/foo/) + assert_equal 3, scanner.pos + assert_equal 1, scanner.line + assert_equal 4, scanner.column + scanner.scan(/\n/) + assert_equal 4, scanner.pos + assert_equal 2, scanner.line + assert_equal 1, scanner.column + scanner.scan(/b/) + assert_equal 5, scanner.pos + assert_equal 2, scanner.line + assert_equal 2, scanner.column + scanner.scan(/a/) + assert_equal 5, scanner.pos + assert_equal 2, scanner.line + assert_equal 2, scanner.column + scanner.scan(/ä/) + assert_equal 7, scanner.pos + assert_equal 2, scanner.line + assert_equal 4, scanner.column + scanner.scan(/r/) + assert_equal 8, scanner.pos + assert_equal 2, scanner.line + assert_equal 5, scanner.column + end + + def test_scanner_use_subclasses + assert_raise NotImplementedError do + CodeRay::Scanners::Scanner.new + end + end + + class InvalidScanner < CodeRay::Scanners::Scanner + end + + def test_scanner_scan_tokens + assert_raise NotImplementedError do + InvalidScanner.new.tokenize '' + end + end + + class RaisingScanner < CodeRay::Scanners::Scanner + def scan_tokens encoder, options + raise_inspect 'message', [], :initial + end + end + + def test_scanner_raise_inspect + assert_raise CodeRay::Scanners::Scanner::ScanError do + RaisingScanner.new.tokenize '' + end + end + + def test_scan_a_frozen_string + assert_nothing_raised do + CodeRay.scan RUBY_VERSION, :ruby + CodeRay.scan RUBY_VERSION, :plain + end + end + + def test_scan_a_non_string + assert_nothing_raised do + CodeRay.scan 42, :ruby + CodeRay.scan nil, :ruby + CodeRay.scan self, :ruby + CodeRay.encode ENV.to_hash, :ruby, :page + CodeRay.highlight CodeRay, :plain + end + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/test/functional/examples.rb b/vendor/bundle/gems/coderay-1.1.0/test/functional/examples.rb new file mode 100755 index 0000000..985ef87 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/test/functional/examples.rb @@ -0,0 +1,129 @@ +require 'test/unit' + +$:.unshift File.expand_path('../../../lib', __FILE__) +require 'coderay' + +class ExamplesTest < Test::Unit::TestCase + + def test_examples + # output as HTML div (using inline CSS styles) + div = CodeRay.scan('puts "Hello, world!"', :ruby).div + assert_equal <<-DIV, div +
+
puts "Hello, world!"
+
+ DIV + + # ...with line numbers + div = CodeRay.scan(<<-CODE.chomp, :ruby).div(:line_numbers => :table) +5.times do + puts 'Hello, world!' +end + CODE + assert_equal <<-DIV, div + + + +
1
+2
+3
+
5.times do
+  puts 'Hello, world!'
+end
+ DIV + + # output as standalone HTML page (using CSS classes) + page = CodeRay.scan('puts "Hello, world!"', :ruby).page + assert_match <<-PAGE, page + + + + + +
1
+
puts "Hello, world!"
+ + + PAGE + + # keep scanned tokens for later use + tokens = CodeRay.scan('{ "just": "an", "example": 42 }', :json) + assert_kind_of CodeRay::TokensProxy, tokens + + assert_equal ["{", :operator, " ", :space, :begin_group, :key, + "\"", :delimiter, "just", :content, "\"", :delimiter, + :end_group, :key, ":", :operator, " ", :space, + :begin_group, :string, "\"", :delimiter, "an", :content, + "\"", :delimiter, :end_group, :string, ",", :operator, + " ", :space, :begin_group, :key, "\"", :delimiter, + "example", :content, "\"", :delimiter, :end_group, :key, + ":", :operator, " ", :space, "42", :integer, + " ", :space, "}", :operator], tokens.tokens + + # produce a token statistic + assert_equal <<-STATISTIC, tokens.statistic + +Code Statistics + +Tokens 26 + Non-Whitespace 15 +Bytes Total 31 + +Token Types (7): + type count ratio size (average) +------------------------------------------------------------- + TOTAL 26 100.00 % 1.2 + delimiter 6 23.08 % 1.0 + operator 5 19.23 % 1.0 + space 5 19.23 % 1.0 + key 4 15.38 % 0.0 + :begin_group 3 11.54 % 0.0 + :end_group 3 11.54 % 0.0 + content 3 11.54 % 4.3 + string 2 7.69 % 0.0 + integer 1 3.85 % 2.0 + + STATISTIC + + # count the tokens + assert_equal 26, tokens.count + + # produce a HTML div, but with CSS classes + div = tokens.div(:css => :class) + assert_equal <<-DIV, div +
+
{ "just": "an", "example": 42 }
+
+ DIV + + # highlight a file (HTML div); guess the file type base on the extension + assert_equal :ruby, CodeRay::FileType[__FILE__] + + # get a new scanner for Python + python_scanner = CodeRay.scanner :python + assert_kind_of CodeRay::Scanners::Python, python_scanner + + # get a new encoder for terminal + terminal_encoder = CodeRay.encoder :term + assert_kind_of CodeRay::Encoders::Terminal, terminal_encoder + + # scanning into tokens + tokens = python_scanner.tokenize 'import this; # The Zen of Python' + assert_equal ["import", :keyword, " ", :space, "this", :include, + ";", :operator, " ", :space, "# The Zen of Python", :comment], tokens + + # format the tokens + term = terminal_encoder.encode_tokens(tokens) + assert_equal "\e[32mimport\e[0m \e[31mthis\e[0m; \e[1;30m# The Zen of Python\e[0m", term + + # re-using scanner and encoder + ruby_highlighter = CodeRay::Duo[:ruby, :div] + div = ruby_highlighter.encode('puts "Hello, world!"') + assert_equal <<-DIV, div +
+
puts "Hello, world!"
+
+ DIV + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/test/functional/for_redcloth.rb b/vendor/bundle/gems/coderay-1.1.0/test/functional/for_redcloth.rb new file mode 100644 index 0000000..9fd244e --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/test/functional/for_redcloth.rb @@ -0,0 +1,78 @@ +require 'test/unit' + +$:.unshift File.expand_path('../../../lib', __FILE__) +require 'coderay' + +begin + require 'rubygems' unless defined? Gem + gem 'RedCloth', '>= 4.0.3' rescue nil + require 'redcloth' +rescue LoadError + warn 'RedCloth not found - skipping for_redcloth tests.' + undef RedCloth if defined? RedCloth +end + +class BasicTest < Test::Unit::TestCase + + def test_for_redcloth + require 'coderay/for_redcloth' + assert_equal "

puts "Hello, World!"

", + RedCloth.new('@[ruby]puts "Hello, World!"@').to_html + assert_equal <<-BLOCKCODE.chomp, +
+
puts "Hello, World!"
+
+ BLOCKCODE + RedCloth.new('bc[ruby]. puts "Hello, World!"').to_html + end + + def test_for_redcloth_no_lang + require 'coderay/for_redcloth' + assert_equal "

puts \"Hello, World!\"

", + RedCloth.new('@puts "Hello, World!"@').to_html + assert_equal <<-BLOCKCODE.chomp, +
puts \"Hello, World!\"
+ BLOCKCODE + RedCloth.new('bc. puts "Hello, World!"').to_html + end + + def test_for_redcloth_style + require 'coderay/for_redcloth' + assert_equal <<-BLOCKCODE.chomp, +
puts \"Hello, World!\"
+ BLOCKCODE + RedCloth.new('bc{color: red}. puts "Hello, World!"').to_html + end + + def test_for_redcloth_escapes + require 'coderay/for_redcloth' + assert_equal '

>

', + RedCloth.new('@[ruby]>@').to_html + assert_equal <<-BLOCKCODE.chomp, +
+
&
+
+ BLOCKCODE + RedCloth.new('bc[ruby]. &').to_html + end + + def test_for_redcloth_escapes2 + require 'coderay/for_redcloth' + assert_equal "

#include <test.h>

", + RedCloth.new('@[c]#include @').to_html + end + + # See http://jgarber.lighthouseapp.com/projects/13054/tickets/124-code-markup-does-not-allow-brackets. + def test_for_redcloth_false_positive + require 'coderay/for_redcloth' + assert_equal '

[project]_dff.skjd

', + RedCloth.new('@[project]_dff.skjd@').to_html + # false positive, but expected behavior / known issue + assert_equal "

_dff.skjd

", + RedCloth.new('@[ruby]_dff.skjd@').to_html + assert_equal <<-BLOCKCODE.chomp, RedCloth.new('bc. [project]_dff.skjd').to_html +
[project]_dff.skjd
+ BLOCKCODE + end + +end if defined? RedCloth \ No newline at end of file diff --git a/vendor/bundle/gems/coderay-1.1.0/test/functional/suite.rb b/vendor/bundle/gems/coderay-1.1.0/test/functional/suite.rb new file mode 100755 index 0000000..ec23eec --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/test/functional/suite.rb @@ -0,0 +1,15 @@ +require 'test/unit' + +$VERBOSE = $CODERAY_DEBUG = true +$:.unshift File.expand_path('../../../lib', __FILE__) +require 'coderay' + +mydir = File.dirname(__FILE__) +suite = Dir[File.join(mydir, '*.rb')]. + map { |tc| File.basename(tc).sub(/\.rb$/, '') } - %w'suite for_redcloth' + +puts "Running basic CodeRay #{CodeRay::VERSION} tests: #{suite.join(', ')}" + +for test_case in suite + load File.join(mydir, test_case + '.rb') +end diff --git a/vendor/bundle/gems/columnize-0.8.9/.gitignore b/vendor/bundle/gems/columnize-0.8.9/.gitignore new file mode 100644 index 0000000..73f35cf --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/.gitignore @@ -0,0 +1,3 @@ +*~ +/doc +/pkg diff --git a/vendor/bundle/gems/columnize-0.8.9/.travis.yml b/vendor/bundle/gems/columnize-0.8.9/.travis.yml new file mode 100644 index 0000000..9292c33 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/.travis.yml @@ -0,0 +1,9 @@ +language: ruby + +rvm: + - 1.8.7 + - 1.9.3 + - 2.0.0 + - ruby-head + - rbx-18mode + - rbx-19mode diff --git a/vendor/bundle/gems/columnize-0.8.9/AUTHORS b/vendor/bundle/gems/columnize-0.8.9/AUTHORS new file mode 100644 index 0000000..463be9b --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/AUTHORS @@ -0,0 +1,2 @@ +R. Bernstein (rockyb@rubyforge.net) +M. Davis (waslogic@gmail.com) diff --git a/vendor/bundle/gems/columnize-0.8.9/COPYING b/vendor/bundle/gems/columnize-0.8.9/COPYING new file mode 100644 index 0000000..32e46ac --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/COPYING @@ -0,0 +1,57 @@ +Columnize is copyrighted free software by Rocky Bernstein . + +You can redistribute it and/or modify it under either the terms of the GPL +version 2, or the conditions below: + + 1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + + 2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b) use the modified software only within your corporation or + organization. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a) distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b) accompany the distribution with the machine-readable source of + the software. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + + 5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + + 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/gems/columnize-0.8.9/ChangeLog b/vendor/bundle/gems/columnize-0.8.9/ChangeLog new file mode 100644 index 0000000..becafe2 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/ChangeLog @@ -0,0 +1,282 @@ +2011-06-09 rocky + + * ChangeLog, NEWS, Rakefile: Get ready for new release. + +2011-04-27 r + + * README.md: Fix code example. + +2011-04-27 r + + * .gemspec, README, README.md, Rakefile: README->README.md + +2011-04-27 r + + * .gemspec, AUTHORS, COPYING, ChangeLog, Makefile, NEWS, README, + Rakefile, lib/Makefile, lib/columnize.rb, lib/version.rb, + tags/release-0.2.1/AUTHORS, tags/release-0.2.1/COPYING, + tags/release-0.2.1/ChangeLog, tags/release-0.2.1/NEWS, + tags/release-0.2.1/README, tags/release-0.2.1/Rakefile, + tags/release-0.2.1/VERSION, tags/release-0.2.1/lib/columnize.rb, + tags/release-0.2.1/test/test-columnize.rb, + tags/release-0.3.0/AUTHORS, tags/release-0.3.0/COPYING, + tags/release-0.3.0/ChangeLog, tags/release-0.3.0/NEWS, + tags/release-0.3.0/README, tags/release-0.3.0/Rakefile, + tags/release-0.3.0/VERSION, tags/release-0.3.0/lib/columnize.rb, + tags/release-0.3.0/test/test-columnize.rb, + tags/release-0.3.1/AUTHORS, tags/release-0.3.1/COPYING, + tags/release-0.3.1/ChangeLog, tags/release-0.3.1/NEWS, + tags/release-0.3.1/README, tags/release-0.3.1/Rakefile, + tags/release-0.3.1/VERSION, tags/release-0.3.1/lib/columnize.rb, + tags/release-0.3.1/test/test-columnize.rb, test/test-columnize.rb, + test/test-hashparm.rb, trunk/.gemspec, trunk/AUTHORS, + trunk/COPYING, trunk/ChangeLog, trunk/Makefile, trunk/NEWS, + trunk/README, trunk/Rakefile, trunk/lib/Makefile, + trunk/lib/columnize.rb, trunk/lib/version.rb, + trunk/test/test-columnize.rb, trunk/test/test-hashparm.rb: Remove + trunk and tags. + +2011-04-27 rockyb + + * trunk/ChangeLog, trunk/lib/columnize.rb, trunk/lib/version.rb, + trunk/test/test-columnize.rb, trunk/test/test-hashparm.rb: Redo + columnize options processing to allow for a single hash of options + instead of the numerous optional arguments. This make future + expansion easier. + +2010-09-22 rockyb + + * trunk/Makefile, trunk/Rakefile: Rakefile: Remove bad test task + Makefile: simplify. + +2010-09-21 rockyb + + * trunk/Makefile, trunk/Rakefile: Makefile was a little off + +2010-09-21 rockyb + + * trunk/.gemspec, trunk/Rakefile, trunk/lib/columnize.rb: Small + changes to Rakefile and rdoc and so on. + +2010-09-20 rockyb + + * trunk/.gemspec, trunk/Rakefile: Forgot to add .gemspec + +2010-09-20 rockyb + + * trunk/ChangeLog, trunk/Makefile, trunk/NEWS, trunk/README, + trunk/Rakefile, trunk/VERSION, trunk/lib/Makefile, + trunk/lib/columnize.rb, trunk/lib/version.rb: Add .gemspec, correct + description field and add a summary. Add Columnize::VERSION Simplify + Rakefile Add stub Makefiles + +2010-03-01 rockyb + + * trunk/README: Better README description + +2010-03-01 rockyb + + * trunk/README: Update README + +2010-02-22 rockyb + + * trunk/ChangeLog, trunk/VERSION, trunk/lib/columnize.rb: Remove + shadow variable warnings. Bump version number + +2009-07-26 rockyb + + * tags/release-0.3.1/AUTHORS, tags/release-0.3.1/COPYING, + tags/release-0.3.1/ChangeLog, tags/release-0.3.1/NEWS, + tags/release-0.3.1/README, tags/release-0.3.1/Rakefile, + tags/release-0.3.1/VERSION, tags/release-0.3.1/lib/columnize.rb, + tags/release-0.3.1/test/test-columnize.rb: Release 0.3.1 + +2009-07-26 rockyb + + * trunk/lib/columnize.rb: Small comment spelling typo. + +2009-07-26 rockyb + + * trunk/ChangeLog: Get ready for 0.3.1 release + +2009-07-26 rockyb + + * trunk/NEWS, trunk/lib/columnize.rb, trunk/test/test-columnize.rb: + Add lineprefix. Get ready for release. + +2009-07-26 mark-moseley + + * trunk/ChangeLog, trunk/lib/columnize.rb: Ruby 1.9 updates + +2009-03-30 rockyb + + * trunk/Rakefile: Revise for 1.9 version of rake + +2009-01-16 rockyb + + * trunk/ChangeLog, trunk/Rakefile, trunk/VERSION: package readme was + wonky. Looks like no one reads this stuff. + +2009-01-10 rockyb + + * tags/release-0.3.0/AUTHORS, tags/release-0.3.0/COPYING, + tags/release-0.3.0/ChangeLog, tags/release-0.3.0/NEWS, + tags/release-0.3.0/README, tags/release-0.3.0/Rakefile, + tags/release-0.3.0/VERSION, tags/release-0.3.0/lib/columnize.rb, + tags/release-0.3.0/test/test-columnize.rb: Release 0.3.0 + +2009-01-10 rockyb + + * trunk/ChangeLog, trunk/NEWS: Get ready for release + +2009-01-08 rockyb + + * trunk/ChangeLog, trunk/NEWS, trunk/VERSION, + trunk/lib/columnize.rb, trunk/test/test-columnize.rb: Fix bad bug in + arranging horizontally + +2009-01-01 rockyb + + * columnize/trunk/AUTHORS, columnize/trunk/COPYING, + columnize/trunk/ChangeLog, columnize/trunk/NEWS, + columnize/trunk/README, columnize/trunk/Rakefile, + columnize/trunk/VERSION, columnize/trunk/lib/columnize.rb, + columnize/trunk/test/test-columnize.rb: Remove hacky + columnize/columnize + +2009-01-01 rockyb + + * tags/columnize-0.2/AUTHORS, tags/columnize-0.2/COPYING, + tags/columnize-0.2/ChangeLog, tags/columnize-0.2/NEWS, + tags/columnize-0.2/README, tags/columnize-0.2/Rakefile, + tags/columnize-0.2/VERSION, tags/columnize-0.2/lib/columnize.rb, + tags/columnize-0.2/test/test-columnize.rb: Regularize tags names + better + +2009-01-01 rockyb + + * tags/release-0.2.1/AUTHORS, tags/release-0.2.1/COPYING, + tags/release-0.2.1/ChangeLog, tags/release-0.2.1/NEWS, + tags/release-0.2.1/README, tags/release-0.2.1/Rakefile, + tags/release-0.2.1/VERSION, tags/release-0.2.1/lib/columnize.rb, + tags/release-0.2.1/test/test-columnize.rb: Release 0.2.1 + +2009-01-01 rockyb + + * trunk/NEWS: Merge NEWS + +2009-01-01 rockyb + + * columnize/tags/columnize-0.2/AUTHORS, + columnize/tags/columnize-0.2/COPYING, + columnize/tags/columnize-0.2/ChangeLog, + columnize/tags/columnize-0.2/NEWS, + columnize/tags/columnize-0.2/README, + columnize/tags/columnize-0.2/Rakefile, + columnize/tags/columnize-0.2/VERSION, + columnize/tags/columnize-0.2/lib/columnize.rb, + columnize/tags/columnize-0.2/test/test-columnize.rb, + tags/columnize-0.2/AUTHORS, tags/columnize-0.2/COPYING, + tags/columnize-0.2/ChangeLog, tags/columnize-0.2/NEWS, + tags/columnize-0.2/README, tags/columnize-0.2/Rakefile, + tags/columnize-0.2/VERSION, tags/columnize-0.2/lib/columnize.rb, + tags/columnize-0.2/test/test-columnize.rb: Cleanup of + columnize/columnize crap + +2009-01-01 rockyb + + * : Add directory for releases + +2009-01-01 rockyb + + * trunk/NEWS, trunk/VERSION: Ooops 0.2 release done. Go for 0.2.1 + +2009-01-01 rockyb + + * trunk/ChangeLog: Get ready for release 0.2 + +2009-01-01 rockyb + + * trunk/ChangeLog, trunk/NEWS, trunk/VERSION, + trunk/lib/columnize.rb, trunk/test/test-columnize.rb: Get ready for + release 0.2 + +2008-09-22 rockyb + + * columnize/tags/columnize-0.2/AUTHORS, + columnize/tags/columnize-0.2/COPYING, + columnize/tags/columnize-0.2/ChangeLog, + columnize/tags/columnize-0.2/NEWS, + columnize/tags/columnize-0.2/README, + columnize/tags/columnize-0.2/Rakefile, + columnize/tags/columnize-0.2/VERSION, + columnize/tags/columnize-0.2/lib/columnize.rb, + columnize/tags/columnize-0.2/test/test-columnize.rb: Tag 0.2 + release. + +2008-09-22 rockyb + + * : Add tags directory for release + +2008-09-22 rockyb + + * columnize/trunk/ChangeLog, columnize/trunk/NEWS: Add directory for + tagging releases. Other Administrivia. + +2008-09-22 rockyb + + * columnize/trunk/VERSION, columnize/trunk/lib/columnize.rb: Get rid + of hacky $0 test. + +2008-03-16 rockyb + + * trunk/lib/columnize.rb: [no log message] + +2008-03-16 rockyb + + * trunk/lib/columnize.rb: Simplify __FILE__ == $0. (rdebug now + changes $0 and rcov has an option) + +2008-02-11 rockyb + + * trunk/lib/columnize.rb: Remove 1.9's shadow warning + +2007-12-10 rockyb + + * columnize/trunk/AUTHORS, columnize/trunk/COPYING, + columnize/trunk/ChangeLog, columnize/trunk/NEWS, + columnize/trunk/README, columnize/trunk/Rakefile, + columnize/trunk/VERSION, columnize/trunk/lib/columnize.rb, + columnize/trunk/test/test-columnize.rb: release 0.1 + +2007-12-09 rockyb + + * trunk/README, trunk/Rakefile: Fix up doc a little. Make the + default rake task "test". + +2007-12-09 rockyb + + * trunk/lib/columnize.rb: Doc fix. + +2007-12-09 rockyb + + * trunk/ChangeLog, trunk/lib/columnize.rb, + trunk/test/test-columnize.rb: columnize.rb: Allow one to specify a + separator string. Remove restriction that all entries in the array + have to be a string. test-columnize.rb: more tests - invalid list, + empty list, with separator string parameter. + +2007-12-09 rockyb + + * trunk/test/test-columnize.rb: Typo. + +2007-12-09 rockyb + + * : Property changes for Id lines and to make test-columnize.rb + executable. + +2007-12-09 rockyb + + * Initial release of Columnize, a module to print an Array in + column-sorted order. + diff --git a/vendor/bundle/gems/columnize-0.8.9/Gemfile b/vendor/bundle/gems/columnize-0.8.9/Gemfile new file mode 100644 index 0000000..fa75df1 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gemspec diff --git a/vendor/bundle/gems/columnize-0.8.9/Makefile b/vendor/bundle/gems/columnize-0.8.9/Makefile new file mode 100644 index 0000000..7f690e9 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/Makefile @@ -0,0 +1,15 @@ +# I'll admit it -- I'm an absent-minded old-timer who has trouble +# learning new tricks. + +RUBY ?= ruby +RAKE ?= rake + +test: check + +#: Default target; same as "make check" +all: check + true + +#: Same as corresponding rake task +%: + $(RAKE) $@ diff --git a/vendor/bundle/gems/columnize-0.8.9/NEWS b/vendor/bundle/gems/columnize-0.8.9/NEWS new file mode 100644 index 0000000..303c211 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/NEWS @@ -0,0 +1,58 @@ +0.8.9 Apr 19, 2014 +- Add columnize method to Array class and a place to set its default options +- Add option :colfmt to allow a format specifier to use (e.g. '%02d') in stringifying + list items +- Add option linesuffix (default is "\n") +- When using arrange_array each line now has trailing "," + +0.3.6 Dec 17, 2011 +- rename version.rb columnize/version.rb so as not to conflict with + another package called version +- Administrivia - shorten gemcutter description + +0.3.5 Nov 24, 2011 +- Handle situation where an array element is larger than the display width. + +0.3.4 July 4, 2011 + +- Change to Ruby License +- Add option 'term_adjust' to ignore terminal sequences in text +- Add :ljust => :auto to decide whether or not to automatically + left or right justify. When passing a hash parameter, the default + is :auto. + +0.3.3 June 12, 2011 Fleetwood release + +- More general but simpler inteface using an options + hash. Compatibility is maintaind though. + +0.3.2 + +- Mostly Administrivia. + * Add .gemspec, correct description field and add a summary. + * Add Columnize::VERSION + * Simplify Rakefile + * Add stub Makefiles + +0.3.1 (01-07-26) + +- Correct for Ruby 1.9 (Mark Moseley) + +- add optional lineprefix parameter + +0.3.0 (01-10-09) - Sam Woodward Release + +- Fix bad bug in arranging horizontally + +0.2.1 (12-31-08) + +- Add ability to run columns horizontally + +0.2 + +- Minor - get rid of hacky $0 test + +0.1 + +- Initial release of Columnize, a module to print an Array in + column-sorted order diff --git a/vendor/bundle/gems/columnize-0.8.9/README.md b/vendor/bundle/gems/columnize-0.8.9/README.md new file mode 100644 index 0000000..027f525 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/README.md @@ -0,0 +1,108 @@ +[![Build Status](https://travis-ci.org/rocky/columnize.png)](https://travis-ci.org/rocky/columnize) + +Columnize - Format an Array as a Column-aligned String +============================================================================ + +In showing a long lists, sometimes one would prefer to see the value +arranged aligned in columns. Some examples include listing methods of +an object, listing debugger commands, or showing a numeric array with data +aligned. + +Setup +----- + + $ irb + >> require 'columnize' + => true + +With numeric data +----------------- + + >> a = (1..10).to_a + => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + >> a.columnize + => "1 2 3 4 5 6 7 8 9 10" + + >> puts a.columnize :arrange_array => true, :displaywidth => 10 + [1, 2, 3, + 4, 5, 6, + 7, 8, 9, + 10] + => nil + + >> puts a.columnize :arrange_array => true, :displaywidth => 20 + [1, 2, 3, 4, 5, 6, + 7, 8, 9, 10] + => nil + +With String data +---------------- + + >> g = %w(bibrons golden madascar leopard mourning suras tokay) + => ["bibrons", "golden", "madascar", "leopard", "mourning", "suras", "tokay"] + + >> puts g.columnize :displaywidth => 15 + bibrons suras + golden tokay + madascar + leopard + mourning + => nil + + >> puts g.columnize :displaywidth => 19, :colsep => ' | ' + bibrons | suras + golden | tokay + madascar + leopard + mourning + => nil + + >> puts g.columnize :displaywidth => 18, :colsep => ' | ', :ljust => false + bibrons | mourning + golden | suras + madascar | tokay + leopard + => nil + +Using Columnize.columnize +------------------------- + + >> Columnize.columnize(a) + => "1 2 3 4 5 6 7 8 9 10" + + >> puts Columnize.columnize(a, :displaywidth => 10) + 1 5 9 + 2 6 10 + 3 7 + 4 8 + => nil + + >> Columnize.columnize(g) + => "bibrons golden madascar leopard mourning suras tokay" + + >> puts Columnize.columnize(g, :displaywidth => 19, :colsep => ' | ') + bibrons | mourning + golden | suras + madascar | tokay + leopard + => nil + + +Credits +------- + +This is adapted from a method of the same name from Python's cmd module. + +Other stuff +----------- + +Authors: Rocky Bernstein [![endorse](https://api.coderwall.com/rocky/endorsecount.png)](https://coderwall.com/rocky) and [Martin Davis](https://github.com/waslogic) + +License: Copyright (c) 2011,2013 Rocky Bernstein + +Warranty +-------- + +You can redistribute it and/or modify it under either the terms of the GPL +version 2 or the conditions listed in COPYING diff --git a/vendor/bundle/gems/columnize-0.8.9/Rakefile b/vendor/bundle/gems/columnize-0.8.9/Rakefile new file mode 100644 index 0000000..f3f55de --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/Rakefile @@ -0,0 +1,105 @@ +#!/usr/bin/env rake +# -*- Ruby -*- +require 'rubygems' +require 'fileutils' + +ROOT_DIR = File.dirname(__FILE__) +Gemspec_filename = 'columnize.gemspec' +require File.join %W(#{ROOT_DIR} lib columnize version) + +def gemspec + @gemspec ||= eval(File.read(Gemspec_filename), binding, Gemspec_filename) +end + +require 'rubygems/package_task' +desc "Build the gem" +task :package=>:gem +task :gem=>:gemspec do + Dir.chdir(ROOT_DIR) do + sh "gem build columnize.gemspec" + FileUtils.mkdir_p 'pkg' + FileUtils.mv gemspec.file_name, 'pkg' + end +end + +desc "Install the gem locally" +task :install => :gem do + Dir.chdir(ROOT_DIR) do + sh %{gem install --local pkg/#{gemspec.file_name}} + end +end + +require 'rake/testtask' +desc "Test everything." +Rake::TestTask.new(:test) do |t| + t.libs << './lib' + t.test_files = FileList['test/test-*.rb'] + t.verbose = true +end +task :test => :lib + +desc "same as test" +task :check => :test + +desc "same as test" +task :columnize => :test + +desc 'Create a GNU-style ChangeLog via git2cl' +task :ChangeLog do + system('git log --pretty --numstat --summary | git2cl > ChangeLog') +end + +task :default => [:test] + +desc 'Create a GNU-style ChangeLog via git2cl' +task :ChangeLog do + system('git log --pretty --numstat --summary | git2cl > ChangeLog') +end + +desc "Generate the gemspec" +task :generate do + puts gemspec.to_ruby +end + +desc "Validate the gemspec" +task :gemspec do + gemspec.validate +end + +# --------- RDoc Documentation ------ +require 'rdoc/task' +desc "Generate rdoc documentation" +Rake::RDocTask.new("rdoc") do |rdoc| + rdoc.rdoc_dir = 'doc' + rdoc.title = "Columnize #{Columnize::VERSION} Documentation" + + # Make the README file the start page for the generated html + rdoc.options += %w(--main README.md) + + rdoc.rdoc_files.include('lib/*.rb', 'README.md', 'COPYING') +end + +desc "Same as rdoc" +task :doc => :rdoc + +task :clobber_package do + FileUtils.rm_rf File.join(ROOT_DIR, 'pkg') +end + +task :clobber_rdoc do + FileUtils.rm_rf File.join(ROOT_DIR, 'doc') +end + +desc 'Remove residue from running patch' +task :rm_patch_residue do + FileUtils.rm_rf Dir.glob('**/*.{rej,orig}'), :verbose => true +end + +desc 'Remove ~ backup files' +task :rm_tilde_backups do + FileUtils.rm_rf Dir.glob('**/*~'), :verbose => true +end + +desc 'Remove built files' +task :clean => [:clobber_package, :clobber_rdoc, :rm_patch_residue, + :rm_tilde_backups] diff --git a/vendor/bundle/gems/columnize-0.8.9/THANKS b/vendor/bundle/gems/columnize-0.8.9/THANKS new file mode 100644 index 0000000..56e07f8 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/THANKS @@ -0,0 +1,8 @@ +I am indebted to: + +Mark Moseley: + the initial port from 1.8 to 1.9 +Martin Davis: + how to extend into Array classes and set options from there +David Rodríguez de Dios: + Miscellaneous portability fixes and doggedness to get out a new release diff --git a/vendor/bundle/gems/columnize-0.8.9/columnize.gemspec b/vendor/bundle/gems/columnize-0.8.9/columnize.gemspec new file mode 100644 index 0000000..6ad5267 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/columnize.gemspec @@ -0,0 +1,38 @@ +# -*- Ruby -*- +# -*- encoding: utf-8 -*- +require 'rake' +require 'rubygems' unless + Object.const_defined?(:Gem) +require File.dirname(__FILE__) + "/lib/columnize/version" unless + Object.const_defined?(:'Columnize') + +Gem::Specification.new do |spec| + spec.authors = ['Rocky Bernstein'] + spec.date = Time.now + spec.description = ' +In showing a long lists, sometimes one would prefer to see the value +arranged aligned in columns. Some examples include listing methods +of an object or debugger commands. +See Examples in the rdoc documentation for examples. +' + spec.email = 'rockyb@rubyforge.net' + spec.files = `git ls-files`.split("\n") + spec.homepage = 'https://github.com/rocky/columnize' + spec.name = 'columnize' + spec.licenses = ['Ruby', 'GPL2'] + spec.platform = Gem::Platform::RUBY + spec.require_path = 'lib' + spec.required_ruby_version = '>= 1.8.2' + spec.rubyforge_project = 'columnize' + spec.summary = 'Module to format an Array as an Array of String aligned in columns' + spec.version = Columnize::VERSION + spec.has_rdoc = true + spec.extra_rdoc_files = %w(README.md lib/columnize.rb COPYING THANKS) + + # Make the readme file the start page for the generated html + spec.rdoc_options += %w(--main README) + spec.rdoc_options += ['--title', "Columnize #{Columnize::VERSION} Documentation"] + + spec.add_development_dependency 'rdoc' + spec.add_development_dependency 'rake' +end diff --git a/vendor/bundle/gems/columnize-0.8.9/lib/Makefile b/vendor/bundle/gems/columnize-0.8.9/lib/Makefile new file mode 100644 index 0000000..b1a10e5 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/lib/Makefile @@ -0,0 +1,10 @@ +# Whatever it is you want to do, it should be handled by the main +# (parent) Makefile. So reissue make from there. +PHONY=check all + +#: Default target - the parent's testing or "check" target +all: check + +#: Whatever it is you want to do, it should be handled by the parent +%: + $(MAKE) -C .. $@ diff --git a/vendor/bundle/gems/columnize-0.8.9/lib/columnize.rb b/vendor/bundle/gems/columnize-0.8.9/lib/columnize.rb new file mode 100644 index 0000000..3469ae4 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/lib/columnize.rb @@ -0,0 +1,137 @@ +# Module to format an Array into a single string with embedded +# newlines, On printing the string, the columns are aligned. +# +# == Summary +# +# Return a string from an array with embedded newlines formatted so +# that when printed the columns are aligned. +# See below for examples and options to the main method +columnize+. +# +# +# == License +# +# Columnize is copyright (C) 2007-2011, 2013 Rocky Bernstein +# +# +# All rights reserved. You can redistribute and/or modify it under +# the same terms as Ruby. +# +# Also available in Python (columnize), and Perl (Array::Columnize) + +module Columnize + # Pull in the rest of my pieces + ROOT_DIR = File.dirname(__FILE__) + %w(opts columnize version).each do |submod| + require File.join %W(#{ROOT_DIR} columnize #{submod}) + end + + # Add +columnize_opts+ instance variable to classes that mix in this module. The type should be a kind of hash in file +columnize/opts+. + attr_accessor :columnize_opts + + # Columnize.columize([args]) => String + # + # Return a string from an array with embedded newlines formatted so + # that when printed the columns are aligned. + # + # For example, for a line width of 4 characters (arranged vertically): + # a = (1..4).to_a + # Columnize.columnize(a) => '1 3\n2 4\n' + # + # Alternatively: + # a.columnize => '1 3\n2 4\n' + # + # Arranged horizontally: + # a.columnize(:arrange_vertical => false) => + # ['1', '2,', '3', '4'] => '1 2\n3 4\n' + # + # Formatted as an array using format specifier '%02d': + # puts (1..10).to_a.columnize(:arrange_array => true, :colfmt => '%02d', + # :displaywidth => 10) => + # [01, 02, + # 03, 04, + # 05, 06, + # 07, 08, + # 09, 10, + # ] + # + # Each column is only as wide as necessary. By default, columns are + # separated by two spaces. Options are available for setting + # * the line display width + # * a column separator + # * a line prefix + # * a line suffix + # * A format specify for formatting each item each array item to a string + # * whether to ignore terminal codes in text size calculation + # * whether to left justify text instead of right justify + # * whether to format as an array - with surrounding [] and + # separating ', ' + def self.columnize(*args) + list = args.shift + opts = parse_columnize_options(args) + Columnizer.new(list, opts).columnize + end + + # Adds columnize_opts to the singleton level of included class + def self.included(base) + # screw class variables, we'll use an instance variable on the class singleton + class << base + attr_accessor :columnize_opts + end + base.columnize_opts = DEFAULT_OPTS.dup + end + + def columnize(*args) + return Columnize.columnize(*args) if args.length > 1 + opts = args.empty? ? {} : args.pop + @columnize_opts ||= self.class.columnize_opts.dup + @columnizer ||= Columnizer.new(self, @columnize_opts) + # make sure that any changes to list or opts get passed to columnizer + @columnizer.list = self unless @columnizer.list == self + @columnizer.opts = @columnize_opts.merge(opts) unless @columnizer.opts == @columnize_opts and opts.empty? + @columnizer.columnize + end +end + +# Mix Columnize into Array +Array.send :include, Columnize + +# Demo this sucker +if __FILE__ == $0 + # include Columnize + + a = (1..80).to_a + puts a.columnize :arrange_array => true + puts '=' * 50 + + b = (1..10).to_a + puts b.columnize(:displaywidth => 10) + + puts '-' * 50 + puts b.columnize(:arrange_array => true, :colfmt => '%02d', :displaywidth => 10) + + [[4, 4], [4, 7], [100, 80]].each do |width, num| + data = (1..num).map{|i| i } + [[false, 'horizontal'], [true, 'vertical']].each do |bool, dir| + puts "Width: #{width}, direction: #{dir}" + print Columnize.columnize(data, :displaywidth => width, :colsep => ' ', :arrange_vertical => bool, :ljust => :auto) + end + end + + puts Columnize.columnize(5) + puts Columnize.columnize([]) + puts Columnize.columnize(["a", 2, "c"], :displaywidth =>10, :colsep => ', ') + puts Columnize.columnize(["oneitem"]) + puts Columnize.columnize(["one", "two", "three"]) + data = ["one", "two", "three", + "for", "five", "six", + "seven", "eight", "nine", + "ten", "eleven", "twelve", + "thirteen", "fourteen", "fifteen", + "sixteen", "seventeen", "eightteen", + "nineteen", "twenty", "twentyone", + "twentytwo", "twentythree", "twentyfour", + "twentyfive","twentysix", "twentyseven"] + + puts Columnize.columnize(data) + puts Columnize.columnize(data, 80, ' ', false) +end diff --git a/vendor/bundle/gems/columnize-0.8.9/lib/columnize/Makefile b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/Makefile new file mode 100644 index 0000000..aa4f784 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/Makefile @@ -0,0 +1,11 @@ +# Whatever it is you want to do, it should be handled by the main +# (parent) Makefile. So reissue make from there. +PHONY=check all + +#: Default target - the parent's testing or "check" target +all: check + true + +#: Whatever it is you want to do, it should be handled by the parent +%: + $(MAKE) -C ../.. $@ diff --git a/vendor/bundle/gems/columnize-0.8.9/lib/columnize/columnize.rb b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/columnize.rb new file mode 100644 index 0000000..fd394ea --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/columnize.rb @@ -0,0 +1,159 @@ +# Copyright (C) 2007-2011, 2013 Rocky Bernstein +# +# +# Part of Columnize to format in either direction +module Columnize + class Columnizer + ARRANGE_ARRAY_OPTS = {:array_prefix => '[', :line_prefix => ' ', :line_suffix => ',', :array_suffix => ']', :colsep => ', ', :arrange_vertical => false} + OLD_AND_NEW_KEYS = {:lineprefix => :line_prefix, :linesuffix => :line_suffix} + # TODO: change colfmt to cell_format; change colsep to something else + ATTRS = [:arrange_vertical, :array_prefix, :array_suffix, :line_prefix, :line_suffix, :colfmt, :colsep, :displaywidth, :ljust] + + attr_reader :list, :opts + + def initialize(list=[], opts={}) + self.list = list + self.opts = DEFAULT_OPTS.merge(opts) + end + + def list=(list) + @list = list + if @list.is_a? Array + @short_circuit = @list.empty? ? "\n" : nil + else + @short_circuit = '' + @list = [] + end + end + + # TODO: freeze @opts + def opts=(opts) + @opts = opts + OLD_AND_NEW_KEYS.each {|old, new| @opts[new] = @opts.delete(old) if @opts.keys.include?(old) and !@opts.keys.include?(new) } + @opts.merge!(ARRANGE_ARRAY_OPTS) if @opts[:arrange_array] + set_attrs_from_opts + end + + def update_opts(opts) + self.opts = @opts.merge(opts) + end + + def columnize + return @short_circuit if @short_circuit + + rows, colwidths = min_rows_and_colwidths + ncols = colwidths.length + justify = lambda {|t, c| + @ljust ? t.ljust(colwidths[c]) : t.rjust(colwidths[c]) + } + textify = lambda do |row| + row.map!.with_index(&justify) unless ncols == 1 && @ljust + "#{@line_prefix}#{row.join(@colsep)}#{@line_suffix}" + end + + text = rows.map(&textify) + text.first.sub!(/^#{@line_prefix}/, @array_prefix) unless @array_prefix.empty? + text.last.sub!(/#{@line_suffix}$/, @array_suffix) unless @array_suffix.empty? + text.join("\n") # + "\n" # if we want extra separation + end + + # TODO: make this a method, rather than a function (?) + # compute the smallest number of rows and the max widths for each column + def min_rows_and_colwidths + list = @list.map &@stringify + cell_widths = list.map(&@term_adjuster).map(&:size) + + # Set default arrangement: one atom per row + cell_width_max = cell_widths.max + result = [arrange_by_row(list, list.size, 1), [cell_width_max]] + + # If any atom > @displaywidth, stop and use one atom per row. + return result if cell_width_max > @displaywidth + + # For horizontal arrangement, we want to *maximize* the number + # of columns. Thus the candidate number of rows (+sizes+) starts + # at the minumum number of rows, 1, and increases. + + # For vertical arrangement, we want to *minimize* the number of + # rows. So here the candidate number of columns (+sizes+) starts + # at the maximum number of columns, list.length, and + # decreases. Also the roles of columns and rows are reversed + # from horizontal arrangement. + + # Loop from most compact arrangement to least compact, stopping + # at the first successful packing. The below code is tricky, + # but very cool. + # + # FIXME: In the below code could be DRY'd. (The duplication got + # introduced when I revised the code - rocky) + if @arrange_vertical + (1..list.length).each do |size| + other_size = (list.size + size - 1) / size + colwidths = arrange_by_row(cell_widths, other_size, size).map(&:max) + totwidth = colwidths.inject(&:+) + ((colwidths.length-1) * @colsep.length) + return [arrange_by_column(list, other_size, size), colwidths] if + totwidth <= @displaywidth + end + else + list.length.downto(1).each do |size| + other_size = (list.size + size - 1) / size + colwidths = arrange_by_column(cell_widths, other_size, size).map(&:max) + totwidth = colwidths.inject(&:+) + ((colwidths.length-1) * @colsep.length) + return [arrange_by_row(list, other_size, size), colwidths] if + totwidth <= @displaywidth + end + end + result + end + + # Given +list+, +ncols+, +nrows+, arrange the one-dimensional + # array into a 2-dimensional lists of lists organized by rows. + # + # In either horizontal or vertical arrangement, we will need to + # access this for the list data or for the width + # information. + # + # Here is an example: + # arrange_by_row((1..5).to_a, 3, 2) => + # [[1,2], [3,4], [5]], + def arrange_by_row(list, nrows, ncols) + (0...nrows).map {|r| list[r*ncols, ncols] }.compact + end + + # Given +list+, +ncols+, +nrows+, arrange the one-dimensional + # array into a 2-dimensional lists of lists organized by columns. + # + # In either horizontal or vertical arrangement, we will need to + # access this for the list data or for the width + # information. + # + # Here is an example: + # arrange_by_column((1..5).to_a, 2, 3) => + # [[1,3,5], [2,4]] + def arrange_by_column(list, nrows, ncols) + (0...ncols).map do |i| + (0..nrows-1).inject([]) do |row, j| + k = i + (j * ncols) + k < list.length ? row << list[k] : row + end + end + end + + def set_attrs_from_opts + ATTRS.each {|attr| self.instance_variable_set "@#{attr}", @opts[attr] } + + @ljust = !@list.all? {|datum| datum.kind_of?(Numeric)} if @ljust == :auto + @displaywidth -= @line_prefix.length + @displaywidth = @line_prefix.length + 4 if @displaywidth < 4 + @stringify = @colfmt ? lambda {|li| @colfmt % li } : lambda {|li| li.to_s } + @term_adjuster = @opts[:term_adjust] ? lambda {|c| c.gsub(/\e\[.*?m/, '') } : lambda {|c| c } + end + end +end + +# Demo +if __FILE__ == $0 + Columnize::DEFAULT_OPTS = {:line_prefix => '', :displaywidth => 80} + puts Columnize::Columnizer.new.arrange_by_row((1..5).to_a, 2, 3).inspect + puts Columnize::Columnizer.new.arrange_by_column((1..5).to_a, 2, 3).inspect +end diff --git a/vendor/bundle/gems/columnize-0.8.9/lib/columnize/opts.rb b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/opts.rb new file mode 100644 index 0000000..81e4c20 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/opts.rb @@ -0,0 +1,35 @@ +module Columnize + computed_displaywidth = (ENV['COLUMNS'] || '80').to_i + computed_displaywidth = 80 unless computed_displaywidth >= 10 + + # When an option is not specified for the below keys, these are the defaults. + DEFAULT_OPTS = { + :arrange_array => false, + :arrange_vertical => true, + :array_prefix => '', + :array_suffix => '', + :colfmt => nil, + :colsep => ' ', + :displaywidth => computed_displaywidth, + :line_prefix => '', + :line_suffix => '', + :ljust => :auto, + :term_adjust => false + } + + # Options parsing routine for Columnize::columnize. In the preferred + # newer style, +args+ is a hash where each key is one of the option names. + # + # In the older style positional arguments are used and the positions + # are in the order: +displaywidth+, +colsep+, +arrange_vertical+, + # +ljust+, and +line_prefix+. + def self.parse_columnize_options(args) + if 1 == args.size && args[0].kind_of?(Hash) # explicitly passed as a hash + args[0] + elsif !args.empty? # passed as ugly positional parameters. + Hash[args.zip([:displaywidth, :colsep, :arrange_vertical, :ljust, :line_prefix]).map(&:reverse)] + else + {} + end + end +end diff --git a/vendor/bundle/gems/columnize-0.8.9/lib/columnize/version.rb b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/version.rb new file mode 100644 index 0000000..598a9ad --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/version.rb @@ -0,0 +1,7 @@ +# Sets constant Columnize::VERSION, the version number of +# this package. It is used in Gem creation but can also be consulted after +# require'ing 'columnize'. +module Columnize + # The current version of this package + VERSION = '0.8.9' +end diff --git a/vendor/bundle/gems/columnize-0.8.9/test/test-columnize-array.rb b/vendor/bundle/gems/columnize-0.8.9/test/test-columnize-array.rb new file mode 100755 index 0000000..2231fba --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/test/test-columnize-array.rb @@ -0,0 +1,48 @@ +#!/usr/bin/env ruby +require 'test/unit' + +# Test of Columnize module +class TestColumnizeArray < Test::Unit::TestCase + # Ruby 1.8 form of require_relative + TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib') + ENV['COLUMNS'] = '80' + require File.join(TOP_SRC_DIR, 'columnize.rb') + + # test columnize + def test_arrange_array + data = (1..80).to_a + expect = "[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n" + + " 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n" + + " 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,\n" + + " 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80]" + assert_equal(expect, + data.columnize(:arrange_array => true, :displaywidth => 80), + "columnize_opts -> arrange_array") + end + + def test_displaywidth + expect = "1 5 9\n" + + "2 6 10\n" + + "3 7\n" + + "4 8" + data = (1..10).to_a + assert_equal(expect, data.columnize(:displaywidth => 10), "displaywidth") + end + + def test_colfmt + expect = "[01, 02,\n" + + " 03, 04,\n" + + " 05, 06,\n" + + " 07, 08,\n" + + " 09, 10]" + data = (1..10).to_a + assert_equal(expect, data.columnize(:arrange_array => true, :colfmt => '%02d', :displaywidth => 10), "arrange_array, colfmt, displaywidth") + end + + def test_backwards_compatiblity + foo = [] + data = (1..11).to_a + expect = " 1 2 3\n 4 5 6\n 7 8 9\n10 11" + assert_equal expect, foo.columnize(data, :displaywidth => 10, :arrange_vertical => false) + end +end diff --git a/vendor/bundle/gems/columnize-0.8.9/test/test-columnize.rb b/vendor/bundle/gems/columnize-0.8.9/test/test-columnize.rb new file mode 100755 index 0000000..7963b42 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/test/test-columnize.rb @@ -0,0 +1,74 @@ +#!/usr/bin/env ruby +require 'test/unit' + +# Test of Columnize module +class TestColumnize < Test::Unit::TestCase + # Ruby 1.8 form of require_relative + TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib') + require File.join(TOP_SRC_DIR, 'columnize.rb') + + # test columnize + def test_basic + assert_equal("1, 2, 3", Columnize::columnize([1, 2, 3], 10, ', ')) + assert_equal("", Columnize::columnize(5)) + assert_equal("1 3\n2 4", Columnize::columnize(['1', '2', '3', '4'], 4)) + assert_equal("1 2\n3 4", Columnize::columnize(['1', '2', '3', '4'], 4, ' ', false)) + assert_equal("\n", Columnize::columnize([])) + + assert_equal("oneitem", Columnize::columnize(["oneitem"])) + + data = (0..54).map{|i| i.to_s} + assert_equal( + "0, 6, 12, 18, 24, 30, 36, 42, 48, 54\n" + + "1, 7, 13, 19, 25, 31, 37, 43, 49\n" + + "2, 8, 14, 20, 26, 32, 38, 44, 50\n" + + "3, 9, 15, 21, 27, 33, 39, 45, 51\n" + + "4, 10, 16, 22, 28, 34, 40, 46, 52\n" + + "5, 11, 17, 23, 29, 35, 41, 47, 53", + Columnize::columnize(data, 39, ', ', true, false)) + + assert_equal( + " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n" + + "10, 11, 12, 13, 14, 15, 16, 17, 18, 19\n" + + "20, 21, 22, 23, 24, 25, 26, 27, 28, 29\n" + + "30, 31, 32, 33, 34, 35, 36, 37, 38, 39\n" + + "40, 41, 42, 43, 44, 45, 46, 47, 48, 49\n" + + "50, 51, 52, 53, 54", + Columnize::columnize(data, 39, ', ', false, false)) + + + assert_equal( + " 0, 1, 2, 3, 4, 5, 6, 7, 8\n" + + " 9, 10, 11, 12, 13, 14, 15, 16, 17\n" + + " 18, 19, 20, 21, 22, 23, 24, 25, 26\n" + + " 27, 28, 29, 30, 31, 32, 33, 34, 35\n" + + " 36, 37, 38, 39, 40, 41, 42, 43, 44\n" + + " 45, 46, 47, 48, 49, 50, 51, 52, 53\n" + + " 54", + Columnize::columnize(data, 39, ', ', false, false, ' ')) + + + data = ["one", "two", "three", + "for", "five", "six", + "seven", "eight", "nine", + "ten", "eleven", "twelve", + "thirteen", "fourteen", "fifteen", + "sixteen", "seventeen", "eightteen", + "nineteen", "twenty", "twentyone", + "twentytwo", "twentythree", "twentyfour", + "twentyfive","twentysix", "twentyseven"] + + assert_equal( +"one two three for five six \n" + +"seven eight nine ten eleven twelve \n" + +"thirteen fourteen fifteen sixteen seventeen eightteen \n" + +"nineteen twenty twentyone twentytwo twentythree twentyfour\n" + +"twentyfive twentysix twentyseven", Columnize::columnize(data, 80, ' ', false)) + + assert_equal( +"one five nine thirteen seventeen twentyone twentyfive \n" + +"two six ten fourteen eightteen twentytwo twentysix \n" + +"three seven eleven fifteen nineteen twentythree twentyseven\n" + +"for eight twelve sixteen twenty twentyfour ", Columnize::columnize(data, 80)) + end +end diff --git a/vendor/bundle/gems/columnize-0.8.9/test/test-columnizer.rb b/vendor/bundle/gems/columnize-0.8.9/test/test-columnizer.rb new file mode 100755 index 0000000..fe27f73 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/test/test-columnizer.rb @@ -0,0 +1,112 @@ +#!/usr/bin/env ruby +require 'test/unit' + +# Test of Columnizer class +class TestColumnizer < Test::Unit::TestCase + TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib') + require File.join(TOP_SRC_DIR, 'columnize.rb') + + Columnize::Columnizer.class_eval 'attr_reader :stringify, :short_circuit, :term_adjuster' + Columnize::Columnizer.class_eval 'attr_reader *ATTRS' + + # SETTING OPTS IN INITIALIZE + def test_passed_in_opts + # passed in opts should be merged with DEFAULT_OPTS + c = Columnize::Columnizer.new([], :displaywidth => 15) + assert_equal false, c.opts[:term_adjust], 'term_adjust comes from DEFAULT_OPTS' + assert_equal 15, c.opts[:displaywidth], 'displaywidth should override DEFAULT_OPTS' + end + + def test_ljust_attr + c = Columnize::Columnizer.new([1,2,3], {:ljust => :auto}) + assert_equal false, c.ljust, 'ljust: :auto should transform to false when all values are numeric' + c = Columnize::Columnizer.new(['1', 2, 3], {:ljust => :auto}) + assert_equal true, c.ljust, 'ljust: :auto should transform to true when not all values are numeric' + c = Columnize::Columnizer.new([], {:ljust => false}) + assert_equal false, c.ljust, 'ljust: false should stay false' + c = Columnize::Columnizer.new([], {:ljust => true}) + assert_equal true, c.ljust, 'ljust: true should stay true' + end + + def test_stringify_attr + c = Columnize::Columnizer.new + assert_equal '1.0', c.stringify[1.0], 'without colfmt, should be to_s' + c.update_opts :colfmt => '%02d' + assert_equal '01', c.stringify[1.0], 'without colfmt, should be to_s' + end + + def test_short_circuit_attr + c = Columnize::Columnizer.new + assert_equal "\n", c.short_circuit, 'should explicitly state when empty' + c.list = 1 + assert_equal '', c.short_circuit, 'should be an empty string when not an array' + c.list = [1] + assert_equal nil, c.short_circuit, 'should be nil when list is good' + end + + def test_term_adjuster_attr + c = Columnize::Columnizer.new + assert_equal 'abc', c.term_adjuster['abc'] + assert_equal "\e[0;31mObject\e[0;4m", c.term_adjuster["\e[0;31mObject\e[0;4m"] + c.update_opts :term_adjust => true + assert_equal 'abc', c.term_adjuster['abc'] + assert_equal 'Object', c.term_adjuster["\e[0;31mObject\e[0;4m"] + end + + def test_displaywidth_attr + c = Columnize::Columnizer.new [], :displaywidth => 10, :line_prefix => ' ' + assert_equal 12, c.displaywidth, 'displaywidth within 4 of line_prefix.length' + c.update_opts :line_prefix => ' ' + assert_equal 8, c.displaywidth, 'displaywidth not within 4 of line_prefix.length' + end + + # COLUMNIZE + def test_columnize_with_short_circuit + msg = 'Johnny 5 is alive!' + c = Columnize::Columnizer.new + c.instance_variable_set(:@short_circuit, msg) + assert_equal msg, c.columnize, 'columnize should return short_circuit message if set' + end + + def test_columnize_applies_ljust + c = Columnize::Columnizer.new [1,2,3,10,20,30], :displaywidth => 10, :ljust => false, :arrange_vertical => false + assert_equal " 1 2 3\n10 20 30", c.columnize, "ljust: #{c.ljust}" + c.update_opts :ljust => true + assert_equal "1 2 3 \n10 20 30", c.columnize, "ljust: #{c.ljust}" + end + + def no_test_columnize_applies_colsep_and_prefix_and_suffix + c = Columnize::Columnizer.new [1,2,3] + assert_equal "1 2 3", c.columnize + c.update_opts :line_prefix => '>', :colsep => '-', :line_suffix => '<' + assert_equal ">1-2-3<", c.columnize + end + + def test_columnize_applies_array_prefix_and_suffix + c = Columnize::Columnizer.new [1,2,3] + assert_equal "1 2 3", c.columnize + c.update_opts :array_prefix => '>', :array_suffix => '<' + assert_equal ">1 2 3<", c.columnize + end + + # NOTE: min_rows_and_colwidths tested in test-min_rows_and_colwidths.rb + + # arrange_rows_and_cols + def test_arrange_rows_and_cols + rows = Columnize::Columnizer.new.arrange_by_row((1..9).to_a, 3, 3) + assert_equal [[1,2,3],[4,5,6],[7,8,9]], rows, 'rows for (1..9), 3, 3' + + cols = Columnize::Columnizer.new.arrange_by_column((1..9).to_a, 3, 3) + assert_equal [[1,4,7],[2,5,8],[3,6,9]], cols, 'cols for (1..9), 3, 3' + + rows = Columnize::Columnizer.new.arrange_by_row((1..5).to_a, 3, 2) + assert_equal [[1,2],[3,4],[5]], rows, 'rows for (1..5, 2, 3)' + + cols = Columnize::Columnizer.new.arrange_by_column((1..5).to_a, 3, 2) + assert_equal [[1,3,5],[2,4]], cols, 'cols for (1..5, 2, 3)' + end + + def test_set_attrs_from_opts + assert(true, 'test set_attrs_from_opts') + end +end diff --git a/vendor/bundle/gems/columnize-0.8.9/test/test-hashparm.rb b/vendor/bundle/gems/columnize-0.8.9/test/test-hashparm.rb new file mode 100755 index 0000000..f2a8f40 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/test/test-hashparm.rb @@ -0,0 +1,43 @@ +#!/usr/bin/env ruby +require 'test/unit' + +# Test of Columnize module +class TestHashFormat < Test::Unit::TestCase + TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib') + require File.join(TOP_SRC_DIR, 'columnize.rb') + + def test_parse_columnize_options + assert Columnize.parse_columnize_options([{}]).kind_of?(Hash) + assert_equal 90, Columnize.parse_columnize_options([90])[:displaywidth] + opts = Columnize.parse_columnize_options([70, '|']) + assert_equal 70, opts[:displaywidth] + assert_equal '|', opts[:colsep] + end + + def test_new_hash + hash = {:displaywidth => 40, :colsep => ', ', :term_adjust => true,} + assert_equal(hash, Columnize.parse_columnize_options([hash]), "parse_columnize_options returns same hash it was passed") + end + + def test_array + data = (0..54).to_a + expected = "[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\n" + + " 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n" + + " 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n" + + " 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\n" + + " 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,\n" + + " 50, 51, 52, 53, 54]" + assert_equal(expected, Columnize.columnize(data, :arrange_array => true, :ljust => false, :displaywidth => 39)) + end + + def test_justify + data = (0..54).to_a + expected = "[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\n" + + " 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n" + + " 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n" + + " 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\n" + + " 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,\n" + + " 50, 51, 52, 53, 54]" + assert_equal(expected, Columnize.columnize(data, :arrange_array => true, :displaywidth => 39)) + end +end diff --git a/vendor/bundle/gems/columnize-0.8.9/test/test-issue3.rb b/vendor/bundle/gems/columnize-0.8.9/test/test-issue3.rb new file mode 100755 index 0000000..11034d5 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/test/test-issue3.rb @@ -0,0 +1,24 @@ +#!/usr/bin/env ruby +require 'test/unit' + +# Test of Columnize module for github issue #3 +class TestIssue3 < Test::Unit::TestCase + @@TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib') + require File.join(@@TOP_SRC_DIR, 'columnize.rb') + + # test columnize + def test_long_column + data = ["what's", "upppppppppppppppppp"] + data.columnize_opts = Columnize::DEFAULT_OPTS.merge :displaywidth => 7, :arrange_vertical => false + assert_equal("what's\nupppppppppppppppppp", data.columnize) + assert_equal("what's\nupppppppppppppppppp", data.columnize(:arrange_vertical => true)) + end + + def test_long_column_with_ljust + data = ["whaaaaaat's", "up"] + data.columnize_opts = Columnize::DEFAULT_OPTS.merge :displaywidth => 7, :arrange_vertical => false, :ljust => true + assert_equal("whaaaaaat's\nup", data.columnize) + assert_equal("whaaaaaat's\n up", data.columnize(:ljust => false)) + assert_equal("whaaaaaat's\nup", data.columnize(:arrange_vertical => true)) + end +end diff --git a/vendor/bundle/gems/columnize-0.8.9/test/test-min_rows_and_colwidths.rb b/vendor/bundle/gems/columnize-0.8.9/test/test-min_rows_and_colwidths.rb new file mode 100755 index 0000000..cf2b57d --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/test/test-min_rows_and_colwidths.rb @@ -0,0 +1,65 @@ +#!/usr/bin/env ruby +require 'test/unit' + +# Test of Columnize#min_rows_and_colwidths +class TestComputeRowsAndColwidths < Test::Unit::TestCase + # Ruby 1.8 form of require_relative + TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib') + require File.join(TOP_SRC_DIR, 'columnize.rb') + + VOPTS = Columnize::DEFAULT_OPTS.merge(:displaywidth => 80) + HOPTS = VOPTS.merge(:arrange_vertical => false) + + def min_rows_and_colwidths(list, opts) + Columnize::Columnizer.new(list, opts).min_rows_and_colwidths + end + + def test_colwidths + data = ["one", "two", "three", + "four", "five", "six", + "seven", "eight", "nine", + "ten", "eleven", "twelve", + "thirteen", "fourteen", "fifteen", + "sixteen", "seventeen", "eightteen", + "nineteen", "twenty", "twentyone", + "twentytwo", "twentythree", "twentyfour", + "twentyfive","twentysix", "twentyseven"] + + [['horizontal', HOPTS, [10, 9, 11, 9, 11, 10], 5, 6], + ['vertical' , VOPTS, [5, 5, 6, 8, 9, 11, 11], 4, 7]].each do + |direction, opts, expect_colwidths, expect_rows, expect_cols| + rows, colwidths = min_rows_and_colwidths(data, opts) + assert_equal(expect_colwidths, colwidths, "colwidths - #{direction}") + assert_equal(expect_rows, rows.length, + "number of rows - #{direction}") + assert_equal(expect_cols, rows.first.length, + "number of cols - #{direction}") + end + end + + def test_horizontal_vs_vertical + data = (0..54).map{|i| i.to_s} + + [['horizontal', HOPTS.merge(:displaywidth => 39), [2,2,2,2,2,2,2,2,2,2]], + ['vertical' , VOPTS.merge(:displaywidth => 39), [1,2,2,2,2,2,2,2,2,2]]].each do + |direction, opts, expect| + rows, colwidths = min_rows_and_colwidths(data, opts) + assert_equal(expect, colwidths, "colwidths #{direction}") + assert_equal(6, rows.length, "number of rows - #{direction}") + assert_equal(10, rows.first.length, "number of cols - #{direction}") + end + end + + def test_displaywidth_smaller_than_largest_atom + data = ['a' * 100, 'b', 'c', 'd', 'e'] + + [['horizontal', HOPTS], + ['vertical' , VOPTS]].each do + |direction, opts| + rows, colwidths = min_rows_and_colwidths(data, opts) + assert_equal([100], colwidths, "colwidths #{direction}") + assert_equal(5, rows.length, "number of rows - #{direction}") + assert_equal(1, rows.first.length, "number of cols - #{direction}") + end + end +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/.travis.yml b/vendor/bundle/gems/debugger-linecache-1.2.0/.travis.yml new file mode 100644 index 0000000..fa2eee6 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/.travis.yml @@ -0,0 +1,5 @@ +before_install: bundle init --gemspec=debugger-linecache.gemspec +rvm: +- 1.9.2 +- 1.9.3 +- 2.0.0 diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/CHANGELOG.md b/vendor/bundle/gems/debugger-linecache-1.2.0/CHANGELOG.md new file mode 100644 index 0000000..671b891 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/CHANGELOG.md @@ -0,0 +1,54 @@ +## 1.2.0 +* Replace C extension with ruby +* No more debugger-ruby_core_source dependency + +## 1.1.2 +* Fix rdoc/ri warning + +## 1.1.1 +* Depend on working version of debugger-ruby-core-source + +## 1.1.0 +* Point to new debugger-ruby_core_source API +* rename trace_nums19 ext to trace_nums +* Renable Rakefile and tests +* General cleanup + +## 1.0.1 +* Point to debugger-ruby_core_source as dependency + +## 1.0.0 +* Initial release - fork and release latest linecache + +## From previous gem's NEWS file + +0.5 (7/23/09) +- updated for Ruby 1.9 + +0.43 +06-12-08 +- tolerance for finding windows extension in lib rather than ext. + +0.41 +- add test/data/* to gem. + +0.4 +- Credit Ryan Davis and ParseTree. + +0.3 +- Add tracelines: get line numbers that can be stopped at. + +- Add routines to allow line-number + remapping and filename remapping. + +- Add access methods to get the number of lines in a file. + +0.2 +- Make this work with ruby-debug-base. Add reload-on-change parameters. + add checkcache, cache, cached? sha1, and stat methods. + +- Use SCRIPT_LINES__. + +0.1 + +- Initial release of LineCache, a module for reading and caching lines. diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/CONTRIBUTING.md b/vendor/bundle/gems/debugger-linecache-1.2.0/CONTRIBUTING.md new file mode 100644 index 0000000..c796c4f --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/CONTRIBUTING.md @@ -0,0 +1 @@ +Thanks for trying out this project! [See here for contribution guidelines.](http://tagaholic.me/contributing.html) diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/LICENSE.txt b/vendor/bundle/gems/debugger-linecache-1.2.0/LICENSE.txt new file mode 100644 index 0000000..b0b7edc --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/LICENSE.txt @@ -0,0 +1,22 @@ +The MIT LICENSE + +Copyright (c) 2012 Gabriel Horner + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/OLD_CHANGELOG b/vendor/bundle/gems/debugger-linecache-1.2.0/OLD_CHANGELOG new file mode 100644 index 0000000..ca74b9c --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/OLD_CHANGELOG @@ -0,0 +1,68 @@ +2009-07-23 13:15 mark-moseley + + * Updated for Ruby 1.9 + +2008-06-12 00:04 rockyb + + * .: Look in lib as well as ext for trace_nums. Win32 puts it in + lib. + +2008-04-11 02:54 rockyb + + * .: Wasn't listing extension to for C compilation? + +2008-04-10 20:02 rockyb + + * .: Forgot to add test/data to the gem. + +2008-03-09 23:24 rockyb + + * .: Deal with Depricated win32. + +2008-02-10 13:59 rockyb + + * .: Go over Rakefile and doc for 0.3 release. + +2008-01-28 15:35 rockyb + + * .: Change line number return from a Set to an Array. + +2008-01-23 16:06 rockyb + + * .: Show add_lines level, nicer formatting including \n for end. + +2008-01-20 16:31 rockyb + + * .: Add module TraceLineNumbers for extracting the stoppable lines + in a + Ruby program. + +2008-01-14 12:27 rockyb + + * .: Add parameter to getline and getlines to reload file on + change. Add + option on clear_file_cache to clear out SCRIPT_LINES__ as well. + TESTS ARE NEEDED. + Update to version 0.2. + +2007-12-10 16:24 rockyb + + * : release 0.1 + +2007-12-09 17:17 rockyb + + * : Better tests mean more bugs found. "rake" defaults now to + "test". + +2007-12-09 13:15 rockyb + + * : NEWS, README, linecache.rb: Add $Id$ line + test-linecache.rb: make executable + Rakefile: Correct documentation + +2007-12-09 12:58 rockyb + + * : Initial import of LineCache, a module for reading and caching + lines. + This time to trunk. + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/OLD_README b/vendor/bundle/gems/debugger-linecache-1.2.0/OLD_README new file mode 100644 index 0000000..2e5e180 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/OLD_README @@ -0,0 +1,50 @@ += LineCache - A module to read and cache file information of a Ruby program. + +== SYNOPSIS + +The LineCache module allows one to get any line from any file, caching +the lines and file information on first access to the file. Although +the file may be any file, the common use is when the file is a Ruby +script since parsing of the file is done to figure out where the +statement boundaries are. + +The routines here may be is useful when a small random sets of lines +are read from a single file, in particular in a debugger to show +source lines. + +== Summary + + require 'linecache' + lines = LineCache::getlines('/tmp/myruby.rb') + # The following lines have same effect as the above. + $: << '/tmp' + Dir.chdir('/tmp') {lines = LineCache::getlines('myruby.rb') + + line = LineCache::getline('/tmp/myruby.rb', 6) + # Note lines[6] == line (if /tmp/myruby.rb has 6 lines) + + LineCache::clear_file_cache + LineCache::clear_file_cache('/tmp/myruby.rb') + LineCache::update_cache # Check for modifications of all cached files. + +== Credits + + This is a port of the module of the same name from the Python distribution. + + The idea for how TraceLineNumbers works, and some code was taken + from ParseTree by Ryan Davis. + +== Other stuff + +Author:: Rocky Bernstein +License:: Copyright (c) 2007, 2008 Rocky Bernstein + Released under the GNU GPL 2 license + +== Warranty + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +$Id$ diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/README.md b/vendor/bundle/gems/debugger-linecache-1.2.0/README.md new file mode 100644 index 0000000..d133aac --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/README.md @@ -0,0 +1,20 @@ +## Description +Fork of linecache for [debugger](http://github.com/cldwalker/debugger) +For more info see OLD\_README. + +[![Build Status](https://secure.travis-ci.org/cldwalker/debugger-linecache.png?branch=master)](http://travis-ci.org/cldwalker/debugger-linecache) + +## Credits + +* Original authors: R. Bernstein, Mark Moseley +* @ko1 - replace C extension with ruby + +## TODO +* Fix todo test + +## Contributing +[See here](http://tagaholic.me/contributing.html) + +## LICENSE + +This library is licensed under LICENSE.txt. Original was GNU. diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/Rakefile b/vendor/bundle/gems/debugger-linecache-1.2.0/Rakefile new file mode 100644 index 0000000..c925c88 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/Rakefile @@ -0,0 +1,28 @@ +# -*- Ruby -*- + +require 'rubygems/package_task' +require 'rake/testtask' + +desc "Test everything." +test_task = task :test => :lib do + Rake::TestTask.new(:test) do |t| + # TODO: fix test-lnum + t.test_files = Dir['test/test-*.rb'] - ['test/test-lnum.rb'] + t.verbose = true + end +end + +desc "Test everything - same as test." +task :check => :test + +base_spec = eval(File.read('debugger-linecache.gemspec'), binding, 'debugger-linecache.gemspec') + +Gem::PackageTask.new(base_spec) do |pkg| + pkg.need_tar = true +end + +desc "Remove built files" +task :clean => [:clobber_package] do +end + +task :default => [:test] diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/debugger-linecache.gemspec b/vendor/bundle/gems/debugger-linecache-1.2.0/debugger-linecache.gemspec new file mode 100644 index 0000000..83f5942 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/debugger-linecache.gemspec @@ -0,0 +1,20 @@ +# -*- encoding: utf-8 -*- +require 'rubygems' unless defined? Gem +require File.dirname(__FILE__) + "/lib/debugger/linecache" + +Gem::Specification.new do |s| + s.name = "debugger-linecache" + s.version = Debugger::Linecache::VERSION + s.authors = ["R. Bernstein", "Mark Moseley", "Gabriel Horner"] + s.email = "gabriel.horner@gmail.com" + s.homepage = "http://github.com/cldwalker/debugger-linecache" + s.summary = %q{Read file with caching} + s.description = %q{Linecache is a module for reading and caching lines. This may be useful for +example in a debugger where the same lines are shown many times. +} + s.required_rubygems_version = ">= 1.3.6" + s.extra_rdoc_files = ["README.md"] + s.files = `git ls-files`.split("\n") + s.add_development_dependency 'rake', '~> 0.9.2.2' + s.license = "MIT" +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/lib/debugger/linecache.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/lib/debugger/linecache.rb new file mode 100644 index 0000000..d35255e --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/lib/debugger/linecache.rb @@ -0,0 +1,5 @@ +module Debugger + module Linecache + VERSION = '1.2.0' + end +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/lib/linecache19.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/lib/linecache19.rb new file mode 100755 index 0000000..41674ce --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/lib/linecache19.rb @@ -0,0 +1,407 @@ +# $Id$ +# +# Copyright (C) 2007, 2008 Rocky Bernstein +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA. +# + +# Author:: Rocky Bernstein (mailto:rockyb@rubyforge.net) +# +# = linecache +# A module to read and cache lines of a Ruby program. + +# == SYNOPSIS +# +# The LineCache module allows one to get any line from any file, +# caching lines of the file on first access to the file. Although the +# file may be any file, the common use is when the file is a Ruby +# script since parsing of the file is done to figure out where the +# statement boundaries are. +# +# The routines here may be is useful when a small random sets of lines +# are read from a single file, in particular in a debugger to show +# source lines. +# +# +# require 'linecache19' +# lines = LineCache::getlines('/tmp/myruby.rb') +# # The following lines have same effect as the above. +# $: << '/tmp' +# Dir.chdir('/tmp') {lines = LineCache::getlines('myruby.rb') +# +# line = LineCache::getline('/tmp/myruby.rb', 6) +# # Note lines[6] == line (if /tmp/myruby.rb has 6 lines) +# +# LineCache::clear_file_cache +# LineCache::clear_file_cache('/tmp/myruby.rb') +# LineCache::update_cache # Check for modifications of all cached files. +# +# Some parts of the interface is derived from the Python module of the +# same name. +# + +# Defining SCRIPT_LINES__ causes Ruby to cache the lines of files +# it reads. The key the setting of __FILE__ at the time when Ruby does +# its read. LineCache keeps a separate copy of the lines elsewhere +# and never destroys SCRIPT_LINES__ +SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__ + +require 'digest/sha1' +require 'set' + +require 'tracelines19' + +# = module LineCache +# A module to read and cache lines of a Ruby program. +module LineCache + LineCacheInfo = Struct.new(:stat, :line_numbers, :lines, :path, :sha1) unless + defined?(LineCacheInfo) + + # The file cache. The key is a name as would be given by Ruby for + # __FILE__. The value is a LineCacheInfo object. + @@file_cache = {} + + # Maps a string filename (a String) to a key in @@file_cache (a + # String). + # + # One important use of @@file2file_remap is mapping the a full path + # of a file into the name stored in @@file_cache or given by Ruby's + # __FILE__. Applications such as those that get input from users, + # may want canonicalize a file name before looking it up. This map + # gives a way to do that. + # + # Another related use is when a template system is used. Here we'll + # probably want to remap not only the file name but also line + # ranges. Will probably use this for that, but I'm not sure. + @@file2file_remap = {} + @@file2file_remap_lines = {} + + # Clear the file cache entirely. + def clear_file_cache() + @@file_cache = {} + @@file2file_remap = {} + @@file2file_remap_lines = {} + end + module_function :clear_file_cache + + # Return an array of cached file names + def cached_files() + @@file_cache.keys + end + module_function :cached_files + + # Discard cache entries that are out of date. If +filename+ is +nil+ + # all entries in the file cache +@@file_cache+ are checked. + # If we don't have stat information about a file, which can happen + # if the file was read from SCRIPT_LINES__ but no corresponding file + # is found, it will be kept. Return a list of invalidated filenames. + # nil is returned if a filename was given but not found cached. + def checkcache(filename=nil, use_script_lines=false) + + if !filename + filenames = @@file_cache.keys() + elsif @@file_cache.member?(filename) + filenames = [filename] + else + return nil + end + + result = [] + for filename in filenames + next unless @@file_cache.member?(filename) + path = @@file_cache[filename].path + if File.exist?(path) + cache_info = @@file_cache[filename].stat + stat = File.stat(path) + if stat && + (cache_info.size != stat.size or cache_info.mtime != stat.mtime) + result << filename + update_cache(filename, use_script_lines) + end + end + end + return result + end + module_function :checkcache + + # Cache filename if it's not already cached. + # Return the expanded filename for it in the cache + # or nil if we can't find the file. + def cache(filename, reload_on_change=false) + if @@file_cache.member?(filename) + checkcache(filename) if reload_on_change + else + update_cache(filename, true) + end + if @@file_cache.member?(filename) + @@file_cache[filename].path + else + nil + end + end + module_function :cache + + # Return true if filename is cached + def cached?(filename) + @@file_cache.member?(unmap_file(filename)) + end + module_function :cached? + + def cached_script?(filename) + # In 1.8.6, the SCRIPT_LINES__ filename key can be unqualified + # In 1.9.1 it's the fully qualified name + if RUBY_VERSION < "1.9" + SCRIPT_LINES__.member?(unmap_file(filename)) + else + SCRIPT_LINES__.member?(File.expand_path(unmap_file(filename))) + end + end + module_function :cached_script? + + def empty?(filename) + filename=unmap_file(filename) + @@file_cache[filename].lines.empty? + end + module_function :empty? + + # Get line +line_number+ from file named +filename+. Return nil if + # there was a problem. If a file named filename is not found, the + # function will look for it in the $: array. + # + # Examples: + # + # lines = LineCache::getline('/tmp/myfile.rb') + # # Same as above + # $: << '/tmp' + # lines = LineCache.getlines('myfile.rb') + # + def getline(filename, line_number, reload_on_change=true) + filename = unmap_file(filename) + filename, line_number = unmap_file_line(filename, line_number) + lines = getlines(filename, reload_on_change) + if lines and (1..lines.size) === line_number + return lines[line_number-1] + else + return nil + end + end + module_function :getline + + # Read lines of +filename+ and cache the results. However +filename+ was + # previously cached use the results from the cache. Return nil + # if we can't get lines + def getlines(filename, reload_on_change=false) + filename = unmap_file(filename) + checkcache(filename) if reload_on_change + if @@file_cache.member?(filename) + return @@file_cache[filename].lines + else + update_cache(filename, true) + return @@file_cache[filename].lines if @@file_cache.member?(filename) + end + end + module_function :getlines + + # Return full filename path for filename + def path(filename) + filename = unmap_file(filename) + return nil unless @@file_cache.member?(filename) + @@file_cache[filename].path + end + module_function :path + + def remap_file(from_file, to_file) + @@file2file_remap[to_file] = from_file + end + module_function :remap_file + + def remap_file_lines(from_file, to_file, range, start) + range = (range..range) if range.is_a?(Fixnum) + to_file = from_file unless to_file + if @@file2file_remap_lines[to_file] + # FIXME: need to check for overwriting ranges: whether + # they intersect or one encompasses another. + @@file2file_remap_lines[to_file] << [from_file, range, start] + else + @@file2file_remap_lines[to_file] = [[from_file, range, start]] + end + end + module_function :remap_file_lines + + # Return SHA1 of filename. + def sha1(filename) + filename = unmap_file(filename) + return nil unless @@file_cache.member?(filename) + return @@file_cache[filename].sha1.hexdigest if + @@file_cache[filename].sha1 + sha1 = Digest::SHA1.new + @@file_cache[filename].lines.each do |line| + sha1 << line + end + @@file_cache[filename].sha1 = sha1 + sha1.hexdigest + end + module_function :sha1 + + # Return the number of lines in filename + def size(filename) + filename = unmap_file(filename) + return nil unless @@file_cache.member?(filename) + @@file_cache[filename].lines.length + end + module_function :size + + # Return File.stat in the cache for filename. + def stat(filename) + return nil unless @@file_cache.member?(filename) + @@file_cache[filename].stat + end + module_function :stat + + # Return an Array of breakpoints in filename. + # The list will contain an entry for each distinct line event call + # so it is possible (and possibly useful) for a line number appear more + # than once. + def trace_line_numbers(filename, reload_on_change=false) + fullname = cache(filename, reload_on_change) + return nil unless fullname + e = @@file_cache[filename] + unless e.line_numbers + e.line_numbers = + TraceLineNumbers.lnums_for_str_array(e.lines) + e.line_numbers = false unless e.line_numbers + end + e.line_numbers + end + module_function :trace_line_numbers + + def unmap_file(file) + @@file2file_remap[file] ? @@file2file_remap[file] : file + end + module_function :unmap_file + + def unmap_file_line(file, line) + if @@file2file_remap_lines[file] + @@file2file_remap_lines[file].each do |from_file, range, start| + if range === line + from_file = from_file || file + return [from_file, start+line-range.begin] + end + end + end + return [file, line] + end + module_function :unmap_file_line + + # Update a cache entry. If something's + # wrong, return nil. Return true if the cache was updated and false + # if not. If use_script_lines is true, use that as the source for the + # lines of the file + def update_cache(filename, use_script_lines=false) + + return nil unless filename + + @@file_cache.delete(filename) + path = File.expand_path(filename) + + if use_script_lines + list = [filename] + list << @@file2file_remap[path] if @@file2file_remap[path] + list.each do |name| + if !SCRIPT_LINES__[name].nil? && SCRIPT_LINES__[name] != true + begin + stat = File.stat(name) + rescue + stat = nil + end + lines = SCRIPT_LINES__[name] + if "ruby19".respond_to?(:force_encoding) + lines.each{|l| l.force_encoding(Encoding.default_external) } + end + @@file_cache[filename] = LineCacheInfo.new(stat, nil, lines, path, nil) + @@file2file_remap[path] = filename + return true + end + end + end + + if File.exist?(path) + stat = File.stat(path) + elsif File.basename(filename) == filename + # try looking through the search path. + stat = nil + for dirname in $: + path = File.join(dirname, filename) + if File.exist?(path) + stat = File.stat(path) + break + end + end + return false unless stat + end + begin + fp = File.open(path, 'r') + lines = fp.readlines() + fp.close() + rescue + ## print '*** cannot open', path, ':', msg + return nil + end + @@file_cache[filename] = LineCacheInfo.new(File.stat(path), nil, lines, + path, nil) + @@file2file_remap[path] = filename + return true + end + + module_function :update_cache + +end + +# example usage +if __FILE__ == $0 + def yes_no(var) + return var ? "" : "not " + end + + lines = LineCache::getlines(__FILE__) + puts "#{__FILE__} has #{LineCache.size(__FILE__)} lines" + line = LineCache::getline(__FILE__, 6) + puts "The 6th line is\n#{line}" + line = LineCache::remap_file(__FILE__, 'another_name') + puts LineCache::getline('another_name', 7) + + puts("Files cached: #{LineCache::cached_files.inspect}") + LineCache::update_cache(__FILE__) + LineCache::checkcache(__FILE__) + puts "#{__FILE__} has #{LineCache::size(__FILE__)} lines" + puts "#{__FILE__} trace line numbers:\n" + + "#{LineCache::trace_line_numbers(__FILE__).to_a.sort.inspect}" + puts("#{__FILE__} is %scached." % + yes_no(LineCache::cached?(__FILE__))) + puts LineCache::stat(__FILE__).inspect + puts "Full path: #{LineCache::path(__FILE__)}" + LineCache::checkcache # Check all files in the cache + LineCache::clear_file_cache + puts("#{__FILE__} is now %scached." % + yes_no(LineCache::cached?(__FILE__))) + digest = SCRIPT_LINES__.select{|k,v| k =~ /digest.rb$/} + puts digest.first[0] if digest + line = LineCache::getline(__FILE__, 7) + puts "The 7th line is\n#{line}" + LineCache::remap_file_lines(__FILE__, 'test2', (10..20), 6) + puts LineCache::getline('test2', 10) + puts "Remapped 10th line of test2 is\n#{line}" +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/lib/tracelines19.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/lib/tracelines19.rb new file mode 100755 index 0000000..92f20c4 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/lib/tracelines19.rb @@ -0,0 +1,54 @@ +#!/usr/bin/env ruby +# $Id$ + +module TraceLineNumbers + # Return an array of lines numbers that could be + # stopped at given a file name of a Ruby program. + + def self.lnums_for_str src + name = "#{Time.new.to_i}_#{rand(2**31)}" + iseq = RubyVM::InstructionSequence.compile(src, name) + lines = {} + iseq.disasm.each_line{|line| + if /^\d+ (\w+)\s+.+\(\s*(\d+)\)$/ =~ line + insn = $1 + lineno = $2.to_i + next unless insn == 'trace' + lines[lineno] = true + # p [lineno, line] + end + } + lines.keys + end + + def lnums_for_file(file) + lnums_for_str(File.read(file)) + end + module_function :lnums_for_file + + # Return an array of lines numbers that could be + # stopped at given a file name of a Ruby program. + # We assume the each line has \n at the end. If not + # set the newline parameters to \n. + def lnums_for_str_array(string_array, newline='') + lnums_for_str(string_array.join(newline)) + end + module_function :lnums_for_str_array +end + +if __FILE__ == $0 + SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__ + # test_file = '../test/rcov-bug.rb' + test_file = '../test/lnum-data/begin1.rb' + if File.exists?(test_file) + puts TraceLineNumbers.lnums_for_file(test_file).inspect + load(test_file, 0) # for later + end + puts TraceLineNumbers.lnums_for_file(__FILE__).inspect + unless SCRIPT_LINES__.empty? + key = SCRIPT_LINES__.keys.first + puts key + puts SCRIPT_LINES__[key] + puts TraceLineNumbers.lnums_for_str_array(SCRIPT_LINES__[key]).inspect + end +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin1.rb new file mode 100644 index 0000000..94950b9 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin1.rb @@ -0,0 +1,3 @@ +# [ 2 ] +begin +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin2.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin2.rb new file mode 100644 index 0000000..d92a227 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin2.rb @@ -0,0 +1,3 @@ +# [ 2, 2 ] +begin begin end end + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin3.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin3.rb new file mode 100644 index 0000000..c1b95b6 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin3.rb @@ -0,0 +1,6 @@ +# [ 2, 3 ] +begin + begin + end +end + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block1.rb new file mode 100755 index 0000000..9435794 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block1.rb @@ -0,0 +1,7 @@ +# [2, 2, 3, 4, 6, 6] +if true + puts '3' + puts '4' +end +if true +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block2.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block2.rb new file mode 100644 index 0000000..b358763 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block2.rb @@ -0,0 +1,4 @@ +# [2, 4, 4] +def foo(&block) +end +foo{4} diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case1.rb new file mode 100644 index 0000000..ae7d167 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case1.rb @@ -0,0 +1,6 @@ +# [ 2, 3, 4 ] +case 2 +when 3 +when 4 +else +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case2.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case2.rb new file mode 100644 index 0000000..a7f42ff --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case2.rb @@ -0,0 +1,5 @@ +# [ 5, 3, 4 ] +case +when 3 != 3 +when 4 != 4 +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case3.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case3.rb new file mode 100644 index 0000000..bd43172 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case3.rb @@ -0,0 +1,5 @@ +# [2, 3, 4] +case "2" +when Array +when Fixnum +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case4.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case4.rb new file mode 100644 index 0000000..852dc9b --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case4.rb @@ -0,0 +1,4 @@ +# [2, 3, 3] +case "2" +when Array, Fixnum +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case5.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case5.rb new file mode 100644 index 0000000..8e43138 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case5.rb @@ -0,0 +1,10 @@ +# [3, 4, 5, 6, 7, 9] +# Note: lines 5 and 7 won't appear in a trace. +case '3' +when '4' + x = 5 +when '6' + x = 7 +else + x = 9 +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/class1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/class1.rb new file mode 100644 index 0000000..89075e1 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/class1.rb @@ -0,0 +1,5 @@ +# [3, 4] +class + A + class B ; + end end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/comments1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/comments1.rb new file mode 100644 index 0000000..3e28eec --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/comments1.rb @@ -0,0 +1,6 @@ +# [] + + # space here and in next line + + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/def1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/def1.rb new file mode 100644 index 0000000..88f6ea4 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/def1.rb @@ -0,0 +1,9 @@ +# [3, 4, 8] +def + a ; end +def b +end +def c( + a=7, + b=8) +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/each1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/each1.rb new file mode 100644 index 0000000..bb6b621 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/each1.rb @@ -0,0 +1,3 @@ +# [ 2 ] +[2].each { } + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/end.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/end.rb new file mode 100644 index 0000000..0562f12 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/end.rb @@ -0,0 +1,3 @@ +# [ 3 ] +# POSTEXE +END { } diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/for1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/for1.rb new file mode 100644 index 0000000..1034ae0 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/for1.rb @@ -0,0 +1,4 @@ +# [ 2, 3 ] +for i in [2] + i +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if1.rb new file mode 100644 index 0000000..bd7eaa2 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if1.rb @@ -0,0 +1,4 @@ +# [ 2, 2 ] +x = true ? 1 : 2 + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if2.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if2.rb new file mode 100644 index 0000000..af18e07 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if2.rb @@ -0,0 +1,4 @@ +# [ 2, 2 ] +x = 2 if false + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if3.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if3.rb new file mode 100644 index 0000000..fa4edf3 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if3.rb @@ -0,0 +1,9 @@ +# [ 2, 3, 4, 4, 5, 6] +lines = '' +opts = {:print_source => true} +if opts[:print_source] + puts 5 + puts lines +end + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if4.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if4.rb new file mode 100644 index 0000000..737b229 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if4.rb @@ -0,0 +1,14 @@ +# [ 6, 7, 7, 10, 8] + +# Running through Tracer will not give the line numbers in the same +# order. Also note 9 before 7. This is because in the parse tree +# != has been turned into == with the branches switched. +[true, false].each do |t| + if t != true + 8 + else + 10 + end +end + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if5.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if5.rb new file mode 100644 index 0000000..4a07391 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if5.rb @@ -0,0 +1,7 @@ +# [2, 4, 4] +x=2 +x=3 if x='a' or + false +# What's weird here is we get two stops on line 4 and both times x is +# 4. In Ruby 1.9 we don't get *any* line traces. + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if6.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if6.rb new file mode 100644 index 0000000..61fe636 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if6.rb @@ -0,0 +1,4 @@ +# [ 2, 2 ] +x = 2 if x=3 + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if7.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if7.rb new file mode 100644 index 0000000..6efb5d6 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if7.rb @@ -0,0 +1,8 @@ +# [ 2, 3, 4, 6, 6 ] +def f() + y=1 + true +end +x = 2 if f() + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match.rb new file mode 100644 index 0000000..74bab80 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match.rb @@ -0,0 +1,3 @@ +# [ 3 ] +# MATCH -- FIXME we are not getting a match token. +/.*/ diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3.rb new file mode 100644 index 0000000..ef5c049 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3.rb @@ -0,0 +1,5 @@ +# [ 5 ] +# MATCH3 +3 =~ / + x* +/ diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3a.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3a.rb new file mode 100644 index 0000000..fa124a3 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3a.rb @@ -0,0 +1,6 @@ +# [ 3, 6 ] +# MATCH3 +y = 3 +4 =~ / + #{y}* +/ diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/not-lit.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/not-lit.rb new file mode 100644 index 0000000..c5d2b30 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/not-lit.rb @@ -0,0 +1,6 @@ +# [ 4, 6 ] +# not and lit +3 +not 4 +not + 6 diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/lnum-diag.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/lnum-diag.rb new file mode 100755 index 0000000..2c63d2a --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/lnum-diag.rb @@ -0,0 +1,127 @@ +#!/usr/bin/env ruby + +TEST_DIR = File.expand_path(File.dirname(__FILE__)) +TOP_SRC_DIR = File.join(TEST_DIR, '..') +require File.join(TOP_SRC_DIR, 'lib', 'tracelines19.rb') + +def dump_file(file, opts) + puts file + begin + fp = File.open(file, 'r') + rescue Errno::ENOENT + puts "File #{file} is not readable." + return + end + lines = fp.read + if opts[:print_source] + puts '=' * 80 + puts lines + end + if opts[:print_parse] + puts '=' * 80 + cmd = "#{File.join(TEST_DIR, 'parse-show.rb')} #{file}" + system(cmd) + end + if opts[:print_trace] + require 'tracer' + puts '=' * 80 + tracer = Tracer.new + tracer.add_filter lambda {|event, f, line, id, binding, klass| + __FILE__ != f && event == 'line' + } + tracer.on{load(file)} + end + expected_lnums = nil + if opts[:expect_line] + fp.rewind + first_line = fp.readline.chomp + expected_str = first_line[1..-1] + begin + expected_lnums = eval(expected_str, binding, __FILE__, __LINE__) + rescue SyntaxError + puts '=' * 80 + puts "Failed reading expected values from #{file}" + end + end + fp.close() + got_lnums = TraceLineNumbers.lnums_for_str(lines) + if expected_lnums + puts "expecting: #{expected_lnums.inspect}" + puts '-' * 80 + if expected_lnums + if got_lnums != expected_lnums + puts "mismatch: #{got_lnums.inspect}" + else + puts 'Got what was expected.' + end + else + puts got_lnums.inspect + end + else + puts got_lnums.inspect + end +end + +require 'getoptlong' +program = File.basename($0) +opts = { + :print_source => true, # Print source file? + :print_trace => true, # Run Tracer over file? + :expect_line => true, # Source file has expected (correct) list of lines? + :print_parse => true, # Show ParseTree output? +} + +getopts = GetoptLong.new( + [ '--expect', '-e', GetoptLong::NO_ARGUMENT ], + [ '--no-expect', '-E', GetoptLong::NO_ARGUMENT ], + [ '--help', '-h', GetoptLong::NO_ARGUMENT ], + [ '--parse', '-p', GetoptLong::NO_ARGUMENT ], + [ '--no-parse', '-P', GetoptLong::NO_ARGUMENT ], + [ '--source', '-s', GetoptLong::NO_ARGUMENT ], + [ '--no-source', '-S', GetoptLong::NO_ARGUMENT ], + [ '--trace', '-t', GetoptLong::NO_ARGUMENT ], + [ '--no-trace', '-T', GetoptLong::NO_ARGUMENT ]) + +getopts.each do |opt, arg| + case opt + when '--help' + puts "usage +Usage: #{$program} [options] file1 file2 ... + +Diagnostic program to make see what TraceLineNumbers does and compare +against other output. + +options: + -e --expect Read source file expected comment (default) + -E --no-expect Don't look for source file expected comment + -p --parse Show ParseTree Output (default) + -P --no-parse Don't show ParseTree output + -s --source Show source file (default) + -S --no-source Don't print source + -t --trace Show Tracer output (default) + -T --no-trace Don't show Tracer output +" + when '--expect' + opts[:expect_line] = true + when '--no-expect' + opts[:expect_line] = false + when '--parse' + opts[:print_parse] = true + when '--no-parse' + opts[:print_parse] = false + when '--source' + opts[:print_source] = true + when '--no-source' + opts[:print_source] = false + when '--trace' + opts[:print_trace] = true + when '--no-trace' + opts[:print_trace] = false + else + puts "Unknown and ignored option #{opt}" + end +end + +ARGV.each do |file| + dump_file(file, opts) +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/parse-show.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/parse-show.rb new file mode 100755 index 0000000..4e79426 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/parse-show.rb @@ -0,0 +1,13 @@ +#!/usr/bin/env ruby + +require 'pp' +require 'parse_tree' + +ARGV.push "-" if ARGV.empty? + +parse_tree = ParseTree.new(true) + +ARGV.each do |file| + ruby = file == "-" ? $stdin.read : File.read(file) + pp parse_tree.parse_tree_for_string(ruby, file).first +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/rcov-bug.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/rcov-bug.rb new file mode 100644 index 0000000..a6e73f2 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/rcov-bug.rb @@ -0,0 +1,10 @@ +# [3, 10] +# Some rcov bugs. +z = " +Now is the time +" + +z =~ + / + 5 + /ix diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/short-file b/vendor/bundle/gems/debugger-linecache-1.2.0/test/short-file new file mode 100644 index 0000000..68cb346 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/short-file @@ -0,0 +1,2 @@ +# This is a small test file. + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-linecache.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-linecache.rb new file mode 100755 index 0000000..ad8335c --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-linecache.rb @@ -0,0 +1,148 @@ +#!/usr/bin/env ruby +require 'test/unit' +require 'fileutils' +require 'tempfile' +require 'set' + +# Test LineCache module +class TestLineCache < Test::Unit::TestCase + @@TEST_DIR = File.expand_path(File.dirname(__FILE__)) + @@TOP_SRC_DIR = File.join(@@TEST_DIR, '..', 'lib') + require File.join(@@TOP_SRC_DIR, 'linecache19.rb') + + def setup + LineCache::clear_file_cache + end + + def test_basic + fp = File.open(__FILE__, 'r') + compare_lines = fp.readlines() + fp.close + + # Test getlines to read this file. + lines = LineCache::getlines(__FILE__) + assert_equal(compare_lines, lines, + 'We should get exactly the same lines as reading this file.') + + # Test getline to read this file. The file should now be cached, + # so internally a different set of routines are used. + test_line = 1 + line = LineCache::getline(__FILE__, test_line) + assert_equal(compare_lines[test_line-1], line, + 'We should get exactly the same line as reading this file.') + + # Test getting the line via a relative file name + Dir.chdir(File.dirname(__FILE__)) do + short_file = File.basename(__FILE__) + test_line = 10 + line = LineCache::getline(short_file, test_line) + assert_equal(compare_lines[test_line-1], line, + 'Short filename lookup should work') + end + + # Write a temporary file; read contents, rewrite it and check that + # we get a change when calling getline. + tf = Tempfile.new("testing") + test_string = "Now is the time.\n" + tf.puts(test_string) + tf.close + line = LineCache::getline(tf.path, 1) + assert_equal(test_string, line, + "C'mon - a simple line test like this worked before.") + tf.open + test_string = "Now is another time.\n" + tf.puts(test_string) + tf.close + LineCache::checkcache + line = LineCache::getline(tf.path, 1) + assert_equal(test_string, line, + "checkcache should have reread the temporary file.") + FileUtils.rm tf.path + + LineCache::update_cache(__FILE__) + LineCache::clear_file_cache + end + + def test_cached + assert_equal(false, LineCache::cached?(__FILE__), + "file #{__FILE__} shouldn't be cached - just cleared cache.") + line = LineCache::getline(__FILE__, 1) + assert line + assert_equal(true, LineCache::cached?(__FILE__), + "file #{__FILE__} should now be cached") + assert_equal(false, LineCache::cached_script?('./short-file'), + "Should not find './short-file' in SCRIPT_LINES__") + assert_equal(true, 78 < LineCache.size(__FILE__)) + Dir.chdir(File.dirname(__FILE__)) do + load('./short-file', 0) + assert_equal(true, LineCache::cached_script?('./short-file'), + "Should be able to find './short-file' in SCRIPT_LINES__") + end + end + + def test_remap + LineCache::remap_file(__FILE__, 'another-name') + line1 = LineCache::getline('another-name', 1) + line2 = LineCache::getline(__FILE__, 1) + assert_equal(line1, line2, 'Both lines should be the same via remap_file') + end + + def test_remap_lines + LineCache::remap_file_lines(__FILE__, 'test2', (10..11), 6) + + line5 = LineCache::getline(__FILE__, 5) + LineCache::remap_file_lines(__FILE__, 'test2', 9, 5) + rline9 = LineCache::getline('test2', 9) + assert_equal(line5, rline9, + 'lines should be the same via remap_file_line - remap integer') + + line6 = LineCache::getline(__FILE__, 6) + rline10 = LineCache::getline('test2', 10) + assert_equal(line6, rline10, + 'lines should be the same via remap_file_line - range') + + line7 = LineCache::getline(__FILE__, 7) + rline11 = LineCache::getline('test2', 11) + assert_equal(line7, rline11, + 'lines should be the same via remap_file_line - range') + + line8 = LineCache::getline(__FILE__, 8) + LineCache::remap_file_lines(__FILE__, nil, 20, 8) + rline20 = LineCache::getline(__FILE__, 20) + assert_equal(line8, rline20, + 'lines should be the same via remap_file_line - nil file') + end + + def test_stat + assert_equal(nil, LineCache::stat(__FILE__), + "stat for #{__FILE__} shouldn't be nil - just cleared cache.") + line = LineCache::getline(__FILE__, 1) + assert line + assert(LineCache::stat(__FILE__), + "file #{__FILE__} should now have a stat") + end + + def test_path + assert_equal(nil, LineCache::path(__FILE__), + "path for #{__FILE__} should be nil - just cleared cache.") + path = LineCache::cache(__FILE__) + assert path + assert_equal(path, LineCache::path(__FILE__), + "path of #{__FILE__} should be the same as we got before") + end + + def test_trace_line_numbers + test_file = File.join(@@TEST_DIR, 'short-file') + assert_equal([], LineCache::trace_line_numbers(test_file)) + test_file = File.join(@@TEST_DIR, 'rcov-bug.rb') + assert_equal([3, 10], LineCache::trace_line_numbers(test_file)) + end + + def test_sha1 + test_file = File.join(@@TEST_DIR, 'short-file') + LineCache::cache(test_file) + assert_equal('1134f95ea84a3dcc67d7d1bf41390ee1a03af6d2', + LineCache::sha1(test_file)) + end + +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-lnum.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-lnum.rb new file mode 100755 index 0000000..c64338a --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-lnum.rb @@ -0,0 +1,33 @@ +#!/usr/bin/env ruby +# $Id$ +require 'test/unit' + +# Test TraceLineNumbers module +class TestLineNumbers2 < Test::Unit::TestCase + @@TEST_DIR = File.expand_path(File.dirname(__FILE__)) + @@TOP_SRC_DIR = File.join(@@TEST_DIR, '..') + require File.join(@@TOP_SRC_DIR, 'lib', 'tracelines19.rb') + + def test_all_lnum_data + test_dir = File.join(@@TEST_DIR, 'data') + Dir.chdir(test_dir) do + Dir.glob('*.rb').sort.each do |f| + puts f + fp = File.open(f, 'r') + lines = fp.read + fp.rewind + first_line = fp.readline.chomp + fp.close() + expected_str = first_line[1..-1] + begin + expected_lnums = eval(expected_str, binding, __FILE__, __LINE__) + rescue + assert nil, "Failed reading expected values from #{f}" + else + got_lnums = TraceLineNumbers.lnums_for_str(lines) + assert_equal(expected_lnums, got_lnums) + end + end + end + end +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-tracelines.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-tracelines.rb new file mode 100755 index 0000000..a74566c --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-tracelines.rb @@ -0,0 +1,38 @@ +#!/usr/bin/env ruby +# $Id$ +require 'test/unit' +require 'fileutils' +require 'tempfile' + +SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__ +# Test TestLineNumbers module +class TestLineNumbers1 < Test::Unit::TestCase + + @@TEST_DIR = File.expand_path(File.dirname(__FILE__)) + @@TOP_SRC_DIR = File.join(@@TEST_DIR, '..', 'lib') + require File.join(@@TOP_SRC_DIR, 'tracelines19.rb') + + @@rcov_file = File.join(@@TEST_DIR, 'rcov-bug.rb') + File.open(@@rcov_file, 'r') {|fp| + first_line = fp.readline[1..-2] + @@rcov_lnums = eval(first_line, binding, __FILE__, __LINE__) + } + + def test_for_file + rcov_lines = TraceLineNumbers.lnums_for_file(@@rcov_file) + assert_equal(@@rcov_lnums, rcov_lines) + end + + def test_for_string + string = "# Some rcov bugs.\nz = \"\nNow is the time\n\"\n\nz =~ \n /\n 5\n /ix\n" + rcov_lines = TraceLineNumbers.lnums_for_str(string) + assert_equal([2, 9], rcov_lines) + end + + def test_for_string_array + load(@@rcov_file, 0) + rcov_lines = + TraceLineNumbers.lnums_for_str_array(SCRIPT_LINES__[@@rcov_file]) + assert_equal(@@rcov_lnums, rcov_lines) + end +end diff --git a/vendor/bundle/gems/method_source-0.8.2/.gemtest b/vendor/bundle/gems/method_source-0.8.2/.gemtest new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/gems/method_source-0.8.2/.travis.yml b/vendor/bundle/gems/method_source-0.8.2/.travis.yml new file mode 100644 index 0000000..2349f06 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/.travis.yml @@ -0,0 +1,13 @@ +rvm: + - 1.8.7 + - 1.9.2 + - 1.9.3 + - ree + - rbx-18mode + - rbx-19mode + - jruby + +notifications: + irc: "irc.freenode.org#pry" + recipients: + - jrmair@gmail.com diff --git a/vendor/bundle/gems/method_source-0.8.2/.yardopts b/vendor/bundle/gems/method_source-0.8.2/.yardopts new file mode 100644 index 0000000..a4e7838 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/.yardopts @@ -0,0 +1 @@ +-m markdown diff --git a/vendor/bundle/gems/method_source-0.8.2/Gemfile b/vendor/bundle/gems/method_source-0.8.2/Gemfile new file mode 100644 index 0000000..e45e65f --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/Gemfile @@ -0,0 +1,2 @@ +source :rubygems +gemspec diff --git a/vendor/bundle/gems/method_source-0.8.2/LICENSE b/vendor/bundle/gems/method_source-0.8.2/LICENSE new file mode 100644 index 0000000..d1a50d6 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/LICENSE @@ -0,0 +1,25 @@ +License +------- + +(The MIT License) + +Copyright (c) 2011 John Mair (banisterfiend) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/gems/method_source-0.8.2/README.markdown b/vendor/bundle/gems/method_source-0.8.2/README.markdown new file mode 100644 index 0000000..d91b810 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/README.markdown @@ -0,0 +1,91 @@ +method_source +============= + +(C) John Mair (banisterfiend) 2011 + +_retrieve the sourcecode for a method_ + +*NOTE:* This simply utilizes `Method#source_location`; it + does not access the live AST. + +`method_source` is a utility to return a method's sourcecode as a +Ruby string. Also returns `Proc` and `Lambda` sourcecode. + +Method comments can also be extracted using the `comment` method. + +It is written in pure Ruby (no C). + +* Some Ruby 1.8 support now available. +* Support for MRI, RBX, JRuby, REE + +`method_source` provides the `source` and `comment` methods to the `Method` and +`UnboundMethod` and `Proc` classes. + +* Install the [gem](https://rubygems.org/gems/method_source): `gem install method_source` +* Read the [documentation](http://rdoc.info/github/banister/method_source/master/file/README.markdown) +* See the [source code](http://github.com/banister/method_source) + +Example: display method source +------------------------------ + + Set.instance_method(:merge).source.display + # => + def merge(enum) + if enum.instance_of?(self.class) + @hash.update(enum.instance_variable_get(:@hash)) + else + do_with_enum(enum) { |o| add(o) } + end + + self + end + +Example: display method comments +-------------------------------- + + Set.instance_method(:merge).comment.display + # => + # Merges the elements of the given enumerable object to the set and + # returns self. + +Limitations: +------------ + +* Occasional strange behaviour in Ruby 1.8 +* Cannot return source for C methods. +* Cannot return source for dynamically defined methods. + +Special Thanks +-------------- + +[Adam Sanderson](https://github.com/adamsanderson) for `comment` functionality. + +[Dmitry Elastic](https://github.com/dmitryelastic) for the brilliant Ruby 1.8 `source_location` hack. + +[Samuel Kadolph](https://github.com/samuelkadolph) for the JRuby 1.8 `source_location`. + +License +------- + +(The MIT License) + +Copyright (c) 2011 John Mair (banisterfiend) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/gems/method_source-0.8.2/Rakefile b/vendor/bundle/gems/method_source-0.8.2/Rakefile new file mode 100644 index 0000000..7dad800 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/Rakefile @@ -0,0 +1,79 @@ +dlext = RbConfig::CONFIG['DLEXT'] +direc = File.dirname(__FILE__) + +require 'rake/clean' +require 'rubygems/package_task' +require "#{direc}/lib/method_source/version" + +CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o") +CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o", + "ext/**/*~", "ext/**/*#*", "ext/**/*.obj", "**/*.rbc", + "ext/**/*.def", "ext/**/*.pdb", "**/*_flymake*.*", "**/*_flymake") + +def apply_spec_defaults(s) + s.name = "method_source" + s.summary = "retrieve the sourcecode for a method" + s.version = MethodSource::VERSION + s.date = Time.now.strftime '%Y-%m-%d' + s.author = "John Mair (banisterfiend)" + s.email = 'jrmair@gmail.com' + s.description = s.summary + s.require_path = 'lib' + + s.add_development_dependency("bacon","~>1.1.0") + s.add_development_dependency("rake", "~>0.9") + s.homepage = "http://banisterfiend.wordpress.com" + s.has_rdoc = 'yard' + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- test/*`.split("\n") +end + +task :test do + sh "bacon -q #{direc}/test/test.rb #{direc}/test/test_code_helpers.rb" +end + +desc "reinstall gem" +task :reinstall => :gems do + sh "gem uninstall method_source" rescue nil + sh "gem install #{direc}/pkg/method_source-#{MethodSource::VERSION}.gem" +end + +desc "Set up and run tests" +task :default => [:test] + +desc "Build the gemspec file" +task :gemspec => "ruby:gemspec" + +namespace :ruby do + spec = Gem::Specification.new do |s| + apply_spec_defaults(s) + s.platform = Gem::Platform::RUBY + end + + Gem::PackageTask.new(spec) do |pkg| + pkg.need_zip = false + pkg.need_tar = false + end + + desc "Generate gemspec file" + task :gemspec do + File.open("#{spec.name}.gemspec", "w") do |f| + f << spec.to_ruby + end + end +end + +desc "build all platform gems at once" +task :gems => [:rmgems, "ruby:gem"] + +desc "remove all platform gems" +task :rmgems => ["ruby:clobber_package"] + +desc "build and push latest gems" +task :pushgems => :gems do + chdir("#{direc}/pkg") do + Dir["*.gem"].each do |gemfile| + sh "gem push #{gemfile}" + end + end +end diff --git a/vendor/bundle/gems/method_source-0.8.2/lib/method_source.rb b/vendor/bundle/gems/method_source-0.8.2/lib/method_source.rb new file mode 100644 index 0000000..7d16c3b --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/lib/method_source.rb @@ -0,0 +1,141 @@ +# (C) John Mair (banisterfiend) 2011 +# MIT License + +direc = File.dirname(__FILE__) + +require "#{direc}/method_source/version" +require "#{direc}/method_source/source_location" +require "#{direc}/method_source/code_helpers" + +module MethodSource + extend MethodSource::CodeHelpers + + # An Exception to mark errors that were raised trying to find the source from + # a given source_location. + # + class SourceNotFoundError < StandardError; end + + # Helper method responsible for extracting method body. + # Defined here to avoid polluting `Method` class. + # @param [Array] source_location The array returned by Method#source_location + # @param [String] method_name + # @return [String] The method body + def self.source_helper(source_location, name=nil) + raise SourceNotFoundError, "Could not locate source for #{name}!" unless source_location + file, line = *source_location + + expression_at(lines_for(file), line) + rescue SyntaxError => e + raise SourceNotFoundError, "Could not parse source for #{name}: #{e.message}" + end + + # Helper method responsible for opening source file and buffering up + # the comments for a specified method. Defined here to avoid polluting + # `Method` class. + # @param [Array] source_location The array returned by Method#source_location + # @param [String] method_name + # @return [String] The comments up to the point of the method. + def self.comment_helper(source_location, name=nil) + raise SourceNotFoundError, "Could not locate source for #{name}!" unless source_location + file, line = *source_location + + comment_describing(lines_for(file), line) + end + + # Load a memoized copy of the lines in a file. + # + # @param [String] file_name + # @param [String] method_name + # @return [Array] the contents of the file + # @raise [SourceNotFoundError] + def self.lines_for(file_name, name=nil) + @lines_for_file ||= {} + @lines_for_file[file_name] ||= File.readlines(file_name) + rescue Errno::ENOENT => e + raise SourceNotFoundError, "Could not load source for #{name}: #{e.message}" + end + + # @deprecated — use MethodSource::CodeHelpers#complete_expression? + def self.valid_expression?(str) + complete_expression?(str) + rescue SyntaxError + false + end + + # @deprecated — use MethodSource::CodeHelpers#expression_at + def self.extract_code(source_location) + source_helper(source_location) + end + + # This module is to be included by `Method` and `UnboundMethod` and + # provides the `#source` functionality + module MethodExtensions + + # We use the included hook to patch Method#source on rubinius. + # We need to use the included hook as Rubinius defines a `source` + # on Method so including a module will have no effect (as it's + # higher up the MRO). + # @param [Class] klass The class that includes the module. + def self.included(klass) + if klass.method_defined?(:source) && Object.const_defined?(:RUBY_ENGINE) && + RUBY_ENGINE =~ /rbx/ + + klass.class_eval do + orig_source = instance_method(:source) + + define_method(:source) do + begin + super + rescue + orig_source.bind(self).call + end + end + + end + end + end + + # Return the sourcecode for the method as a string + # @return [String] The method sourcecode as a string + # @raise SourceNotFoundException + # + # @example + # Set.instance_method(:clear).source.display + # => + # def clear + # @hash.clear + # self + # end + def source + MethodSource.source_helper(source_location, defined?(name) ? name : inspect) + end + + # Return the comments associated with the method as a string. + # @return [String] The method's comments as a string + # @raise SourceNotFoundException + # + # @example + # Set.instance_method(:clear).comment.display + # => + # # Removes all elements and returns self. + def comment + MethodSource.comment_helper(source_location, defined?(name) ? name : inspect) + end + end +end + +class Method + include MethodSource::SourceLocation::MethodExtensions + include MethodSource::MethodExtensions +end + +class UnboundMethod + include MethodSource::SourceLocation::UnboundMethodExtensions + include MethodSource::MethodExtensions +end + +class Proc + include MethodSource::SourceLocation::ProcExtensions + include MethodSource::MethodExtensions +end + diff --git a/vendor/bundle/gems/method_source-0.8.2/lib/method_source/code_helpers.rb b/vendor/bundle/gems/method_source-0.8.2/lib/method_source/code_helpers.rb new file mode 100644 index 0000000..6c1d53e --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/lib/method_source/code_helpers.rb @@ -0,0 +1,154 @@ +module MethodSource + + module CodeHelpers + # Retrieve the first expression starting on the given line of the given file. + # + # This is useful to get module or method source code. + # + # @param [Array, File, String] file The file to parse, either as a File or as + # @param [Fixnum] line_number The line number at which to look. + # NOTE: The first line in a file is + # line 1! + # @param [Hash] options The optional configuration parameters. + # @option options [Boolean] :strict If set to true, then only completely + # valid expressions are returned. Otherwise heuristics are used to extract + # expressions that may have been valid inside an eval. + # @option options [Fixnum] :consume A number of lines to automatically + # consume (add to the expression buffer) without checking for validity. + # @return [String] The first complete expression + # @raise [SyntaxError] If the first complete expression can't be identified + def expression_at(file, line_number, options={}) + options = { + :strict => false, + :consume => 0 + }.merge!(options) + + lines = file.is_a?(Array) ? file : file.each_line.to_a + + relevant_lines = lines[(line_number - 1)..-1] || [] + + extract_first_expression(relevant_lines, options[:consume]) + rescue SyntaxError => e + raise if options[:strict] + + begin + extract_first_expression(relevant_lines) do |code| + code.gsub(/\#\{.*?\}/, "temp") + end + rescue SyntaxError + raise e + end + end + + # Retrieve the comment describing the expression on the given line of the given file. + # + # This is useful to get module or method documentation. + # + # @param [Array, File, String] file The file to parse, either as a File or as + # a String or an Array of lines. + # @param [Fixnum] line_number The line number at which to look. + # NOTE: The first line in a file is line 1! + # @return [String] The comment + def comment_describing(file, line_number) + lines = file.is_a?(Array) ? file : file.each_line.to_a + + extract_last_comment(lines[0..(line_number - 2)]) + end + + # Determine if a string of code is a complete Ruby expression. + # @param [String] code The code to validate. + # @return [Boolean] Whether or not the code is a complete Ruby expression. + # @raise [SyntaxError] Any SyntaxError that does not represent incompleteness. + # @example + # complete_expression?("class Hello") #=> false + # complete_expression?("class Hello; end") #=> true + # complete_expression?("class 123") #=> SyntaxError: unexpected tINTEGER + def complete_expression?(str) + old_verbose = $VERBOSE + $VERBOSE = nil + + catch(:valid) do + eval("BEGIN{throw :valid}\n#{str}") + end + + # Assert that a line which ends with a , or \ is incomplete. + str !~ /[,\\]\s*\z/ + rescue IncompleteExpression + false + ensure + $VERBOSE = old_verbose + end + + private + + # Get the first expression from the input. + # + # @param [Array] lines + # @param [Fixnum] consume A number of lines to automatically + # consume (add to the expression buffer) without checking for validity. + # @yield a clean-up function to run before checking for complete_expression + # @return [String] a valid ruby expression + # @raise [SyntaxError] + def extract_first_expression(lines, consume=0, &block) + code = consume.zero? ? "" : lines.slice!(0..(consume - 1)).join + + lines.each do |v| + code << v + return code if complete_expression?(block ? block.call(code) : code) + end + raise SyntaxError, "unexpected $end" + end + + # Get the last comment from the input. + # + # @param [Array] lines + # @return [String] + def extract_last_comment(lines) + buffer = "" + + lines.each do |line| + # Add any line that is a valid ruby comment, + # but clear as soon as we hit a non comment line. + if (line =~ /^\s*#/) || (line =~ /^\s*$/) + buffer << line.lstrip + else + buffer.replace("") + end + end + + buffer + end + + # An exception matcher that matches only subsets of SyntaxErrors that can be + # fixed by adding more input to the buffer. + module IncompleteExpression + GENERIC_REGEXPS = [ + /unexpected (\$end|end-of-file|end-of-input|END_OF_FILE)/, # mri, jruby, ruby-2.0, ironruby + /embedded document meets end of file/, # =begin + /unterminated (quoted string|string|regexp) meets end of file/, # "quoted string" is ironruby + /can't find string ".*" anywhere before EOF/, # rbx and jruby + /missing 'end' for/, /expecting kWHEN/ # rbx + ] + + RBX_ONLY_REGEXPS = [ + /expecting '[})\]]'(?:$|:)/, /expecting keyword_end/ + ] + + def self.===(ex) + return false unless SyntaxError === ex + case ex.message + when *GENERIC_REGEXPS + true + when *RBX_ONLY_REGEXPS + rbx? + else + false + end + end + + def self.rbx? + RbConfig::CONFIG['ruby_install_name'] == 'rbx' + end + end + end +end diff --git a/vendor/bundle/gems/method_source-0.8.2/lib/method_source/source_location.rb b/vendor/bundle/gems/method_source-0.8.2/lib/method_source/source_location.rb new file mode 100644 index 0000000..1e2a22a --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/lib/method_source/source_location.rb @@ -0,0 +1,138 @@ +module MethodSource + module ReeSourceLocation + # Ruby enterprise edition provides all the information that's + # needed, in a slightly different way. + def source_location + [__file__, __line__] rescue nil + end + end + + module SourceLocation + module MethodExtensions + if Proc.method_defined? :__file__ + include ReeSourceLocation + + elsif defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/ + require 'java' + + # JRuby version source_location hack + # @return [Array] A two element array containing the source location of the method + def source_location + to_java.source_location(Thread.current.to_java.getContext()) + end + else + + + def trace_func(event, file, line, id, binding, classname) + return unless event == 'call' + set_trace_func nil + + @file, @line = file, line + raise :found + end + + private :trace_func + + # Return the source location of a method for Ruby 1.8. + # @return [Array] A two element array. First element is the + # file, second element is the line in the file where the + # method definition is found. + def source_location + if @file.nil? + args =[*(1..(arity<-1 ? -arity-1 : arity ))] + + set_trace_func method(:trace_func).to_proc + call(*args) rescue nil + set_trace_func nil + @file = File.expand_path(@file) if @file && File.exist?(File.expand_path(@file)) + end + [@file, @line] if @file + end + end + end + + module ProcExtensions + if Proc.method_defined? :__file__ + include ReeSourceLocation + + elsif defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /rbx/ + + # Return the source location for a Proc (Rubinius only) + # @return [Array] A two element array. First element is the + # file, second element is the line in the file where the + # proc definition is found. + def source_location + [block.file.to_s, block.line] + end + else + + # Return the source location for a Proc (in implementations + # without Proc#source_location) + # @return [Array] A two element array. First element is the + # file, second element is the line in the file where the + # proc definition is found. + def source_location + self.to_s =~ /@(.*):(\d+)/ + [$1, $2.to_i] + end + end + end + + module UnboundMethodExtensions + if Proc.method_defined? :__file__ + include ReeSourceLocation + + elsif defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/ + require 'java' + + # JRuby version source_location hack + # @return [Array] A two element array containing the source location of the method + def source_location + to_java.source_location(Thread.current.to_java.getContext()) + end + + else + + + # Return the source location of an instance method for Ruby 1.8. + # @return [Array] A two element array. First element is the + # file, second element is the line in the file where the + # method definition is found. + def source_location + klass = case owner + when Class + owner + when Module + method_owner = owner + Class.new { include(method_owner) } + end + + # deal with immediate values + case + when klass == Symbol + return :a.method(name).source_location + when klass == Fixnum + return 0.method(name).source_location + when klass == TrueClass + return true.method(name).source_location + when klass == FalseClass + return false.method(name).source_location + when klass == NilClass + return nil.method(name).source_location + end + + begin + Object.instance_method(:method).bind(klass.allocate).call(name).source_location + rescue TypeError + + # Assume we are dealing with a Singleton Class: + # 1. Get the instance object + # 2. Forward the source_location lookup to the instance + instance ||= ObjectSpace.each_object(owner).first + Object.instance_method(:method).bind(instance).call(name).source_location + end + end + end + end + end +end diff --git a/vendor/bundle/gems/method_source-0.8.2/lib/method_source/version.rb b/vendor/bundle/gems/method_source-0.8.2/lib/method_source/version.rb new file mode 100644 index 0000000..7a91c7d --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/lib/method_source/version.rb @@ -0,0 +1,3 @@ +module MethodSource + VERSION = "0.8.2" +end diff --git a/vendor/bundle/gems/method_source-0.8.2/method_source.gemspec b/vendor/bundle/gems/method_source-0.8.2/method_source.gemspec new file mode 100644 index 0000000..d24b3d9 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/method_source.gemspec @@ -0,0 +1,33 @@ +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = "method_source" + s.version = "0.8.1" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["John Mair (banisterfiend)"] + s.date = "2012-10-17" + s.description = "retrieve the sourcecode for a method" + s.email = "jrmair@gmail.com" + s.files = [".gemtest", ".travis.yml", ".yardopts", "Gemfile", "LICENSE", "README.markdown", "Rakefile", "lib/method_source.rb", "lib/method_source/code_helpers.rb", "lib/method_source/source_location.rb", "lib/method_source/version.rb", "method_source.gemspec", "test/test.rb", "test/test_code_helpers.rb", "test/test_helper.rb"] + s.homepage = "http://banisterfiend.wordpress.com" + s.require_paths = ["lib"] + s.rubygems_version = "1.8.23" + s.summary = "retrieve the sourcecode for a method" + s.test_files = ["test/test.rb", "test/test_code_helpers.rb", "test/test_helper.rb"] + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, ["~> 1.1.0"]) + s.add_development_dependency(%q, ["~> 0.9"]) + else + s.add_dependency(%q, ["~> 1.1.0"]) + s.add_dependency(%q, ["~> 0.9"]) + end + else + s.add_dependency(%q, ["~> 1.1.0"]) + s.add_dependency(%q, ["~> 0.9"]) + end +end diff --git a/vendor/bundle/gems/method_source-0.8.2/test/test.rb b/vendor/bundle/gems/method_source-0.8.2/test/test.rb new file mode 100644 index 0000000..4743a50 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/test/test.rb @@ -0,0 +1,138 @@ +direc = File.expand_path(File.dirname(__FILE__)) + +require 'rubygems' +require 'bacon' +require "#{direc}/../lib/method_source" +require "#{direc}/test_helper" + +describe MethodSource do + + describe "source_location (testing 1.8 implementation)" do + it 'should return correct source_location for a method' do + method(:hello).source_location.first.should =~ /test_helper/ + end + + it 'should not raise for immediate instance methods' do + [Symbol, Fixnum, TrueClass, FalseClass, NilClass].each do |immediate_class| + lambda { immediate_class.instance_method(:to_s).source_location }.should.not.raise + end + end + + it 'should not raise for immediate methods' do + [:a, 1, true, false, nil].each do |immediate| + lambda { immediate.method(:to_s).source_location }.should.not.raise + end + end + end + + before do + @hello_module_source = " def hello; :hello_module; end\n" + @hello_singleton_source = "def $o.hello; :hello_singleton; end\n" + @hello_source = "def hello; :hello; end\n" + @hello_comment = "# A comment for hello\n# It spans two lines and is indented by 2 spaces\n" + @lambda_comment = "# This is a comment for MyLambda\n" + @lambda_source = "MyLambda = lambda { :lambda }\n" + @proc_source = "MyProc = Proc.new { :proc }\n" + @hello_instance_evaled_source = " def hello_\#{name}(*args)\n send_mesg(:\#{name}, *args)\n end\n" + @hello_instance_evaled_source_2 = " def \#{name}_two()\n if 44\n 45\n end\n end\n" + @hello_class_evaled_source = " def hello_\#{name}(*args)\n send_mesg(:\#{name}, *args)\n end\n" + @hi_module_evaled_source = " def hi_\#{name}\n @var = \#{name}\n end\n" + end + + it 'should define methods on Method and UnboundMethod and Proc' do + Method.method_defined?(:source).should == true + UnboundMethod.method_defined?(:source).should == true + Proc.method_defined?(:source).should == true + end + + describe "Methods" do + it 'should return source for method' do + method(:hello).source.should == @hello_source + end + + it 'should return source for a method defined in a module' do + M.instance_method(:hello).source.should == @hello_module_source + end + + it 'should return source for a singleton method as an instance method' do + class << $o; self; end.instance_method(:hello).source.should == @hello_singleton_source + end + + it 'should return source for a singleton method' do + $o.method(:hello).source.should == @hello_singleton_source + end + + it 'should return a comment for method' do + method(:hello).comment.should == @hello_comment + end + + # These tests fail because of http://jira.codehaus.org/browse/JRUBY-4576 + unless defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby" + it 'should return source for an *_evaled method' do + M.method(:hello_name).source.should == @hello_instance_evaled_source + M.method(:name_two).source.should == @hello_instance_evaled_source_2 + M.instance_method(:hello_name).source.should == @hello_class_evaled_source + M.instance_method(:hi_name).source.should == @hi_module_evaled_source + end + end + + it "should raise error for evaled methods that do not pass __FILE__ and __LINE__ + 1 as its arguments" do + lambda { M.instance_method(:name_three).source }.should.raise MethodSource::SourceNotFoundError + end + + if !is_rbx? + it 'should raise for C methods' do + lambda { method(:puts).source }.should.raise MethodSource::SourceNotFoundError + end + end + end + + # if RUBY_VERSION =~ /1.9/ || is_rbx? + describe "Lambdas and Procs" do + it 'should return source for proc' do + MyProc.source.should == @proc_source + end + + it 'should return an empty string if there is no comment' do + MyProc.comment.should == '' + end + + it 'should return source for lambda' do + MyLambda.source.should == @lambda_source + end + + it 'should return comment for lambda' do + MyLambda.comment.should == @lambda_comment + end + end + # end + describe "Comment tests" do + before do + @comment1 = "# a\n# b\n" + @comment2 = "# a\n# b\n" + @comment3 = "# a\n#\n# b\n" + @comment4 = "# a\n# b\n" + @comment5 = "# a\n# b\n# c\n# d\n" + end + + it "should correctly extract multi-line comments" do + method(:comment_test1).comment.should == @comment1 + end + + it "should correctly strip leading whitespace before comments" do + method(:comment_test2).comment.should == @comment2 + end + + it "should keep empty comment lines" do + method(:comment_test3).comment.should == @comment3 + end + + it "should ignore blank lines between comments" do + method(:comment_test4).comment.should == @comment4 + end + + it "should align all comments to same indent level" do + method(:comment_test5).comment.should == @comment5 + end + end +end diff --git a/vendor/bundle/gems/method_source-0.8.2/test/test_code_helpers.rb b/vendor/bundle/gems/method_source-0.8.2/test/test_code_helpers.rb new file mode 100644 index 0000000..ba83a63 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/test/test_code_helpers.rb @@ -0,0 +1,41 @@ +describe MethodSource::CodeHelpers do + before do + @tester = Object.new.extend(MethodSource::CodeHelpers) + end + + [ + ["p = '", "'"], + ["def", "a", "(); end"], + ["p = < 1.1.0` +* Remove deprecated hooks API ([#1209](https://github.com/pry/pry/pull/1209)) +* Add 64-bit windows support. + +#### Bug fixes, etc. +* The `gem-install` command can require gems like `net-ssh` thanks to better + logic for guessing what path to require. (#1188) +* `toggle-color` command toggles the local `_pry_.color` setting instead of the + global `Pry.color`. +* Update `Pry::CLIPPED_PRINT` to include a hex representation of object ID when + printing a return value. (#1162) +* Wrap exceptions in a proxy instead of adding singleton methods. (#1145) + * `Pry#last_exception=` now supports exception objects that have been frozen. +* `binding.pry` inside `.pryrc` file now works, with some limitations (@richo / #1118) +* Add support for BasicObjects to `ls` (#984) +* Allow `ls -c ` (#891) +* Fix indentation not working if the `mathn` stdlib was loaded (#872) +* Fix `hist`'s `--exclude-pry` switch (#874) +* Fix `gem-install` on JRuby (#870) +* Fix source lookup for instrumented classes (#923) +* Improved thread safety when multiple instances are running (#944) +* Make `edit` ignore `-n`/`--no-reload` flag and `disable_auto_reload` config + in cases where the user was editing a tempfile +* Make `gem-cd` use the most recent gem, not the oldest +* Make `install-command` honor `.gemrc` switches (#666) +* Make `hist` with no parameters show just the current session's history (#205) + * `hist --all` shows older history +* Make `-s`/`--super` flag of `show-source`/`show-doc` work when method name is + being inferred from context (#877) +* Rename `--installed-plugins` flag to `--plugins` +* Strip ANSI codes from prompt before measuring length for indentation (#493) +* Fix bug in `edit` regarding recognition of file names without suffix. +* Reduced download size by removing tests etc. from distributed gem. + +#### Dev-facing changes +* `CommandSet#commands`, sometimes referenced through `Pry.commands.commands`, + renamed to `CommandSet#to_hash`. It returns a duplicate of the internal hash + a CommandSet uses. +* `CommandSet#keys` is now an alias of `CommandSet#list_commands`. +* All commands should now reference configuration values via `_pry_.config` + (local) and not `Pry.config` (global). (#1096) + * This change improves support for concurrent environments and + context-specific Pry sessions. `_pry_.config` inherits default values from + `Pry.config` but can override them locally. +* `rake pry` now accepts switches prefixed with `_` (e.g., `rake pry _v`) +* Pagers now act like `IO`s and accept streaming output + * See `_pry_.pager.page` and `_pry_.pager.open`. +* The `Pry` class has been broken up into two smaller classes. + * `Pry` represents non-UI-specific session state, including the eval string + * `Pry::REPL` controls the user-facing interface + * This should make it easier to drive Pry from alternative interfaces + * `Pry.start` now has a `:driver` option that defaults to `Pry::REPL` + * This involved a lot of refactoring and may break plugins that depend on + the old layout +* Add `ColorPrinter` subclass of `PP` for colorized object inspection +* Add `[]` and `[]=` methods to `CommandSet`, which find and replace commands + * Example: `Pry.commands["help"] = MyHelpCommand` +* The completion API has been refactored (see fdb703a8de4ef3) +* `Pry.config.input_stack` (and the input stack concept in general) no longer + exists +* There's a new `Pry::Terminal` class that implements a number of different + methods of determining the terminal's dimensions +* Add `ReplTester` class for high-level simulation of Pry sessions in tests +* Add `Pry.main`. Returns the special instance of Object referenced by self of + `TOPLEVEL_BINDING`: "main". +* Changed second argument of `Pry.view_clip()` from Fixnum to Hash to support + returning a string with or without a hex representation of object ID. (#1162) +* The `output` and `pager` objects will now strip color-codes, so commands should + always print in color. +* Commands now have a `state` hash that is persistent across invocations of the command + in the same pry session. + +### 0.9.12.6 (2014/01/28) +* Don't fail if Bond is not installed (#1106) + +### 0.9.12.5 (2014/01/27) +* Fix early readline errors by deferring require of readline (#1081, #1095) + +### 0.9.12.4 (2013/11/23) +* Fix issue with Coderay colors being black, even when on a black background (#1016) + +### 0.9.12.3 (2013/09/11) +* Bump Coderay dependency (#987) +* Fix consecutive newlines in heredocs being collapsed (#962) +* Fix pager not working in JRuby > 1.7.5 (#992) + +### 0.9.12.2 (2013/05/10) +* Make `reload-code` with no args reload "current" file (#920) + +### 0.9.12.1 (2013/04/21) +* Add workaround for JRuby crashing bug (#890) + * Related to http://jira.codehaus.org/browse/JRUBY-7114 + +### 0.9.12 (2013/02/12) +#### Features +* `pry --gem` (see 19bfc13aa) +* `show-source` now works on commands created with `create_command` +* `whereami` now has `-m` (method), `-c` (class), and `-f` (file) options +* `show-source` now falls back to superclass (and displays warning) if it + can't find class code +* `show-source`/`show-doc` now indicate when `-a` option is available + +#### Bug fixes, etc. +* Fix commands breaking due to Slop looking at `ARGV` instead of command + parameters (#828) +* Fix pager breaking in some situations (#845) +* Fix broken rendering of some docs (#795) +* Silence warnings during failed tab-completion attempts +* Fix broken prompt when prompt is colored (#822 / #823) +* Added `reload-method` as alias for `reload-code` (for backwards + compatibility) +* Reopen `Readline.output` if it is not a tty (see 1538bc0990) + +### 0.9.11.4 (2013/01/20) +* Fix pager not rendering color codes in some circumstances +* Add `Pry.last_internal_error`, useful for devs debugging commands + +### 0.9.11.3 (2013/01/17) +* Fix `Pry.run_command` +* Improve `ls` output +* Add `:requires_gem => "jist"` to `gist` command (so dependencies can be + installed via `install-command`) +* Improve help for `edit` command + +### 0.9.11.2 (2013/01/16) +* Fix minor bug in `gist` on Windows: rescue `Jist::ClipboardError` rather + than letting the scary error spill out to users and potentially having them + think the gist didn't post. + +### 0.9.11.1 (2013/01/16) +* Fix minor bug in `gist` command where I neglected to remove + a call to a non-existent method (`no_arg`) which was called when + `gist` is invoked with no parameters + +### 0.9.11 (2013/01/16) +#### Dependency changes +* Upgrade `slop` to `~> 3.4` +* New optional dependency: `bond` + * You'll need to perform `gem install bond` + * It improves autocompletion if you use Readline + * Does not work for libedit + (More info: https://github.com/pry/pry/wiki/FAQ#wiki-readline) + * Big thanks to cldwalker + +#### Features +* Basic Ruby 2.0 support (#738) +* JRuby 1.7.0+ support (#732) +* New `reload-code` command + * Reload code for methods, classes, commands, objects and so on + * Examples: `reload-code MyClass`, `reload-code my_method`, + `reload-code my_obj` +* Bond tab completion (see "Dependency changes") +* Consolidate "show" commands into `show-source` + * `show-source` can now extract source for: + * Classes + * Methods + * Procs + * Pry commands + * Arbitrary objects (it shows the source for the class of the object) + * As a result, `show-command` is now removed +* `gist`, `play`, and `save-file` now infer object type without requiring flags + * Examples: `play MyClass`, `play my_file.rb`, `play my_method` +* Consolidate editing commands into `edit` + * `edit` can now edit: + * Files + * Methods + * Classes + * Pry commands + * As a result, `edit-method` is now removed + * Examples: `edit MyClass`, `edit my_file.rb`, `edit my_method` +* `amend-line` and `play` now properly indent code added to input buffer +* Support for multiple require switches (`pry -rubygems -r./a.rb`) (#674) +* Support for multiple exec switches (`pry -e ':one' -e ':two'`) +* Ability to customize the name displayed in the prompt (#695) +* `--patch` switch for `edit --ex` command (#716) +* Respect the `$PAGER` environment variable (#736) +* `disable-pry` command (#497) +* Two new hooks, `before_eval` and `after_eval` +* Tab completion for `Array#` in `show-source` and `show-doc` +* `gem-install` immediately requires gems +* `-l` switch for `ls` command (displays local variables) +* `gem-open` command +* `fix-indent` command +* Subcommands API +* Public test API for plugin writers (see d1489a) +* Tabular `ls` output +* `--no-line-numbers` switch for `whereami` command +* `--lines` switch for `play` command + +#### Bug fixes, etc. +* Use single escape instead of double in `find-method` (#652) +* Fix blank string delimiters (#657) +* Fix unwanted `binding_impl_method` local in scratch bindings (#622) +* Fix `edit-method -p` changing constant lookup (#645) +* Fix `.pryrc` loading twice when invoked from `$HOME` directory (#682) +* Fix Pry not remembering initial `pwd` (#675) +* Fix multiline object coloring (#717) +* Fix `show-method` not supporting `String::new` notation (#719) +* Fix `whereami` command not showing correct line numbers (#754) +* Fix buggy Cucumber AST output (#751) +* Fix `while/until do` loops indentation (#787) +* Fix `--no-plugins` switch (#526) +* Ensure all errors go to the error handler (#774) +* Fix `.pryrc` loading with wrong `__FILE__` +* Fix pager not working if `less` is not available +* Fix `^D` in nested REPL +* Many small improvements to error message clarity and documentation formatting + +### 0.9.10 (2012/07/04) +#### Dependency changes +* Upgrade `slop` to version 3 (#561) +* Switch from `gist` gem to `jist` (#590) +* Upgrade `method_source` to 0.8 + +#### Features +* Add `--hist`, `-o` and `-k` flags to `gist` command (#572) +* Support `show-source`/`show-doc` on methods defined in `class_eval` (#584) +* Support `show-source`/`show-doc` on gem methods defined in C (#585) +* Add `--disable-plugin` and `--select-plugin` options (#596) +* Allow `cd -` to switch between bindings (#597) +* Add `Pry.config.should_load_local_rc` to turn off `./.pryrc` (#612) +* Allow running a file of Pry input with `pry ` +* Support colours in `ri` command +* Add `before_eval` hook +* The prompt proc now gets a lot more data when its arity is 1 + +#### Bug fixes, etc. +* Removed the `req` command (#554) +* Fix rendering bugs when starting Pry (#567) +* Fix `Array#pretty_print` on Jruby (#568) +* Fix `edit` on Windows (#575) +* Fix `find-method` in the presence of badly behaved objects (#576) +* Fix `whereami` in ERb files on Rails (#580) +* Raise fewer exceptions while tab completing (#632) +* Don't immediately quit Pry when an error happens in Readline (#605) +* Support for `ansicon` to give JRuby Windows users colour (#606) +* Massive speed improvements to `show-source` for modules (#613) +* Improve `whereami` command when not in a `binding.pry` (#620) +* Support embedded documents (`=begin` ... `=end`) (#622) +* Support editing files with spaces in the name (#627) +* Renamed `__binding_impl__` to `__pry__` +* Support for absolute paths in `$EDITOR` +* Fix `cat` command on files with unknown extensions +* Many, many internal refactorings and tidyings + +### 0.9.9.6 (2012/05/09) +* Fix `ZeroDivisionError` in `correct_indentation` (#558) + +### 0.9.9.5 (2012/05/09) +* Fix `ZeroDivisionError` in `correct_indentation` (#558) +* Fix double highlighting in RDoc (#562) +* Automatically create configuration for plugins (#548) + +### 0.9.9.4 (2012/04/26) +* Fix `NoMethodError: undefined method `winsize' for #>` (#549) +* Fixes for JRuby +* Fix syntax error on `exit` (550) +* Heredoc content no longer auto-indented + +### 0.9.9.3 (2012/04/19) +* Fix `show-doc` failing on some core classes, like `Bignum` + +### 0.9.9.2 (2012/04/18) +* Make `correct_indentation`'s auto-colorization respect `Pry.color` + +### 0.9.9.1 (2012/04/18) +* Clear up confusion in `show-source`/`show-doc` docs + * `-a` switch applies to classes as well as modules + +### 0.9.9 (2012/04/18) +#### New features +* Lines of input are syntax highlighted upon Enter keypress +* `show-source` command can now show class/module source code + * Use `-a` to see all monkeypatches + * Hard dependency on `ruby18_source_location` gem in MRI 1.8 +* `show-doc` command can now show class/module docs + * Use `-a` to see docs for all monkeypatches + * Hard dependency on `ruby18_source_location` gem in MRI 1.8 +* New `find-method` command + * Performs a recursive search in a namespace for the existence of methods + * Can find methods whose names match a regex or methods which contain + provided code + * This command is like a ruby-aware `grep`, very cool (thanks swarley) +* [`pry-coolline`](https://github.com/pry/pry-coolline) now works properly +* `alias_command` method now much more powerful + * Example: `alias_command "lM", "ls -M"` +* `whereami` is now more intelligent + * Automatically shows entire source code of current method if current + context is a method (thanks robgleeson) +* New `raise-up` command + * Allows you to raise an exception that will bubble out of pry (ending the + session) and escape into enclosing program + +#### Bug fixes, etc. +* Fixed crash when paging under Windows +* Lines ending with `\` are incomplete (kudos to fowl) +* `edit-method -n` no longer blocks (thanks misfo) +* Show instance methods of modules by default in `ls` +* Docs for REPL-defined methods can now be displayed using `show-doc` +* Autoload `ruby18_source_location` on MRI 1.8, when available + * See https://github.com/conradirwin/ruby18_source_location +* Tab completion should work on first line now (historic bug fixed) +* `:quiet => true` option added to `Pry.start`, turns off `whereami` +* Another easter egg added +* Show unloaded constants in yellow for `ls` +* Improved documentation for `Pry.config` options +* Improved auto-indentation +* JRuby: heuristics used to clean up `ls` output + * Fewer internal methods polluting output + +### 0.9.8.4 (2012/6/3) +* ~/.pry_history wasnt being created (if it did not exist)! FIXED +* `hist --save` saved colors! FIXED +* added Pry#add_sticky_local API for adding sticky locals to individual pry instances + +### 0.9.8.3 (2012/3/2) +* various tweaks to improve rbx support +* commands now support optional block arguments +* much improved help command +* updated method_source dependencya +* added wtf command +* jruby should now work in windows (though without color) + +### 0.9.8.2 (2012/2/9) +* fixed bugs related to --super +* upgraded slop dependency +* added edit -c (edit current line) +* edit now respects Pry.config.disable_autoreload option + +### 0.9.8.1 (2012/1/30) +* fixed broken --no-plugins option +* Ensure ARGV is not mutated during option parsing. +* Use a more rbx-friendly test for unicodeness +* Use rbx-{18,19}mode as indicated http://about.travis-ci.org/docs/user/languages/ruby/ +* Don't explode in gem-list [Fixes #453, #454] +* Check for command-name collision on assignment [Fixes #450] + +### 0.9.8 (2012/1/25) + +MAJOR NEW FEATURES +- upgraded command api, https://github.com/pry/pry/wiki/Custom-commands +- added a system of hooks for customizing pry behaviour +- changed syntax checking to use eval() for improved accuracy +- added save-file command +- added gist command (removed gist-method, new gist command is more general) + +complete CHANGELOG: +* CommandError's no longer cause the current input to be disgarded +* Better syntax highlighting for rbx code code +* added cat --in to show pry input history +* prefixed temporary file names with 'pry' +* show-doc now supports -l and -b options (line numbers) +* play now supports -i and -d options +* moved UserCommandAPI command-set to pry-developer_tools plugin +* added :when_started event for hooks, called in Pry.start +* added a man page +* added rename method to Pry::CommandSet (commands can be renamed) +* added CommandSet#{before_command,after_command} for enhancing builtin commands +* added checking for namespace collisions with pry commands, set Pry.config.collision_warning +* work around namespace collisions by ensuring lines starting with a space are executed as +* ruby.work around namespace collisions by prensuring lines starting with a space are executed as ruby +* added handlers for Ctrl+C (SIGINT) on jruby, these are now caught as in other ruby versions +* removed dependency on ruby_parser +* prevented colours leaking across the pry prompt +* fixed edge cases in Pry::Method, for methods with crazy names and methods that have been 'undef'd +* refactored history handling code for clarity and correctness +* added Pry::WrappedModule as a counterpart to Pry::Method +* made a trailing , cause pry to wait for further input +* removed gist-method command, added gist command +* added pry-backtrace command to show history of current session +* fixed whereami within 'super' methods +* replaced inline version guards by Pry::Helpers::BaseHelpers.{rbx?,jruby?,windows?} etc. +* removed the CommandProcessor, its functionality is part of the new Command class +* changed cd .. at the top level so it doesn't quit pry. +* changed edit-command to no-longer need a command set argument +* fixed empty lines so that they don't replace _ by nil +* fixed SyntaxErrors at the REPL level so they don't replace _ex_. + +### 0.9.7.4 (2011/11/5) +* ls -M now works in modules (bugfix) +* added exception msg for bad cd object/path +* no longer die when encounter exceptions in .pryrc +* baked in CoolLine support +* Pry.config.input in .pryrc now respected + +### 0.9.7.3 (2011/10/28) +* really fixed indentation for 'super if' and friends +* Fixed indentation for tmux +* added Pry.config.correct_indent option (to toggle whether indentation +* corrected optional param behaviour for method signatures: e.g Signature meth(param1=?, param2=?) + +### 0.9.7.2 (2011/10/27) +* fixed indentation for 'super if' and 'ensure', 'next if', etc +* refactored Pry#run_command so it can accept an eval_string parameter (so amend-line and so on can work with it) +* changed ^D so it no longer resets indent level automatically + +### 0.9.7.1 (2011/10/26) +* fixed gem dependecy issues + +### 0.9.7 (2011/10/25) + +MAJOR NEW FEATURES: +- upgraded ls command to have a more intuitive interface +- added automatic indentation (thanks YorickPeterse!) +- added Pry::Method wrapper class to encapsulate method-related functionality + +complete CHANGELOG: +* fixed syntax highlighting for object literals +* fixed ActiveSupport method-naming conflict with "in?" +* added --super option to edit-method, show-method, and friends - making it easier to operate on superclass methods +* officially added edit --in to open previous expressions in an editor +* whereami now works for REPL-defined code +* started using JRuby parser for input validation in JRuby (thanks pangloss!) +* fixed bug where ~/.pryrc could be loaded more than once (thanks kelseyjudson!) +* added parse_options! helper to pull option parsing out of commands +* Pry now respects the terminal's input encoding +* moved some requires out of the startup process for improved speed +* added input_array info to DEFAULT_PROMPT, e.g [1] pry(main)> +* added --no-history option to pry binary (prevent history being LOADED, history will still be saved) + +### 0.9.6.2 (2011/9/27) +* downgrading to CodeRay 0.9.8 due to problems with 1.0 and rails (autoloading problem) see #280 on pry and #6 on CodeRay +* also added (as a minor feature) cirwin's implementation of edit --in +* added early break/exit for objectpath errors (the 'cd 34/@hello/bad_path/23') + +### 0.9.6 (2011/9/19) +* restored previous behavior of command-line switches (allowing "-rfilename") +* removed -p option (--play) from edit command +* `edit` with no arguments now edits the current or most recent expression +* `edit` auto-reloads .rb files (need to specify -n to suppress) +* added -p option (--patch) to edit-method command, which allows + monkeypatching methods without touching the original file +* edit-method can now edit REPL-defined methods +* cat --ex now works on exceptions in REPL-defined code +* play -m now uses eval_string.replace() +* play -m --open uses show-input to show play'd code +* added "unindent" helper to make adding help to commands easier +* local ./.pryrc now loaded after ~/.pryrc if it exists +* cat --ex N and edit --ex N now can navigate through backtrace, where cat --ex (with no args) moves throuh successive levels of the backtrace automatically with state stored on the exceptino object itself +* new option Pry.config.exception_window_size determines window size for cat --ex +* input_stack now implemented - pushing objects onto a pry instance's input_stack causes the instance to read from those objects in turn as it encounters EOF on the previous object. On finishing the input_stack the input object for the pry instance is set back to Pry.config.input, if this fails, pry breaks out of the REPL (throw(:breakout)) with an error message +* Pry.config.system() defines how pry runs system commands +* now injecting target_self method into command scope +* play now performs 'show-input' always unless eval_string contains a valid expression (i.e it's about to be eval'd) +* play and hist --replay now push the current input object onto the input_stack before redirecting input to a StringIO (works much better with pry-remote now) + +### 0.9.5 (2011/9/8) + +MAJOR NEW FEATURES: +- JRuby support, including show-method/edit-method and editor integration on both 1.8 and 1.9 versions +- extended cd syntax: cd ../@x/y +- play command now works much better with _in_ array (this is a very powerful feature, esp with Pry::NAV_PROMPT) +- history saving/loading is now lightning fast +- 'edit' (entered by itself) now opens current lines in input buffer in an editor, and evals on exit +- 'edit' command is also, in general more intelligent +- ls output no longer in array format, and colors can be configured, e.g: Pry.config.ls.ivar_color = :bright_blue +- new switch-to command for moving around the binding stack without exiting out of sessions +- more sophisticated prompts, Pry::NAV_PROMPT to ease deep spelunking of code +- major bug fix for windows systems +- much better support for huge objects, should no longer hang pry (see #245) +- cat --ex and edit --ex now work better + +complete CHANGELOG: +* tempfile should end in .rb (for edit -t) +* ls output should not be in array format +* fix history saving (should not save all of Readline::HISTORY, but only what changed) +* prevent blank lines going to Readline::HISTORY (thanks cirwin!) +* ensure that cat --ex emulates the `whereami` format - includes line numbers and formatted the same, etc +* fixed bug #200 ( https://github.com/pry/pry/issues/200 )- string interpolation bug (thanks to ryanf) +* show-doc and stat now display method visibility (update WIKI) +* got rid of warnings caused by stricter ruby 1.9.3 rules +* remove interpolation of command names and fix interpolation error messag (update WIKI) (thanks ryanf!) +* 'nested sessions' now use binding stacks (so each instance manages its own collection of bindings without spawning other instances) +* 'cd ..' just pops a binding off the binding_stack with special behaviour when only one binding in stack - it breaks out of the repl loop +* added switch-to command (like jump-to but doesnt unwind the stack) +* show-method and show-doc now accept multiple method names +* control_d hook added (Pry.config.control_d_handler) +* behaviour of ^d is now to break out of current expr if in multi-line expr, or break out of current context if nested, or break out of pry repl loop if at top-level +* can no longer interpolate command name itself e.g #{x}-#{y} where x = "show" and y = "doc" +* ^C no longer captured +* got rid of Pry.active_instance, Pry.last_exception and friends. +* also special locals now shared among bindings in a pry instance (i.e _ex_ (and friends) re-injected into new binding entered with 'cd') +* renamed inp and out to _in_ and _out_ (to avoid collisions with actual locals in debugging scope) +* added third parameter to prompts, the pry instance itself (_pry) see https://github.com/pry/pry/issues/233 for why it's important +* cd behaviour when no args performs the same as `cd /` +* commands with keep_retval can now return nil (to suppress output now return 'void' instead) +* Pry::CommandProcessor::Result introduced +* Pry.view_clip() modified to be more robust and properly display Class#name +* edit command when invoked with no args now works like edit -t +* when edit is invoked (with no args or with -t) inside a multi-line expression input buffer, it dumps that buffer into a temp file and takes you to it +* got rid of Pry#null_input? since all that was needed was eval_string.empty? +* cd command now supports complex syntax: cd ../@y/y/../z +* JRuby is no longer a 2nd class citizen, almost full JRuby support, passing 100% tests +* added Pry::NAV_PROMPT (great new navigation prompt, per robgleeson) and Pry::SIMPLE_PRINT for simple (IRB-style) print output (just using inspect) +* _pry_ now passed as 3rd parameter to :before_session hook +* ls colors now configurable via Pry.config.ls.local_var_color = :bright_red etc +* ls separator configurable via, e.g Pry.config.ls.separator = " " +* Pry.view_clip() now only calls inspect on a few immediates, otherwise uses the #<> syntax, which has been truncated further to exclude teh mem address, again related to #245 + +### 0.9.3 (2011/7/27) +* cat --ex (cats 5 lines above and below line in file where exception was raised) +* edit --ex (edits line in file where exception was raised) +* edit -t (opens a temporary file and evals it in current context when closed) +* `pry -r` requires now happen after plugin loading (so as not to interfere with +* new Pry.config.disable_auto_reload option, for turning off auto reloading by edit-method and related (thanks ryanf) +* add better error messages for `cd` command +* fixed exotic object regression - BasicObject.new etc now return "=> unknown" +* added reload-method command (reloads the associated file of a method) +* converted: import => import-set, version => pry-version, install => install-command +* Pry.config.command_prefix support (thanks ryanf!) +* fixed indentation for simple-prompt +* hist command now excludes last line of input (the command invocation itself) +* hist now has `history` alias +* missing plugins no longer raise exception, just print a warning to $stderr +* fixed jedit editor support + +### 0.9.2 (2011/6/21) +* fixed string interpolation bug (caused valid ruby code not to execute, sorry!) +* fixed `ls` command, so it can properly display members of Object and classes, and BasicObject, etc +* added a few git related commands to experimental command set, blame and diff + +### 0.9.0 (2011/6/17) +* plugin system +* regex commands +* show-method works on methods defined in REPL +* new command system/API +* rubinius core support +* more backports to ruby 1.8 +* inp/out special locals +* _ex_ backtrace navigation object (_ex_.line, _ex_.file) +* readline history saving/loading +* prompt stack +* more hooks +* amend-line +* play +* show-input +* edit +* much more comprehensive test suite +* support for new and old rubygems API +* changed -s behaviour of ls (now excludes Object methods) +* removed eval-file, lls, lcd, and a few other commands + + +### 0.7.6.1 (2011/3/26) +* added slightly better support for YARD +* now @param and @return tags are colored green and markdown `code` is syntax highlighted using coderay + +### 0.7.6 (2011/3/26) +* `whereami` command now accepts parameter AROUND, to display AROUND lines on eitherside of invocation line. +* made it so `whereami` is invoked even if no method exists in current context (i.e in rspec tests) +* added rubinius support for `whereami` invocation in HOOKS by checking for __unknown__.rb rather than just
+ +### 0.7.0 (2011/3/15) +* add pry-doc support with syntax highlighting for docs +* add 'mj' option to ls (restrict to singleton methods) +* add _ex_ local to hold last exception raised in an exception + +### 0.6.8 (2011/3/6) +* add whereami command, a la the `ir_b` gem +* make whereami run at the start of every session +* make .pryrc be loaded by run-time pry sessions + +### 0.6.7 (2011/3/4) +* color support +* --simple-prompt for pry commandline +* -I mode for pry commandline +* --color mode for pry commandline +* clean up requires (put them all in one place) +* simple-prompt command and toggle-color commandd. + +### 0.6.3 (2011/2/28) +* Using MethodSource 0.3.4 so 1.8 show-method support provided +* `Set` class added to list of classes that are inspected + +### 0.6.1 (2011/2/26) +* !@ command alias for exit_all +* `cd /` for breaking out to pry top level (jump-to 0) +* made `-e` option work in a more effective way for `pry` command line invocation +* exit and exit-all commands now accept a parameter, this parameter becomes the return value of repl() +* `command` method from CommandBase now accepts a :keep_retval arg that determines if command value is returned to pry session or just `nil` (`nil` was old behaviour) +* tests for new :keep_retval and exit-all/exit behaviour; :keep_retval will remain undocumented. + +### 0.5.8 (2011/2/22) +* Added -c (context) option to show-doc, show-methods and eval-file +* Fixed up ordering issue of -c and -r parameters to command line pry + +### 0.5.7 (2011/2/21) +* Added pry executable, auto-loads .pryrc in user's home directory, if it + exists. + +### 0.5.5 (2011/2/19) +* Added Pry.run_command +* More useful error messages +* Easter eggs (game and cohen-poem) + +### 0.5.0 (2011/2/17) +* Use clipped version of Pry.view() for large objects +* Exit Pry session on ^d +* Use Shellwords for breaking up parameters to pry commands +* Use OptionParser to parse options for default pry commands +* Add version command +* Refactor 'status' command: add current method info +* Add meth_name_from_binding utility lambda to commands.rb +* Add -M, -m, -v(erbose), -a(ll), -s(uper), -l(ocals), -i(ivars), -k(klass + vars), etc options to ls +* add -M(instance method) options to show-method and show-doc +* add --help option to most commands +* Get rid of ls_method and ls_imethods (subsumed by more powerful ls) +* Get rid of show_idoc and show_imethod +* Add special eval-file command that evals target file in current context + +### 0.4.5 (2011/1/27) +* fixed show_method (though fragile as it references __binding_impl__ + directly, making a name change to that method difficult + +### 0.4.4 (2011/1/27) +* oops, added examples/ directory + +### 0.4.3 (2011/1/26) +* added alias_command and desc methods to Pry::CommandBase +* changed behaviour of ls_methods and ls_imethods to return sorted lists + of methods + +### 0.4.1 (2011/1/23) +* made it so a 'def meth;end' in an object Pry session defines singleton + methods, not methods on the class (except in the case of + immediates) +* reorganized documentation, moving customization to a separate wiki file +* storing wiki in a nested git repo, as github wiki pages have their own + repo +* added more tests for new method definition behaviour + +### 0.4.0 (2011/1/21) +* added command API +* added many new commands, i.e ls_methods and friends +* modified other commands +* now accepts greater customization, can modify: input, output, hooks, + prompt, print object +* added tab completion (even completes commands) +* added extensive tests +* added examples +* many more changes + +### 0.1.3 (2010/12/9) +* Got rid of rubygems dependency, refactored some code. + +### 0.1.2 (2010/12/8) +* now rescuing SyntaxError as well as Racc::Parser error in valid_expression? + +### 0.1.0 (2010/12/8) +* release! diff --git a/vendor/bundle/gems/pry-0.10.0/LICENSE b/vendor/bundle/gems/pry-0.10.0/LICENSE new file mode 100644 index 0000000..1258004 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/LICENSE @@ -0,0 +1,25 @@ +License +------- + +(The MIT License) + +Copyright (c) 2013 John Mair (banisterfiend) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/gems/pry-0.10.0/README.md b/vendor/bundle/gems/pry-0.10.0/README.md new file mode 100644 index 0000000..9668562 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/README.md @@ -0,0 +1,406 @@ +[![Build Status](https://img.shields.io/travis/pry/pry.svg)](https://travis-ci.org/pry/pry) +[![Code Climate](https://img.shields.io/codeclimate/github/pry/pry.svg)](https://codeclimate.com/github/pry/pry) +[![Inline docs](http://inch-pages.github.io/github/pry/pry.svg)](http://inch-pages.github.io/github/pry/pry) + +
+![The Pry Logo](https://dl.dropbox.com/u/26521875/pry%20stuff/logo/pry_logo_350.png) + +© John Mair ([banisterfiend](https://twitter.com/banisterfiend)) 2013
+ +**Please** [DONATE](http://www.pledgie.com/campaigns/15899) to the Pry project - Pry was a **huge** amount of work and every donation received is encouraging and supports Pry's continued development! + +**Sponsors** + +[Tealeaf Academy](http://www.gotealeaf.com)
+[Atomic Object](http://www.atomicobject.com/)
+[Hashrocket](http://hashrocket.com/)
+[Intridea](http://intridea.com/)
+[Gaslight](http://gaslight.co/home)
+ +**Other Resources** + +[Skip to the website (recommended)](http://pry.github.com)
+[Skip to the wiki](https://github.com/pry/pry/wiki) +
+ +Pry is a powerful alternative to the standard IRB shell for Ruby. It is +written from scratch to provide a number of advanced features, +including: + +* Source code browsing (including core C source with the pry-doc gem) +* Documentation browsing +* Live help system +* Open methods in editors (`edit Class#method`) +* Syntax highlighting +* Command shell integration (start editors, run git, and rake from within Pry) +* Gist integration +* Navigation around state (`cd`, `ls` and friends) +* Runtime invocation (use Pry as a developer console or debugger) +* Exotic object support (BasicObject instances, IClasses, ...) +* A Powerful and flexible command system +* Ability to view and replay history +* Many convenience commands inspired by IPython, Smalltalk and other advanced REPLs +* A wide-range number of [plugins](https://github.com/pry/pry/wiki/Available-plugins) that provide remote sessions, full debugging functionality, and more. + +Pry also aims to be more than an IRB replacement; it is an +attempt to bring REPL driven programming to the Ruby language. It is +currently not as powerful as tools like [SLIME](http://en.wikipedia.org/wiki/SLIME) for lisp, but that is the +general direction Pry is heading. + +Pry is also fairly flexible and allows significant user +[customization](https://github.com/pry/pry/wiki/Customization-and-configuration) +is trivial to set it to read from any object that has a `readline` method and write to any object that has a +`puts` method - many other aspects of Pry are also configurable making +it a good choice for implementing custom shells. + +Pry comes with an executable so it can be invoked at the command line. +Just enter `pry` to start. A `.pryrc` file in the user's home directory will +be loaded if it exists. Type `pry --help` at the command line for more +information. + +Try `gem install pry-doc` for additional documentation on Ruby Core +methods. The additional docs are accessed through the `show-doc` and +`show-method` commands. + +* Install the [gem](https://rubygems.org/gems/pry): `gem install pry` +* Browse the comprehensive [documentation at the official Pry wiki](https://github.com/pry/pry/wiki) +* Read the [YARD API documentation](http://rdoc.info/github/pry/pry/master/file/README.markdown) +* See the [source code](http://github.com/pry/pry) + +### Commands + +Nearly every piece of functionality in a Pry session is implemented as +a command. Commands are not methods and must start at the beginning of a line, with no +whitespace in between. Commands support a flexible syntax and allow +'options' in the same way as shell commands, for example the following +Pry command will show a list of all private instance methods (in +scope) that begin with 'pa' + + pry(YARD::Parser::SourceParser):5> ls -Mp --grep ^pa + YARD::Parser::SourceParser#methods: parse parser_class parser_type parser_type= parser_type_for_filename + +### Navigating around state + +Pry allows us to pop in and out of different scopes (objects) using +the `cd` command. This enables us to explore the run-time view of a +program or library. To view which variables and methods are available +within a particular scope we use the versatile [ls command.](https://gist.github.com/c0fc686ef923c8b87715) + +Here we will begin Pry at top-level, then Pry on a class and then on +an instance variable inside that class: + + pry(main)> class Hello + pry(main)* @x = 20 + pry(main)* end + => 20 + pry(main)> cd Hello + pry(Hello):1> ls -i + instance variables: @x + pry(Hello):1> cd @x + pry(20):2> self + 10 + => 30 + pry(20):2> cd .. + pry(Hello):1> cd .. + pry(main)> cd .. + +The number after the `:` in the pry prompt indicates the nesting +level. To display more information about nesting, use the `nesting` +command. E.g + + pry("friend"):3> nesting + Nesting status: + 0. main (Pry top level) + 1. Hello + 2. 100 + 3. "friend" + => nil + +We can then jump back to any of the previous nesting levels by using +the `jump-to` command: + + pry("friend"):3> jump-to 1 + => 100 + pry(Hello):1> + +### Runtime invocation + +Pry can be invoked in the middle of a running program. It opens a Pry +session at the point it's called and makes all program state at that +point available. It can be invoked on any object using the +`my_object.pry` syntax or on the current binding (or any binding) +using `binding.pry`. The Pry session will then begin within the scope +of the object (or binding). When the session ends the program continues with any +modifications you made to it. + +This functionality can be used for such things as: debugging, +implementing developer consoles and applying hot patches. + +code: + + # test.rb + require 'pry' + + class A + def hello() puts "hello world!" end + end + + a = A.new + + # start a REPL session + binding.pry + + # program resumes here (after pry session) + puts "program resumes here." + +Pry session: + + pry(main)> a.hello + hello world! + => nil + pry(main)> def a.goodbye + pry(main)* puts "goodbye cruel world!" + pry(main)* end + => nil + pry(main)> a.goodbye + goodbye cruel world! + => nil + pry(main)> exit + + program resumes here. + +### Command Shell Integration + +A line of input that begins with a '.' will be forwarded to the +command shell. This enables us to navigate the file system, spawn +editors, and run git and rake directly from within Pry. + +Further, we can use the `shell-mode` command to incorporate the +present working directory into the Pry prompt and bring in (limited at this stage, sorry) file name completion. +We can also interpolate Ruby code directly into the shell by +using the normal `#{}` string interpolation syntax. + +In the code below we're going to switch to `shell-mode` and edit the +`.pryrc` file in the home directory. We'll then cat its contents and +reload the file. + + pry(main)> shell-mode + pry main:/home/john/ruby/projects/pry $ .cd ~ + pry main:/home/john $ .emacsclient .pryrc + pry main:/home/john $ .cat .pryrc + def hello_world + puts "hello world!" + end + pry main:/home/john $ load ".pryrc" + => true + pry main:/home/john $ hello_world + hello world! + +We can also interpolate Ruby code into the shell. In the +example below we use the shell command `cat` on a random file from the +current directory and count the number of lines in that file with +`wc`: + + pry main:/home/john $ .cat #{Dir['*.*'].sample} | wc -l + 44 + +### Code Browsing + +You can browse method source code with the `show-method` command. Nearly all Ruby methods (and some C methods, with the pry-doc +gem) can have their source viewed. Code that is longer than a page is +sent through a pager (such as less), and all code is properly syntax +highlighted (even C code). + +The `show-method` command accepts two syntaxes, the typical ri +`Class#method` syntax and also simply the name of a method that's in +scope. You can optionally pass the `-l` option to show-method to +include line numbers in the output. + +In the following example we will enter the `Pry` class, list the +instance methods beginning with 're' and display the source code for the `rep` method: + + pry(main)> cd Pry + pry(Pry):1> ls -M --grep re + Pry#methods: re readline refresh rep repl repl_epilogue repl_prologue retrieve_line + pry(Pry):1> show-method rep -l + + From: /home/john/ruby/projects/pry/lib/pry/pry_instance.rb @ line 143: + Number of lines: 6 + + 143: def rep(target=TOPLEVEL_BINDING) + 144: target = Pry.binding_for(target) + 145: result = re(target) + 146: + 147: show_result(result) if should_print? + 148: end + +Note that we can also view C methods (from Ruby Core) using the +`pry-doc` plugin; we also show off the alternate syntax for +`show-method`: + + pry(main)> show-method Array#select + + From: array.c in Ruby Core (C Method): + Number of lines: 15 + + static VALUE + rb_ary_select(VALUE ary) + { + VALUE result; + long i; + + RETURN_ENUMERATOR(ary, 0, 0); + result = rb_ary_new2(RARRAY_LEN(ary)); + for (i = 0; i < RARRAY_LEN(ary); i++) { + if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) { + rb_ary_push(result, rb_ary_elt(ary, i)); + } + } + return result; + } + +### Documentation Browsing + +One use-case for Pry is to explore a program at run-time by `cd`-ing +in and out of objects and viewing and invoking methods. In the course +of exploring it may be useful to read the documentation for a +specific method that you come across. Like `show-method` the `show-doc` command supports +two syntaxes - the normal `ri` syntax as well as accepting the name of +any method that is currently in scope. + +The Pry documentation system does not rely on pre-generated `rdoc` or +`ri`, instead it grabs the comments directly above the method on +demand. This results in speedier documentation retrieval and allows +the Pry system to retrieve documentation for methods that would not be +picked up by `rdoc`. Pry also has a basic understanding of both the +rdoc and yard formats and will attempt to syntax highlight the +documentation appropriately. + +Nonetheless, the `ri` functionality is very good and +has an advantage over Pry's system in that it allows documentation +lookup for classes as well as methods. Pry therefore has good +integration with `ri` through the `ri` command. The syntax +for the command is exactly as it would be in command-line - +so it is not necessary to quote strings. + +In our example we will enter the `Gem` class and view the +documentation for the `try_activate` method: + + pry(main)> cd Gem + pry(Gem):1> show-doc try_activate + + From: /Users/john/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/site_ruby/1.9.1/rubygems.rb @ line 201: + Number of lines: 3 + + Try to activate a gem containing path. Returns true if + activation succeeded or wasn't needed because it was already + activated. Returns false if it can't find the path in a gem. + pry(Gem):1> + +We can also use `ri` in the normal way: + + pry(main) ri Array#each + ----------------------------------------------------------- Array#each + array.each {|item| block } -> array + ------------------------------------------------------------------------ + Calls _block_ once for each element in _self_, passing that element + as a parameter. + + a = [ "a", "b", "c" ] + a.each {|x| print x, " -- " } + + produces: + + a -- b -- c -- + +### Gist integration + +If the `gist` gem is installed then method source or documentation can be gisted to github with the +`gist` command. The `gist` command is capable of gisting [almost any REPL content](https://gist.github.com/cae143e4533416529726), including methods, documentation, +input expressions, command source, and so on. In the example below we will gist the C source +code for the `Symbol#to_proc` method to github: + + pry(main)> gist -m Symbol#to_proc + Gist created at https://gist.github.com/5332c38afc46d902ce46 and added to clipboard. + pry(main)> + +You can see the actual gist generated here: [https://gist.github.com/5332c38afc46d902ce46](https://gist.github.com/5332c38afc46d902ce46) + +### Edit methods + +You can use `edit Class#method` or `edit my_method` +(if the method is in scope) to open a method for editing directly in +your favorite editor. Pry has knowledge of a few different editors and +will attempt to open the file at the line the method is defined. + +You can set the editor to use by assigning to the `Pry.editor` +accessor. `Pry.editor` will default to `$EDITOR` or failing that will +use `nano` as the backup default. The file that is edited will be +automatically reloaded after exiting the editor - reloading can be +suppressed by passing the `--no-reload` option to `edit` + +In the example below we will set our default editor to "emacsclient" +and open the `Pry#repl` method for editing: + + pry(main)> Pry.editor = "emacsclient" + pry(main)> edit Pry#repl + +### Live Help System + +Many other commands are available in Pry; to see the full list type +`help` at the prompt. A short description of each command is provided +with basic instructions for use; some commands have a more extensive +help that can be accessed via typing `command_name --help`. A command +will typically say in its description if the `--help` option is +avaiable. + +### Use Pry as your Rails Console + +The recommended way to use Pry as your Rails console is to add +[the `pry-rails` gem](https://github.com/rweng/pry-rails) to +your Gemfile. This replaces the default console with Pry, in +addition to loading the Rails console helpers and adding some +useful Rails-specific commands. + +If you don't want to change your Gemfile, you can still run a Pry +console in your app's environment using Pry's `-r` flag: + + pry -r ./config/environment + +Also check out the [wiki](https://github.com/pry/pry/wiki/Setting-up-Rails-or-Heroku-to-use-Pry) +for more information about integrating Pry with Rails. + +### Limitations: + +* Tab completion is currently a bit broken/limited this will have a + major overhaul in a future version. + +### Syntax Highlighting + +Syntax highlighting is on by default in Pry. If you want to change +the colors, check out the [pry-theme](https://github.com/kyrylo/pry-theme) +gem. + +You can toggle the syntax highlighting on and off in a session by +using the `toggle-color` command. Alternatively, you can turn it off +permanently by putting the line `Pry.color = false` in your `~/.pryrc` +file. + +### Future Directions + +Many new features are planned such as: + +* Increase modularity (rely more on plugin system) +* Much improved documentation system, better support for YARD +* Better support for code and method reloading and saving code +* Extended and more sophisticated command system, allowing piping +between commands and running commands in background + +### Contact + +Problems or questions? file an issue at [github](https://github.com/pry/pry/issues) + +### Contributors + +Pry is primarily the work of [John Mair (banisterfiend)](http://github.com/banister), for full list +of contributors see the +[CONTRIBUTORS](https://github.com/pry/pry/blob/master/CONTRIBUTORS) file. diff --git a/vendor/bundle/gems/pry-0.10.0/bin/pry b/vendor/bundle/gems/pry-0.10.0/bin/pry new file mode 100755 index 0000000..3904fe9 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/bin/pry @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby + +# (C) John Mair (banisterfiend) +# MIT license + +$0 = 'pry' + +begin + require 'pry' +rescue LoadError + require 'rubygems' + require 'pry' +end + +# Process command line options and run Pry +Pry::CLI.parse_options diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry.rb new file mode 100644 index 0000000..a8e81c0 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry.rb @@ -0,0 +1,161 @@ +# (C) John Mair (banisterfiend) 2013 +# MIT License +# +require 'pp' + +require 'pry/input_lock' +require 'pry/exceptions' +require 'pry/helpers/base_helpers' +require 'pry/hooks' +require 'forwardable' + +class Pry + # The default hooks - display messages when beginning and ending Pry sessions. + DEFAULT_HOOKS = Pry::Hooks.new.add_hook(:before_session, :default) do |out, target, _pry_| + next if _pry_.quiet? + _pry_.run_command("whereami --quiet") + end + + # The default print + DEFAULT_PRINT = proc do |output, value, _pry_| + _pry_.pager.open do |pager| + pager.print _pry_.config.output_prefix + Pry::ColorPrinter.pp(value, pager, Pry::Terminal.width! - 1) + end + end + + # may be convenient when working with enormous objects and + # pretty_print is too slow + SIMPLE_PRINT = proc do |output, value| + begin + output.puts value.inspect + rescue RescuableException + output.puts "unknown" + end + end + + # useful when playing with truly enormous objects + CLIPPED_PRINT = proc do |output, value| + output.puts Pry.view_clip(value, id: true) + end + + # Will only show the first line of the backtrace + DEFAULT_EXCEPTION_HANDLER = proc do |output, exception, _| + if UserError === exception && SyntaxError === exception + output.puts "SyntaxError: #{exception.message.sub(/.*syntax error, */m, '')}" + else + output.puts "#{exception.class}: #{exception.message}" + output.puts "from #{exception.backtrace.first}" + end + end + + DEFAULT_PROMPT_NAME = 'pry' + + # The default prompt; includes the target and nesting level + DEFAULT_PROMPT = [ + proc { |target_self, nest_level, pry| + "[#{pry.input_array.size}] #{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}> " + }, + + proc { |target_self, nest_level, pry| + "[#{pry.input_array.size}] #{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}* " + } + ] + + DEFAULT_PROMPT_SAFE_OBJECTS = [String, Numeric, Symbol, nil, true, false] + + # A simple prompt - doesn't display target or nesting level + SIMPLE_PROMPT = [proc { ">> " }, proc { " | " }] + + NO_PROMPT = [proc { '' }, proc { '' }] + + SHELL_PROMPT = [ + proc { |target_self, _, _pry_| "#{_pry_.config.prompt_name} #{Pry.view_clip(target_self)}:#{Dir.pwd} $ " }, + proc { |target_self, _, _pry_| "#{_pry_.config.prompt_name} #{Pry.view_clip(target_self)}:#{Dir.pwd} * " } + ] + + # A prompt that includes the full object path as well as + # input/output (_in_ and _out_) information. Good for navigation. + NAV_PROMPT = [ + proc do |_, _, _pry_| + tree = _pry_.binding_stack.map { |b| Pry.view_clip(b.eval("self")) }.join " / " + "[#{_pry_.input_array.count}] (#{_pry_.config.prompt_name}) #{tree}: #{_pry_.binding_stack.size - 1}> " + end, + proc do |_, _, _pry_| + tree = _pry_.binding_stack.map { |b| Pry.view_clip(b.eval("self")) }.join " / " + "[#{_pry_.input_array.count}] (#{ _pry_.config.prompt_name}) #{tree}: #{_pry_.binding_stack.size - 1}* " + end, + ] + + # Deal with the ^D key being pressed. Different behaviour in different cases: + # 1. In an expression behave like `!` command. + # 2. At top-level session behave like `exit` command. + # 3. In a nested session behave like `cd ..`. + DEFAULT_CONTROL_D_HANDLER = proc do |eval_string, _pry_| + if !eval_string.empty? + eval_string.replace('') # Clear input buffer. + elsif _pry_.binding_stack.one? + _pry_.binding_stack.clear + throw(:breakout) + else + # Otherwise, saves current binding stack as old stack and pops last + # binding out of binding stack (the old stack still has that binding). + _pry_.command_state["cd"] ||= Pry::Config.from_hash({}) # FIXME + _pry_.command_state['cd'].old_stack = _pry_.binding_stack.dup + _pry_.binding_stack.pop + end + end + + DEFAULT_SYSTEM = proc do |output, cmd, _| + if !system(cmd) + output.puts "Error: there was a problem executing system command: #{cmd}" + end + end + + # Store the current working directory. This allows show-source etc. to work if + # your process has changed directory since boot. [Issue #675] + INITIAL_PWD = Dir.pwd + + # This is to keep from breaking under Rails 3.2 for people who are doing that + # IRB = Pry thing. + module ExtendCommandBundle; end +end + +require 'method_source' +require 'shellwords' +require 'stringio' +require 'coderay' +require 'slop' +require 'rbconfig' +require 'tempfile' +require 'pathname' + +require 'pry/version' +require 'pry/repl' +require 'pry/rbx_path' +require 'pry/code' +require 'pry/history_array' +require 'pry/helpers' +require 'pry/code_object' +require 'pry/method' +require 'pry/wrapped_module' +require 'pry/history' +require 'pry/command' +require 'pry/command_set' +require 'pry/commands' +require 'pry/plugins' +require 'pry/core_extensions' +require 'pry/pry_class' +require 'pry/pry_instance' +require 'pry/cli' +require 'pry/color_printer' +require 'pry/pager' +require 'pry/terminal' +require 'pry/editor' +require 'pry/rubygem' +require "pry/indent" +require "pry/last_exception" +require "pry/prompt" +require "pry/inspector" +require 'pry/object_path' +require 'pry/output' diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/cli.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/cli.rb new file mode 100644 index 0000000..ef73869 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/cli.rb @@ -0,0 +1,220 @@ +class Pry + + # Manage the processing of command line options + class CLI + + NoOptionsError = Class.new(StandardError) + + class << self + + # @return [Proc] The Proc defining the valid command line options. + attr_accessor :options + + # @return [Array] The Procs that process the parsed options. Plugins can + # utilize this facility in order to add and process their own Pry + # options. + attr_accessor :option_processors + + # @return [Array] The input array of strings to process + # as CLI options. + attr_accessor :input_args + + # Add another set of CLI options (a Slop block) + def add_options(&block) + if options + old_options = options + self.options = proc do + instance_exec(&old_options) + instance_exec(&block) + end + else + self.options = block + end + + self + end + + # Bring in options defined in plugins + def add_plugin_options + Pry.plugins.values.each do |plugin| + plugin.load_cli_options + end + + self + end + + # Add a block responsible for processing parsed options. + def add_option_processor(&block) + self.option_processors ||= [] + option_processors << block + + self + end + + # Clear `options` and `option_processors` + def reset + self.options = nil + self.option_processors = nil + end + + def parse_options(args=ARGV) + unless options + raise NoOptionsError, "No command line options defined! Use Pry::CLI.add_options to add command line options." + end + + self.input_args = args + + begin + opts = Slop.parse!( + args, + :help => true, + :multiple_switches => false, + :strict => true, + &options + ) + rescue Slop::InvalidOptionError + # Display help message on unknown switches and exit. + puts Slop.new(&options) + exit + end + + # Option processors are optional. + if option_processors + option_processors.each { |processor| processor.call(opts) } + end + + self + end + + end + + reset + end +end + + +# String that is built to be executed on start (created by -e and -exec switches) +exec_string = "" + +# Bring in options defined by plugins +Slop.new do + on "no-plugins" do + Pry.config.should_load_plugins = false + end +end.parse(ARGV.dup) + +if Pry.config.should_load_plugins + Pry::CLI.add_plugin_options +end + +# The default Pry command line options (before plugin options are included) +Pry::CLI.add_options do + banner %{Usage: pry [OPTIONS] +Start a Pry session. +See http://pryrepl.org/ for more information. +Copyright (c) 2013 John Mair (banisterfiend) +-- +} + on :e, :exec=, "A line of code to execute in context before the session starts" do |input| + exec_string << input << "\n" + end + + on "no-pager", "Disable pager for long output" do + Pry.config.pager = false + end + + on "no-history", "Disable history loading" do + Pry.config.history.should_load = false + end + + on "no-color", "Disable syntax highlighting for session" do + Pry.config.color = false + end + + on :f, "Suppress loading of ~/.pryrc and ./.pryrc" do + Pry.config.should_load_rc = false + Pry.config.should_load_local_rc = false + end + + on :s, "select-plugin=", "Only load specified plugin (and no others)." do |plugin_name| + Pry.config.should_load_plugins = false + Pry.plugins[plugin_name].activate! + end + + on :d, "disable-plugin=", "Disable a specific plugin." do |plugin_name| + Pry.plugins[plugin_name].disable! + end + + on "no-plugins", "Suppress loading of plugins." do + Pry.config.should_load_plugins = false + end + + on "plugins", "List installed plugins." do + puts "Installed Plugins:" + puts "--" + Pry.locate_plugins.each do |plugin| + puts "#{plugin.name}".ljust(18) << plugin.spec.summary + end + exit + end + + on "simple-prompt", "Enable simple prompt mode" do + Pry.config.prompt = Pry::SIMPLE_PROMPT + end + + on "noprompt", "No prompt mode" do + Pry.config.prompt = Pry::NO_PROMPT + end + + on :r, :require=, "`require` a Ruby script at startup" do |file| + Pry.config.requires << file + end + + on :I=, "Add a path to the $LOAD_PATH", :as => Array, :delimiter => ":" do |load_path| + load_path.map! do |path| + /\A\.\// =~ path ? path : File.expand_path(path) + end + + $LOAD_PATH.unshift(*load_path) + end + + on "gem", "Shorthand for -I./lib -rgemname" do |load_path| + $LOAD_PATH.unshift("./lib") + Dir["./lib/*.rb"].each do |file| + Pry.config.requires << file + end + end + + on :v, :version, "Display the Pry version" do + puts "Pry version #{Pry::VERSION} on Ruby #{RUBY_VERSION}" + exit + end + + on(:c, :context=, + "Start the session in the specified context. Equivalent to `context.pry` in a session.", + :default => "Pry.toplevel_binding" + ) +end.add_option_processor do |opts| + + exit if opts.help? + + # invoked via cli + Pry.cli = true + + # create the actual context + if opts[:context] + Pry.initial_session_setup + context = Pry.binding_for(eval(opts[:context])) + else + context = Pry.toplevel_binding + end + + if Pry::CLI.input_args.any? && Pry::CLI.input_args != ["pry"] + full_name = File.expand_path(Pry::CLI.input_args.first) + Pry.load_file_through_repl(full_name) + exit + end + + # Start the session (running any code passed with -e, if there is any) + Pry.start(context, :input => StringIO.new(exec_string)) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/code.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/code.rb new file mode 100644 index 0000000..b99f976 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/code.rb @@ -0,0 +1,341 @@ +require 'pry/code/loc' +require 'pry/code/code_range' +require 'pry/code/code_file' + +class Pry + class << self + # Convert the given object into an instance of `Pry::Code`, if it isn't + # already one. + # + # @param [Code, Method, UnboundMethod, Proc, Pry::Method, String, Array, + # IO] obj + def Code(obj) + case obj + when Code + obj + when ::Method, UnboundMethod, Proc, Pry::Method + Code.from_method(obj) + else + Code.new(obj) + end + end + end + + # `Pry::Code` is a class that encapsulates lines of source code and their + # line numbers and formats them for terminal output. It can read from a file + # or method definition or be instantiated with a `String` or an `Array`. + # + # In general, the formatting methods in `Code` return a new `Code` object + # which will format the text as specified when `#to_s` is called. This allows + # arbitrary chaining of formatting methods without mutating the original + # object. + class Code + class << self + include MethodSource::CodeHelpers + + # Instantiate a `Code` object containing code loaded from a file or + # Pry's line buffer. + # + # @param [String] filename The name of a file, or "(pry)". + # @param [Symbol] code_type The type of code the file contains. + # @return [Code] + def from_file(filename, code_type = nil) + code_file = CodeFile.new(filename, code_type) + new(code_file.code, 1, code_file.code_type) + end + + # Instantiate a `Code` object containing code extracted from a + # `::Method`, `UnboundMethod`, `Proc`, or `Pry::Method` object. + # + # @param [::Method, UnboundMethod, Proc, Pry::Method] meth The method + # object. + # @param [Integer, nil] start_line The line number to start on, or nil to + # use the method's original line numbers. + # @return [Code] + def from_method(meth, start_line = nil) + meth = Pry::Method(meth) + start_line ||= meth.source_line || 1 + new(meth.source, start_line, meth.source_type) + end + + # Attempt to extract the source code for module (or class) `mod`. + # + # @param [Module, Class] mod The module (or class) of interest. + # @param [Integer] candidate_rank The module candidate (by rank) + # to use (see `Pry::WrappedModule::Candidate` for more information). + # @param [Integer, nil] start_line The line number to start on, or nil to + # use the method's original line numbers. + # @return [Code] + def from_module(mod, candidate_rank = 0, start_line=nil) + candidate = Pry::WrappedModule(mod).candidate(candidate_rank) + start_line ||= candidate.line + new(candidate.source, start_line, :ruby) + end + end + + # @return [Symbol] The type of code stored in this wrapper. + attr_accessor :code_type + + # Instantiate a `Code` object containing code from the given `Array`, + # `String`, or `IO`. The first line will be line 1 unless specified + # otherwise. If you need non-contiguous line numbers, you can create an + # empty `Code` object and then use `#push` to insert the lines. + # + # @param [Array, String, IO] lines + # @param [Integer?] start_line + # @param [Symbol?] code_type + def initialize(lines = [], start_line = 1, code_type = :ruby) + if lines.is_a? String + lines = lines.lines + end + @lines = lines.each_with_index.map { |line, lineno| + LOC.new(line, lineno + start_line.to_i) } + @code_type = code_type + end + + # Append the given line. +lineno+ is one more than the last existing + # line, unless specified otherwise. + # + # @param [String] line + # @param [Integer?] lineno + # @return [String] The inserted line. + def push(line, lineno = nil) + if lineno.nil? + lineno = @lines.last.lineno + 1 + end + @lines.push(LOC.new(line, lineno)) + line + end + alias << push + + # Filter the lines using the given block. + # + # @yield [LOC] + # @return [Code] + def select(&block) + alter do + @lines = @lines.select(&block) + end + end + + # Remove all lines that aren't in the given range, expressed either as a + # `Range` object or a first and last line number (inclusive). Negative + # indices count from the end of the array of lines. + # + # @param [Range, Integer] start_line + # @param [Integer?] end_line + # @return [Code] + def between(start_line, end_line = nil) + return self unless start_line + + code_range = CodeRange.new(start_line, end_line) + + alter do + @lines = @lines[code_range.indices_range(@lines)] || [] + end + end + + # Take `num_lines` from `start_line`, forward or backwards. + # + # @param [Integer] start_line + # @param [Integer] num_lines + # @return [Code] + def take_lines(start_line, num_lines) + start_idx = + if start_line >= 0 + @lines.index { |loc| loc.lineno >= start_line } || @lines.length + else + [@lines.length + start_line, 0].max + end + + alter do + @lines = @lines.slice(start_idx, num_lines) + end + end + + # Remove all lines except for the +lines+ up to and excluding +lineno+. + # + # @param [Integer] lineno + # @param [Integer] lines + # @return [Code] + def before(lineno, lines = 1) + return self unless lineno + + select do |loc| + loc.lineno >= lineno - lines && loc.lineno < lineno + end + end + + # Remove all lines except for the +lines+ on either side of and including + # +lineno+. + # + # @param [Integer] lineno + # @param [Integer] lines + # @return [Code] + def around(lineno, lines = 1) + return self unless lineno + + select do |loc| + loc.lineno >= lineno - lines && loc.lineno <= lineno + lines + end + end + + # Remove all lines except for the +lines+ after and excluding +lineno+. + # + # @param [Integer] lineno + # @param [Integer] lines + # @return [Code] + def after(lineno, lines = 1) + return self unless lineno + + select do |loc| + loc.lineno > lineno && loc.lineno <= lineno + lines + end + end + + # Remove all lines that don't match the given `pattern`. + # + # @param [Regexp] pattern + # @return [Code] + def grep(pattern) + return self unless pattern + pattern = Regexp.new(pattern) + + select do |loc| + loc.line =~ pattern + end + end + + # Format output with line numbers next to it, unless `y_n` is falsy. + # + # @param [Boolean?] y_n + # @return [Code] + def with_line_numbers(y_n = true) + alter do + @with_line_numbers = y_n + end + end + + # Format output with a marker next to the given +lineno+, unless +lineno+ is + # falsy. + # + # @param [Integer?] lineno + # @return [Code] + def with_marker(lineno = 1) + alter do + @with_marker = !!lineno + @marker_lineno = lineno + end + end + + # Format output with the specified number of spaces in front of every line, + # unless `spaces` is falsy. + # + # @param [Integer?] spaces + # @return [Code] + def with_indentation(spaces = 0) + alter do + @with_indentation = !!spaces + @indentation_num = spaces + end + end + + # @return [String] + def inspect + Object.instance_method(:to_s).bind(self).call + end + + # @return [Integer] the number of digits in the last line. + def max_lineno_width + @lines.length > 0 ? @lines.last.lineno.to_s.length : 0 + end + + # @return [String] a formatted representation (based on the configuration of + # the object). + def to_s + print_to_output("") + end + + # Writes a formatted representation (based on the configuration of the + # object) to the given output, which must respond to `#<<`. + def print_to_output(output, color=false) + @lines.each do |loc| + loc = loc.dup + loc.colorize(@code_type) + loc.add_line_number(max_lineno_width, color) if @with_line_numbers + loc.add_marker(@marker_lineno) if @with_marker + loc.indent(@indentation_num) if @with_indentation + output << loc.line + output << "\n" + end + output + end + + # Get the comment that describes the expression on the given line number. + # + # @param [Integer] line_number (1-based) + # @return [String] the code. + def comment_describing(line_number) + self.class.comment_describing(raw, line_number) + end + + # Get the multiline expression that starts on the given line number. + # + # @param [Integer] line_number (1-based) + # @return [String] the code. + def expression_at(line_number, consume = 0) + self.class.expression_at(raw, line_number, :consume => consume) + end + + # Get the (approximate) Module.nesting at the give line number. + # + # @param [Integer] line_number line number starting from 1 + # @param [Module] top_module the module in which this code exists + # @return [Array] a list of open modules. + def nesting_at(line_number, top_module = Object) + Pry::Indent.nesting_at(raw, line_number) + end + + # Return an unformatted String of the code. + # + # @return [String] + def raw + @lines.map(&:line).join("\n") << "\n" + end + + # Return the number of lines stored. + # + # @return [Integer] + def length + @lines ? @lines.length : 0 + end + + # Two `Code` objects are equal if they contain the same lines with the same + # numbers. Otherwise, call `to_s` and `chomp` and compare as Strings. + # + # @param [Code, Object] other + # @return [Boolean] + def ==(other) + if other.is_a?(Code) + other_lines = other.instance_variable_get(:@lines) + @lines.each_with_index.all? { |loc, i| loc == other_lines[i] } + else + to_s.chomp == other.to_s.chomp + end + end + + # Forward any missing methods to the output of `#to_s`. + def method_missing(name, *args, &block) + to_s.send(name, *args, &block) + end + undef =~ + + protected + + # An abstraction of the `dup.instance_eval` pattern used throughout this + # class. + def alter(&block) + dup.tap { |o| o.instance_eval(&block) } + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_file.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_file.rb new file mode 100644 index 0000000..9ccb23b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_file.rb @@ -0,0 +1,103 @@ +class Pry + class CodeFile + DEFAULT_EXT = '.rb' + + # List of all supported languages. + # @return [Hash] + EXTENSIONS = { + %w(.py) => :python, + %w(.js) => :javascript, + %w(.css) => :css, + %w(.xml) => :xml, + %w(.php) => :php, + %w(.html) => :html, + %w(.diff) => :diff, + %w(.java) => :java, + %w(.json) => :json, + %w(.c .h) => :c, + %w(.rhtml) => :rhtml, + %w(.yaml .yml) => :yaml, + %w(.cpp .hpp .cc .h cxx) => :cpp, + %w(.rb .ru .irbrc .gemspec .pryrc) => :ruby, + } + + # @return [Symbol] The type of code stored in this wrapper. + attr_reader :code_type + + # @param [String] filename The name of a file with code to be detected + # @param [Symbol] code_type The type of code the `filename` contains + def initialize(filename, code_type = type_from_filename(filename)) + @filename = filename + @code_type = code_type + end + + # @return [String] The code contained in the current `@filename`. + def code + if @filename == Pry.eval_path + Pry.line_buffer.drop(1) + elsif Pry::Method::Patcher.code_for(@filename) + Pry::Method::Patcher.code_for(@filename) + elsif RbxPath.is_core_path?(@filename) + File.read(RbxPath.convert_path_to_full(@filename)) + else + path = abs_path + @code_type = type_from_filename(path) + File.read(path) + end + end + + private + + # @raise [MethodSource::SourceNotFoundError] if the `filename` is not + # readable for some reason. + # @return [String] absolute path for the given `filename`. + def abs_path + code_path.detect { |path| readable?(path) } or + raise MethodSource::SourceNotFoundError, + "Cannot open #{ @filename.inspect } for reading." + end + + # @param [String] path + # @return [Boolean] if the path, with or without the default ext, + # is a readable file then `true`, otherwise `false`. + def readable?(path) + File.readable?(path) && !File.directory?(path) or + File.readable?(path << DEFAULT_EXT) + end + + # @return [Array] All the paths that contain code that Pry can use for its + # API's. Skips directories. + def code_path + [from_pwd, from_pry_init_pwd, *from_load_path] + end + + # @param [String] filename + # @param [Symbol] default (:unknown) the file type to assume if none could be + # detected. + # @return [Symbol, nil] The CodeRay type of a file from its extension, or + # `nil` if `:unknown`. + def type_from_filename(filename, default = :unknown) + _, @code_type = EXTENSIONS.find do |k, _| + k.any? { |ext| ext == File.extname(filename) } + end + + code_type || default + end + + # @return [String] + def from_pwd + File.expand_path(@filename, Dir.pwd) + end + + # @return [String] + def from_pry_init_pwd + File.expand_path(@filename, Pry::INITIAL_PWD) + end + + # @return [String] + def from_load_path + $LOAD_PATH.map { |path| File.expand_path(@filename, path) } + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_range.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_range.rb new file mode 100644 index 0000000..043be02 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_range.rb @@ -0,0 +1,71 @@ +class Pry + class Code + + # Represents a range of lines in a code listing. + # + # @api private + class CodeRange + + # @param [Integer] start_line + # @param [Integer?] end_line + def initialize(start_line, end_line = nil) + @start_line = start_line + @end_line = end_line + force_set_end_line + end + + # @param [Array] lines + # @return [Range] + def indices_range(lines) + Range.new(*indices(lines)) + end + + private + + def start_line; @start_line; end + def end_line; @end_line; end + + # If `end_line` is equal to `nil`, then calculate it from the first + # parameter, `start_line`. Otherwise, leave it as it is. + # @return [void] + def force_set_end_line + if start_line.is_a?(Range) + set_end_line_from_range + else + @end_line ||= start_line + end + end + + # Finds indices of `start_line` and `end_line` in the given Array of + # +lines+. + # + # @param [Array] lines + # @return [Array] + def indices(lines) + [find_start_index(lines), find_end_index(lines)] + end + + # @return [Integer] + def find_start_index(lines) + return start_line if start_line < 0 + lines.index { |loc| loc.lineno >= start_line } || lines.length + end + + # @return [Integer] + def find_end_index(lines) + return end_line if end_line < 0 + (lines.index { |loc| loc.lineno > end_line } || 0) - 1 + end + + # For example, if the range is 4..10, then `start_line` would be equal to + # 4 and `end_line` to 10. + # @return [void] + def set_end_line_from_range + @end_line = start_line.last + @end_line -= 1 if start_line.exclude_end? + @start_line = start_line.first + end + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/code/loc.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/code/loc.rb new file mode 100644 index 0000000..905c704 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/code/loc.rb @@ -0,0 +1,92 @@ +class Pry + class Code + + # Represents a line of code. A line of code is a tuple, which consists of a + # line and a line number. A `LOC` object's state (namely, the line + # parameter) can be changed via instance methods. `Pry::Code` heavily uses + # this class. + # + # @api private + # @example + # loc = LOC.new("def example\n :example\nend", 1) + # puts loc.line + # def example + # :example + # end + # #=> nil + # + # loc.indent(3) + # loc.line #=> " def example\n :example\nend" + class LOC + + # @return [Array] + attr_reader :tuple + + # @param [String] line The line of code. + # @param [Integer] lineno The position of the +line+. + def initialize(line, lineno) + @tuple = [line.chomp, lineno.to_i] + end + + # @return [Boolean] + def ==(other) + other.tuple == tuple + end + + def dup + self.class.new(line, lineno) + end + + # @return [String] + def line + tuple.first + end + + # @return [Integer] + def lineno + tuple.last + end + + # Paints the `line` of code. + # + # @param [Symbol] code_type + # @return [void] + def colorize(code_type) + tuple[0] = CodeRay.scan(line, code_type).term + end + + # Prepends the line number `lineno` to the `line`. + # + # @param [Integer] max_width + # @return [void] + def add_line_number(max_width = 0, color = false) + padded = lineno.to_s.rjust(max_width) + colorized_lineno = color ? Pry::Helpers::BaseHelpers.colorize_code(padded) : padded + tuple[0] = "#{ colorized_lineno }: #{ line }" + end + + # Prepends a marker "=>" or an empty marker to the +line+. + # + # @param [Integer] marker_lineno If it is equal to the `lineno`, then + # prepend a hashrocket. Otherwise, an empty marker. + # @return [void] + def add_marker(marker_lineno) + tuple[0] = + if lineno == marker_lineno + " => #{ line }" + else + " #{ line }" + end + end + + # Indents the `line` with +distance+ spaces. + # + # @param [Integer] distance + # @return [void] + def indent(distance) + tuple[0] = "#{ ' ' * distance }#{ line }" + end + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/code_object.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/code_object.rb new file mode 100644 index 0000000..11a3aa6 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/code_object.rb @@ -0,0 +1,172 @@ +class Pry + + # This class is responsible for taking a string (identifying a + # command/class/method/etc) and returning the relevant type of object. + # For example, if the user looks up "show-source" then a + # `Pry::Command` will be returned. Alternatively, if the user passes in "Pry#repl" then + # a `Pry::Method` object will be returned. + # + # The `CodeObject.lookup` method is responsible for 1. figuring out what kind of + # object the user wants (applying precedence rules in doing so -- i.e methods + # get precedence over commands with the same name) and 2. Returning + # the appropriate object. If the user fails to provide a string + # identifer for the object (i.e they pass in `nil` or "") then the + # object looked up will be the 'current method' or 'current class' + # associated with the Binding. + # + # TODO: This class is a clusterfuck. We need a much more robust + # concept of what a "Code Object" really is. Currently + # commands/classes/candidates/methods and so on just share a very + # ill-defined interface. + class CodeObject + module Helpers + # we need this helper as some Pry::Method objects can wrap Procs + # @return [Boolean] + def real_method_object? + is_a?(::Method) || is_a?(::UnboundMethod) + end + + def c_method? + real_method_object? && source_type == :c + end + + def module_with_yard_docs? + is_a?(WrappedModule) && yard_docs? + end + + def command? + is_a?(Module) && self <= Pry::Command + end + end + + include Pry::Helpers::CommandHelpers + + class << self + def lookup(str, _pry_, options={}) + co = new(str, _pry_, options) + + co.default_lookup || co.method_or_class_lookup || + co.command_lookup || co.empty_lookup + end + end + + attr_accessor :str + attr_accessor :target + attr_accessor :_pry_ + attr_accessor :super_level + + def initialize(str, _pry_, options={}) + options = { + :super => 0, + }.merge!(options) + + @str = str + @_pry_ = _pry_ + @target = _pry_.current_context + @super_level = options[:super] + end + + def command_lookup + # TODO: just make it so find_command_by_match_or_listing doesn't + # raise? + _pry_.commands.find_command_by_match_or_listing(str) rescue nil + end + + # when no paramter is given (i.e CodeObject.lookup(nil)), then we + # lookup the 'current object' from the binding. + def empty_lookup + return nil if str && !str.empty? + + obj = if internal_binding?(target) + mod = target_self.is_a?(Module) ? target_self : target_self.class + Pry::WrappedModule(mod) + else + Pry::Method.from_binding(target) + end + + # respect the super level (i.e user might have specified a + # --super flag to show-source) + lookup_super(obj, super_level) + end + + # lookup variables and constants and `self` that are not modules + def default_lookup + + # we skip instance methods as we want those to fall through to method_or_class_lookup() + if safe_to_evaluate?(str) && !looks_like_an_instance_method?(str) + obj = target.eval(str) + + # restrict to only objects we KNOW for sure support the full API + # Do NOT support just any object that responds to source_location + if sourcable_object?(obj) + Pry::Method(obj) + elsif !obj.is_a?(Module) + Pry::WrappedModule(obj.class) + else + nil + end + end + + rescue Pry::RescuableException + nil + end + + def method_or_class_lookup + obj = case str + when /\S+\(\)\z/ + Pry::Method.from_str(str.sub(/\(\)\z/, ''),target) || Pry::WrappedModule.from_str(str, target) + else + Pry::WrappedModule.from_str(str,target) || Pry::Method.from_str(str, target) + end + + lookup_super(obj, super_level) + end + + private + + def sourcable_object?(obj) + [::Proc, ::Method, ::UnboundMethod].any? { |o| obj.is_a?(o) } + end + + # Returns true if `str` looks like a method, i.e Klass#method + # We need to consider this case because method lookups should fall + # through to the `method_or_class_lookup()` method but a + # defined?() on a "Klass#method` string will see the `#` as a + # comment and only evaluate the `Klass` part. + # @param [String] str + # @return [Boolean] Whether the string looks like an instance method. + def looks_like_an_instance_method?(str) + str =~ /\S#\S/ + end + + # We use this method to decide whether code is safe to eval. Method's are + # generally not, but everything else is. + # TODO: is just checking != "method" enough?? + # TODO: see duplication of this method in Pry::WrappedModule + # @param [String] str The string to lookup + # @return [Boolean] + def safe_to_evaluate?(str) + return true if str.strip == "self" + kind = target.eval("defined?(#{str})") + kind =~ /variable|constant/ + end + + def target_self + target.eval('self') + end + + # grab the nth (`super_level`) super of `obj + # @param [Object] obj + # @param [Fixnum] super_level How far up the super chain to ascend. + def lookup_super(obj, super_level) + return nil if !obj + + sup = obj.super(super_level) + if !sup + raise Pry::CommandError, "No superclass found for #{obj.wrapped}" + else + sup + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/color_printer.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/color_printer.rb new file mode 100644 index 0000000..218a821 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/color_printer.rb @@ -0,0 +1,55 @@ +# PP subclass for streaming inspect output in color. +class Pry + class ColorPrinter < ::PP + OBJ_COLOR = begin + code = CodeRay::Encoders::Terminal::TOKEN_COLORS[:keyword] + if code.start_with? "\e" + code + else + "\e[0m\e[0;#{code}m" + end + end + + CodeRay::Encoders::Terminal::TOKEN_COLORS[:comment][:self] = "\e[1;34m" + + def self.pp(obj, out = $>, width = 79) + q = ColorPrinter.new(out, width) + q.guard_inspect_key { q.pp obj } + q.flush + out << "\n" + end + + def text(str, width = str.length) + # Don't recolorize output with color [Issue #751] + if str.include?("\e[") + super "#{str}\e[0m", width + elsif str.start_with?('#<') || str == '=' || str == '>' + super highlight_object_literal(str), width + else + super CodeRay.scan(str, :ruby).term, width + end + end + + def pp(obj) + super + rescue => e + raise if e.is_a? Pry::Pager::StopPaging + + # Read the class name off of the singleton class to provide a default + # inspect. + singleton = class << obj; self; end + ancestors = Pry::Method.safe_send(singleton, :ancestors) + klass = ancestors.reject { |k| k == singleton }.first + obj_id = obj.__id__.to_s(16) rescue 0 + str = "#<#{klass}:0x#{obj_id}>" + + text highlight_object_literal(str) + end + + private + + def highlight_object_literal(object_literal) + "#{OBJ_COLOR}#{object_literal}\e[0m" + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/command.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/command.rb new file mode 100644 index 0000000..0cf334f --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/command.rb @@ -0,0 +1,692 @@ +require 'delegate' +require 'pry/helpers/documentation_helpers' + +class Pry + + # The super-class of all commands, new commands should be created by calling + # {Pry::CommandSet#command} which creates a BlockCommand or {Pry::CommandSet#create_command} + # which creates a ClassCommand. Please don't use this class directly. + class Command + extend Helpers::DocumentationHelpers + extend CodeObject::Helpers + + # represents a void return value for a command + VOID_VALUE = Object.new + + # give it a nice inspect + def VOID_VALUE.inspect() "void" end + + # Properties of the command itself (as passed as arguments to + # {CommandSet#command} or {CommandSet#create_command}). + class << self + attr_writer :block + attr_writer :description + attr_writer :command_options + attr_writer :match + + def match(arg=nil) + if arg + @command_options ||= default_options(arg) + @command_options[:listing] = arg.is_a?(String) ? arg : arg.inspect + @match = arg + end + @match ||= nil + end + + # Define or get the command's description + def description(arg=nil) + @description = arg if arg + @description ||= nil + end + + # Define or get the command's options + def command_options(arg=nil) + @command_options ||= default_options(match) + @command_options.merge!(arg) if arg + @command_options + end + # backward compatibility + alias_method :options, :command_options + alias_method :options=, :command_options= + + # Define or get the command's banner + def banner(arg=nil) + @banner = arg if arg + @banner || description + end + + def block + @block || instance_method(:process) + end + + def source + file, line = block.source_location + strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line)) + end + + def doc + new.help + end + + def source_location + block.source_location + end + + def source_file + Array(block.source_location).first + end + alias_method :file, :source_file + + def source_line + Array(block.source_location).last + end + alias_method :line, :source_line + + def default_options(match) + { + :requires_gem => [], + :keep_retval => false, + :argument_required => false, + :interpolate => true, + :shellwords => true, + :listing => (String === match ? match : match.inspect), + :use_prefix => true, + :takes_block => false + } + end + end + + # Make those properties accessible to instances + def name; self.class.name; end + def match; self.class.match; end + def description; self.class.description; end + def block; self.class.block; end + def command_options; self.class.options; end + def command_name; self.class.command_name; end + def source; self.class.source; end + def source_location; self.class.source_location; end + + class << self + def name + super.to_s == "" ? "#" : super + end + + def inspect + name + end + + def command_name + self.options[:listing] + end + + # Create a new command with the given properties. + # @param [String, Regex] match The thing that triggers this command + # @param [String] description The description to appear in `help` + # @param [Hash] options Behavioral options (see {Pry::CommandSet#command}) + # @param [Module] helpers A module of helper functions to be included. + # @yield optional, used for BlockCommands + # @return [Class] (a subclass of {Pry::Command}) + def subclass(match, description, options, helpers, &block) + klass = Class.new(self) + klass.send(:include, helpers) + klass.match = match + klass.description = description + klass.command_options = options + klass.block = block + klass + end + + # Should this command be called for the given line? + # @param [String] val A line input at the REPL + # @return [Boolean] + def matches?(val) + command_regex =~ val + end + + # How well does this command match the given line? + # + # Higher scores are better because they imply that this command matches + # the line more closely. + # + # The score is calculated by taking the number of characters at the start + # of the string that are used only to identify the command, not as part of + # the arguments. + # + # @example + # /\.(.*)/.match_score(".foo") #=> 1 + # /\.*(.*)/.match_score("...foo") #=> 3 + # 'hi'.match_score("hi there") #=> 2 + # + # @param [String] val A line input at the REPL + # @return [Fixnum] + def match_score(val) + if command_regex =~ val + Regexp.last_match.size > 1 ? Regexp.last_match.begin(1) : Regexp.last_match.end(0) + else + -1 + end + end + + # Store hooks to be run before or after the command body. + # @see {Pry::CommandSet#before_command} + # @see {Pry::CommandSet#after_command} + def hooks + @hooks ||= {:before => [], :after => []} + end + + def command_regex + pr = Pry.respond_to?(:config) ? Pry.config.command_prefix : "" + prefix = convert_to_regex(pr) + prefix = "(?:#{prefix})?" unless options[:use_prefix] + + /^#{prefix}#{convert_to_regex(match)}(?!\S)/ + end + + def convert_to_regex(obj) + case obj + when String + Regexp.escape(obj) + else + obj + end + end + + # The group in which the command should be displayed in "help" output. + # This is usually auto-generated from directory naming, but it can be + # manually overridden if necessary. + # Group should not be changed once it is initialized. + def group(name=nil) + @group ||= if name + name + else + case Pry::Method(block).source_file + when %r{/pry/.*_commands/(.*).rb} + $1.capitalize.gsub(/_/, " ") + when %r{(pry-\w+)-([\d\.]+([\w\.]+)?)} + name, version = $1, $2 + "#{name.to_s} (v#{version.to_s})" + when /pryrc/ + "~/.pryrc" + else + "(other)" + end + end + end + end + + # Properties of one execution of a command (passed by {Pry#run_command} as a hash of + # context and expanded in `#initialize` + attr_accessor :output + attr_accessor :target + attr_accessor :captures + attr_accessor :eval_string + attr_accessor :arg_string + attr_accessor :context + attr_accessor :command_set + attr_accessor :_pry_ + + # The block we pass *into* a command so long as `:takes_block` is + # not equal to `false` + # @example + # my-command | do + # puts "block content" + # end + attr_accessor :command_block + + # Run a command from another command. + # @param [String] command_string The string that invokes the command + # @param [Array] args Further arguments to pass to the command + # @example + # run "show-input" + # @example + # run ".ls" + # @example + # run "amend-line", "5", 'puts "hello world"' + def run(command_string, *args) + command_string = _pry_.config.command_prefix.to_s + command_string + complete_string = "#{command_string} #{args.join(" ")}".rstrip + command_set.process_line(complete_string, context) + end + + def commands + command_set.to_hash + end + + def text + Pry::Helpers::Text + end + + def void + VOID_VALUE + end + + include Pry::Helpers::BaseHelpers + include Pry::Helpers::CommandHelpers + + # Instantiate a command, in preparation for calling it. + # @param [Hash] context The runtime context to use with this command. + def initialize(context={}) + self.context = context + self.target = context[:target] + self.output = context[:output] + self.eval_string = context[:eval_string] + self.command_set = context[:command_set] + self._pry_ = context[:pry_instance] + end + + # @return [Object] The value of `self` inside the `target` binding. + def target_self; target.eval('self'); end + + # @return [Hash] Pry commands can store arbitrary state + # here. This state persists between subsequent command invocations. + # All state saved here is unique to the command, it does not + # need to be namespaced. + # @example + # state.my_state = "my state" # this will not conflict with any + # # `state.my_state` used in another command. + def state + _pry_.command_state[match] ||= Pry::Config.from_hash({}) + end + + # Revaluate the string (str) and perform interpolation. + # @param [String] str The string to reevaluate with interpolation. + # + # @return [String] The reevaluated string with interpolations + # applied (if any). + def interpolate_string(str) + dumped_str = str.dump + if dumped_str.gsub!(/\\\#\{/, '#{') + target.eval(dumped_str) + else + str + end + end + + # Display a warning if a command collides with a local/method in + # the current scope. + def check_for_command_collision(command_match, arg_string) + collision_type = target.eval("defined?(#{command_match})") + collision_type ||= 'local-variable' if arg_string.match(%r{\A\s*[-+*/%&|^]*=}) + + if collision_type + output.puts "#{text.bold('WARNING:')} Calling Pry command '#{command_match}', which conflicts with a #{collision_type}.\n\n" + end + rescue Pry::RescuableException + end + + # Extract necessary information from a line that Command.matches? this + # command. + # + # Returns an array of four elements: + # + # ``` + # [String] the portion of the line that matched with the Command match + # [String] a string of all the arguments (i.e. everything but the match) + # [Array] the captures caught by the command_regex + # [Array] the arguments obtained by splitting the arg_string + # ``` + # + # @param [String] val The line of input + # @return [Array] + def tokenize(val) + val.replace(interpolate_string(val)) if command_options[:interpolate] + + self.class.command_regex =~ val + + # please call Command.matches? before Command#call_safely + raise CommandError, "fatal: called a command which didn't match?!" unless Regexp.last_match + captures = Regexp.last_match.captures + pos = Regexp.last_match.end(0) + + arg_string = val[pos..-1] + + # remove the one leading space if it exists + arg_string.slice!(0) if arg_string.start_with?(" ") + + # process and pass a block if one is found + pass_block(arg_string) if command_options[:takes_block] + + if arg_string + args = command_options[:shellwords] ? Shellwords.shellwords(arg_string) : arg_string.split(" ") + else + args = [] + end + + [val[0..pos].rstrip, arg_string, captures, args] + end + + # Process a line that Command.matches? this command. + # @param [String] line The line to process + # @return [Object, Command::VOID_VALUE] + def process_line(line) + command_match, arg_string, captures, args = tokenize(line) + + check_for_command_collision(command_match, arg_string) if Pry.config.collision_warning + + self.arg_string = arg_string + self.captures = captures + + call_safely(*(captures + args)) + end + + # Pass a block argument to a command. + # @param [String] arg_string The arguments (as a string) passed to the command. + # We inspect these for a '| do' or a '| {' and if we find it we use it + # to start a block input sequence. Once we have a complete + # block, we save it to an accessor that can be retrieved from the command context. + # Note that if we find the '| do' or '| {' we delete this and the + # elements following it from `arg_string`. + def pass_block(arg_string) + # Workaround for weird JRuby bug where rindex in this case can return nil + # even when there's a match. + arg_string.scan(/\| *(?:do|\{)/) + block_index = $~ && $~.offset(0)[0] + + return if !block_index + + block_init_string = arg_string.slice!(block_index..-1)[1..-1] + prime_string = "proc #{block_init_string}\n" + + if !Pry::Code.complete_expression?(prime_string) + block_string = _pry_.r(target, prime_string) + else + block_string = prime_string + end + + begin + self.command_block = target.eval(block_string) + rescue Pry::RescuableException + raise CommandError, "Incomplete block definition." + end + end + + private :pass_block + + # Run the command with the given `args`. + # + # This is a public wrapper around `#call` which ensures all preconditions + # are met. + # + # @param [Array] args The arguments to pass to this command. + # @return [Object] The return value of the `#call` method, or + # {Command::VOID_VALUE}. + def call_safely(*args) + unless dependencies_met? + gems_needed = Array(command_options[:requires_gem]) + gems_not_installed = gems_needed.select { |g| !Rubygem.installed?(g) } + output.puts "\nThe command '#{command_name}' is #{text.bold("unavailable")} because it requires the following gems to be installed: #{(gems_not_installed.join(", "))}" + output.puts "-" + output.puts "Type `install-command #{command_name}` to install the required gems and activate this command." + return void + end + + if command_options[:argument_required] && args.empty? + raise CommandError, "The command '#{command_name}' requires an argument." + end + + ret = call_with_hooks(*args) + command_options[:keep_retval] ? ret : void + end + + # Are all the gems required to use this command installed? + # + # @return Boolean + def dependencies_met? + @dependencies_met ||= command_dependencies_met?(command_options) + end + + # Generate completions for this command + # + # @param [String] search The line typed so far + # @return [Array] Completion words + def complete(search) + [] + end + + private + + # Run the `#call` method and all the registered hooks. + # @param [Array] args The arguments to `#call` + # @return [Object] The return value from `#call` + def call_with_hooks(*args) + self.class.hooks[:before].each do |block| + instance_exec(*args, &block) + end + + ret = call(*args) + + self.class.hooks[:after].each do |block| + ret = instance_exec(*args, &block) + end + + ret + end + + # Fix the number of arguments we pass to a block to avoid arity warnings. + # @param [Fixnum] arity The arity of the block + # @param [Array] args The arguments to pass + # @return [Array] A (possibly shorter) array of the arguments to pass + def correct_arg_arity(arity, args) + case + when arity < 0 + args + when arity == 0 + [] + when arity > 0 + args.values_at(*(0..(arity - 1)).to_a) + end + end + end + + # A super-class for Commands that are created with a single block. + # + # This class ensures that the block is called with the correct number of arguments + # and the right context. + # + # Create subclasses using {Pry::CommandSet#command}. + class BlockCommand < Command + # backwards compatibility + alias_method :opts, :context + + # Call the block that was registered with this command. + # @param [Array] args The arguments passed + # @return [Object] The return value of the block + def call(*args) + instance_exec(*correct_arg_arity(block.arity, args), &block) + end + + def help + "#{command_options[:listing].to_s.ljust(18)} #{description}" + end + end + + # A super-class of Commands with structure. + # + # This class implements the bare-minimum functionality that a command should + # have, namely a --help switch, and then delegates actual processing to its + # subclasses. + # + # Create subclasses using {Pry::CommandSet#create_command}, and override the + # `options(opt)` method to set up an instance of Slop, and the `process` + # method to actually run the command. If necessary, you can also override + # `setup` which will be called before `options`, for example to require any + # gems your command needs to run, or to set up state. + class ClassCommand < Command + class << self + + # Ensure that subclasses inherit the options, description and + # match from a ClassCommand super class. + def inherited(klass) + klass.match match + klass.description description + klass.command_options options + end + + def source + source_object.source + end + + def doc + new.help + end + + def source_location + source_object.source_location + end + + def source_file + source_object.source_file + end + alias_method :file, :source_file + + def source_line + source_object.source_line + end + alias_method :line, :source_line + + private + + # The object used to extract the source for the command. + # + # This should be a `Pry::Method(block)` for a command made with `create_command` + # and a `Pry::WrappedModule(self)` for a command that's a standard class. + # @return [Pry::WrappedModule, Pry::Method] + def source_object + @source_object ||= if name =~ /^[A-Z]/ + Pry::WrappedModule(self) + else + Pry::Method(block) + end + end + end + + attr_accessor :opts + attr_accessor :args + + # Set up `opts` and `args`, and then call `process`. + # + # This method will display help if necessary. + # + # @param [Array] args The arguments passed + # @return [Object] The return value of `process` or VOID_VALUE + def call(*args) + setup + + self.opts = slop + self.args = self.opts.parse!(args) + + if opts.present?(:help) + output.puts slop.help + void + else + process(*correct_arg_arity(method(:process).arity, args)) + end + end + + # Return the help generated by Slop for this command. + def help + slop.help + end + + # Return an instance of Slop that can parse either subcommands or the + # options that this command accepts. + def slop + Slop.new do |opt| + opt.banner(unindent(self.class.banner)) + subcommands(opt) + options(opt) + opt.on :h, :help, 'Show this message.' + end + end + + # Generate shell completions + # @param [String] search The line typed so far + # @return [Array] the words to complete + def complete(search) + slop.map do |opt| + [opt.long && "--#{opt.long} " || opt.short && "-#{opt.short}"] + end.flatten(1).compact + super + end + + # A method called just before `options(opt)` as part of `call`. + # + # This method can be used to set up any context your command needs to run, + # for example requiring gems, or setting default values for options. + # + # @example + # def setup + # require 'gist' + # @action = :method + # end + def setup; end + + # A method to setup Slop commands so it can parse the subcommands your + # command expects. If you need to set up default values, use `setup` + # instead. + # + # @example A minimal example + # def subcommands(cmd) + # cmd.command :download do |opt| + # description 'Downloads a content from a server' + # + # opt.on :verbose, 'Use verbose output' + # + # run do |options, arguments| + # ContentDownloader.download(options, arguments) + # end + # end + # end + # + # @example Define the invokation block anywhere you want + # def subcommands(cmd) + # cmd.command :download do |opt| + # description 'Downloads a content from a server' + # + # opt.on :verbose, 'Use verbose output' + # end + # end + # + # def process + # # Perform calculations... + # opts.fetch_command(:download).run do |options, arguments| + # ContentDownloader.download(options, arguments) + # end + # # More calculations... + # end + def subcommands(cmd); end + + # A method to setup Slop so it can parse the options your command expects. + # + # @note Please don't do anything side-effecty in the main part of this + # method, as it may be called by Pry at any time for introspection reasons. + # If you need to set up default values, use `setup` instead. + # + # @example + # def options(opt) + # opt.banner "Gists methods or classes" + # opt.on(:c, :class, "gist a class") do + # @action = :class + # end + # end + def options(opt); end + + # The actual body of your command should go here. + # + # The `opts` mehod can be called to get the options that Slop has passed, + # and `args` gives the remaining, unparsed arguments. + # + # The return value of this method is discarded unless the command was + # created with `:keep_retval => true`, in which case it is returned to the + # repl. + # + # @example + # def process + # if opts.present?(:class) + # gist_class + # else + # gist_method + # end + # end + def process; raise CommandError, "command '#{command_name}' not implemented" end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/command_set.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/command_set.rb new file mode 100644 index 0000000..9483ab0 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/command_set.rb @@ -0,0 +1,443 @@ +class Pry + class NoCommandError < StandardError + def initialize(match, owner) + super "Command '#{match}' not found in command set #{owner}" + end + end + + # This class is used to create sets of commands. Commands can be imported from + # different sets, aliased, removed, etc. + class CommandSet + include Enumerable + include Pry::Helpers::BaseHelpers + attr_reader :helper_module + + # @param [Array] imported_sets + # Sets which will be imported automatically + # @yield Optional block run to define commands + def initialize(*imported_sets, &block) + @commands = {} + @helper_module = Module.new + import(*imported_sets) + instance_eval(&block) if block + end + + # Defines a new Pry command. + # @param [String, Regexp] match The start of invocations of this command. + # @param [String] description A description of the command. + # @param [Hash] options The optional configuration parameters. + # @option options [Boolean] :keep_retval Whether or not to use return value + # of the block for return of `command` or just to return `nil` + # (the default). + # @option options [Array] :requires_gem Whether the command has + # any gem dependencies, if it does and dependencies not met then + # command is disabled and a stub proc giving instructions to + # install command is provided. + # @option options [Boolean] :interpolate Whether string #{} based + # interpolation is applied to the command arguments before + # executing the command. Defaults to true. + # @option options [String] :listing The listing name of the + # command. That is the name by which the command is looked up by + # help and by show-command. Necessary for commands with regex matches. + # @option options [Boolean] :use_prefix Whether the command uses + # `Pry.config.command_prefix` prefix (if one is defined). Defaults + # to true. + # @option options [Boolean] :shellwords Whether the command's arguments + # should be split using Shellwords instead of just split on spaces. + # Defaults to true. + # @yield The action to perform. The parameters in the block + # determines the parameters the command will receive. All + # parameters passed into the block will be strings. Successive + # command parameters are separated by whitespace at the Pry prompt. + # @example + # MyCommands = Pry::CommandSet.new do + # command "greet", "Greet somebody" do |name| + # puts "Good afternoon #{name.capitalize}!" + # end + # end + # + # # From pry: + # # pry(main)> _pry_.commands = MyCommands + # # pry(main)> greet john + # # Good afternoon John! + # # pry(main)> help greet + # # Greet somebody + # @example Regexp command + # MyCommands = Pry::CommandSet.new do + # command /number-(\d+)/, "number-N regex command", :listing => "number" do |num, name| + # puts "hello #{name}, nice number: #{num}" + # end + # end + # + # # From pry: + # # pry(main)> _pry_.commands = MyCommands + # # pry(main)> number-10 john + # # hello john, nice number: 10 + # # pry(main)> help number + # # number-N regex command + def block_command(match, description="No description.", options={}, &block) + description, options = ["No description.", description] if description.is_a?(Hash) + options = Pry::Command.default_options(match).merge!(options) + + @commands[match] = Pry::BlockCommand.subclass(match, description, options, helper_module, &block) + end + alias_method :command, :block_command + + # Defines a new Pry command class. + # + # @param [String, Regexp] match The start of invocations of this command. + # @param [String] description A description of the command. + # @param [Hash] options The optional configuration parameters, see {#command} + # @yield The class body's definition. + # + # @example + # Pry::Commands.create_command "echo", "echo's the input", :shellwords => false do + # def options(opt) + # opt.banner "Usage: echo [-u | -d] " + # opt.on :u, :upcase, "ensure the output is all upper-case" + # opt.on :d, :downcase, "ensure the output is all lower-case" + # end + # + # def process + # raise Pry::CommandError, "-u and -d makes no sense" if opts.present?(:u) && opts.present?(:d) + # result = args.join(" ") + # result.downcase! if opts.present?(:downcase) + # result.upcase! if opts.present?(:upcase) + # output.puts result + # end + # end + # + def create_command(match, description="No description.", options={}, &block) + description, options = ["No description.", description] if description.is_a?(Hash) + options = Pry::Command.default_options(match).merge!(options) + + @commands[match] = Pry::ClassCommand.subclass(match, description, options, helper_module, &block) + @commands[match].class_eval(&block) + @commands[match] + end + + # Execute a block of code before a command is invoked. The block also + # gets access to parameters that will be passed to the command and + # is evaluated in the same context. + # @param [String, Regexp] search The match or listing of the command. + # @yield The block to be run before the command. + # @example Display parameter before invoking command + # Pry.config.commands.before_command("whereami") do |n| + # output.puts "parameter passed was #{n}" + # end + def before_command(search, &block) + cmd = find_command_by_match_or_listing(search) + cmd.hooks[:before].unshift block + end + + # Execute a block of code after a command is invoked. The block also + # gets access to parameters that will be passed to the command and + # is evaluated in the same context. + # @param [String, Regexp] search The match or listing of the command. + # @yield The block to be run after the command. + # @example Display text 'command complete' after invoking command + # Pry.config.commands.after_command("whereami") do |n| + # output.puts "command complete!" + # end + def after_command(search, &block) + cmd = find_command_by_match_or_listing(search) + cmd.hooks[:after] << block + end + + def each(&block) + @commands.each(&block) + end + + # Removes some commands from the set + # @param [Array] searches the matches or listings of the commands to remove + def delete(*searches) + searches.each do |search| + cmd = find_command_by_match_or_listing(search) + @commands.delete cmd.match + end + end + + # Imports all the commands from one or more sets. + # @param [Array] sets Command sets, all of the commands of which + # will be imported. + # @return [Pry::CommandSet] Returns the reciever (a command set). + def import(*sets) + sets.each do |set| + @commands.merge! set.to_hash + helper_module.send :include, set.helper_module + end + self + end + + # Imports some commands from a set + # @param [CommandSet] set Set to import commands from + # @param [Array] matches Commands to import + # @return [Pry::CommandSet] Returns the reciever (a command set). + def import_from(set, *matches) + helper_module.send :include, set.helper_module + matches.each do |match| + cmd = set.find_command_by_match_or_listing(match) + @commands[cmd.match] = cmd + end + self + end + + # @param [String, Regexp] match_or_listing The match or listing of a command. + # of the command to retrieve. + # @return [Command] The command object matched. + def find_command_by_match_or_listing(match_or_listing) + cmd = (@commands[match_or_listing] || + Pry::Helpers::BaseHelpers.find_command(match_or_listing, @commands)) + cmd or raise ArgumentError, "Cannot find a command: '#{match_or_listing}'!" + end + + # Aliases a command + # @param [String, Regex] match The match of the alias (can be a regex). + # @param [String] action The action to be performed (typically + # another command). + # @param [Hash] options The optional configuration parameters, + # accepts the same as the `command` method, but also allows the + # command description to be passed this way too as `:desc` + # @example Creating an alias for `ls -M` + # Pry.config.commands.alias_command "lM", "ls -M" + # @example Pass explicit description (overriding default). + # Pry.config.commands.alias_command "lM", "ls -M", :desc => "cutiepie" + def alias_command(match, action, options={}) + cmd = find_command(action) or fail "Command: `#{action}` not found" + original_options = cmd.options.dup + + options = original_options.merge!({ + :desc => "Alias for `#{action}`", + :listing => match + }).merge!(options) + + # ensure default description is used if desc is nil + desc = options.delete(:desc).to_s + + c = block_command match, desc, options do |*args| + run action, *args + end + + c.class_eval do + define_method(:complete) do |input| + cmd.new(context).complete(input) + end + end + + c.group "Aliases" + + c + end + + # Rename a command. Accepts either match or listing for the search. + # + # @param [String, Regexp] new_match The new match for the command. + # @param [String, Regexp] search The command's current match or listing. + # @param [Hash] options The optional configuration parameters, + # accepts the same as the `command` method, but also allows the + # command description to be passed this way too. + # @example Renaming the `ls` command and changing its description. + # Pry.config.commands.rename "dir", "ls", :description => "DOS friendly ls" + def rename_command(new_match, search, options={}) + cmd = find_command_by_match_or_listing(search) + + options = { + :listing => new_match, + :description => cmd.description + }.merge!(options) + + @commands[new_match] = cmd.dup + @commands[new_match].match = new_match + @commands[new_match].description = options.delete(:description) + @commands[new_match].options.merge!(options) + @commands.delete(cmd.match) + end + + def disabled_command(name_of_disabled_command, message, matcher=name_of_disabled_command) + create_command name_of_disabled_command do + match matcher + description "" + + define_method(:process) do + output.puts "DISABLED: #{message}" + end + end + end + + # Sets or gets the description for a command (replacing the old + # description). Returns current description if no description + # parameter provided. + # @param [String, Regexp] search The command match. + # @param [String?] description (nil) The command description. + # @example Setting + # MyCommands = Pry::CommandSet.new do + # desc "help", "help description" + # end + # @example Getting + # Pry.config.commands.desc "amend-line" + def desc(search, description=nil) + cmd = find_command_by_match_or_listing(search) + return cmd.description if !description + + cmd.description = description + end + + # Defines helpers methods for this command sets. + # Those helpers are only defined in this command set. + # + # @yield A block defining helper methods + # @example + # helpers do + # def hello + # puts "Hello!" + # end + # + # include OtherModule + # end + def helpers(&block) + helper_module.class_eval(&block) + end + + + # @return [Array] + # The list of commands provided by the command set. + def list_commands + @commands.keys + end + alias_method :keys, :list_commands + + def to_hash + @commands.dup + end + alias_method :to_h, :to_hash + + # Find a command that matches the given line + # @param [String] pattern The line that might be a command invocation + # @return [Pry::Command, nil] + def [](pattern) + @commands.values.select do |command| + command.matches?(pattern) + end.sort_by do |command| + command.match_score(pattern) + end.last + end + alias_method :find_command, :[] + + # + # Re-assign the command found at _pattern_ with _command_. + # + # @param [Regexp, String] pattern + # The command to add or replace(found at _pattern_). + # + # @param [Pry::Command] command + # The command to add. + # + # @return [Pry::Command] + # Returns the new command (matched with "pattern".) + # + # @example + # Pry.config.commands["help"] = MyHelpCommand + # + def []=(pattern, command) + if command.equal?(nil) + return @commands.delete(pattern) + end + unless Class === command && command < Pry::Command + raise TypeError, "command is not a subclass of Pry::Command" + end + bind_command_to_pattern = pattern != command.match + if bind_command_to_pattern + command_copy = command.dup + command_copy.match = pattern + @commands[pattern] = command_copy + else + @commands[pattern] = command + end + end + + # + # Add a command to set. + # + # @param [Command] command + # a subclass of Pry::Command. + # + def add_command(command) + self[command.match] = command + end + + # Find the command that the user might be trying to refer to. + # @param [String] search The user's search. + # @return [Pry::Command?] + def find_command_for_help(search) + find_command(search) || (begin + find_command_by_match_or_listing(search) + rescue ArgumentError + nil + end) + end + + # Is the given line a command invocation? + # @param [String] val + # @return [Boolean] + def valid_command?(val) + !!find_command(val) + end + + # Process the given line to see whether it needs executing as a command. + # @param [String] val The line to execute + # @param [Hash] context The context to execute the commands with + # @return [CommandSet::Result] + def process_line(val, context={}) + if command = find_command(val) + context = context.merge(:command_set => self) + retval = command.new(context).process_line(val) + Result.new(true, retval) + else + Result.new(false) + end + end + + # @private (used for testing) + def run_command(context, match, *args) + command = @commands[match] or raise NoCommandError.new(match, self) + command.new(context).call_safely(*args) + end + + # Generate completions for the user's search. + # @param [String] search The line to search for + # @param [Hash] context The context to create the command with + # @return [Array] + def complete(search, context={}) + if command = find_command(search) + command.new(context).complete(search) + else + @commands.keys.select do |key| + String === key && key.start_with?(search) + end.map{ |key| key + " " } + end + end + end + + # Wraps the return result of process_commands, indicates if the + # result IS a command and what kind of command (e.g void) + class Result + attr_reader :retval + + def initialize(is_command, retval = nil) + @is_command, @retval = is_command, retval + end + + # Is the result a command? + # @return [Boolean] + def command? + @is_command + end + + # Is the result a command and if it is, is it a void command? + # (one that does not return a value) + # @return [Boolean] + def void_command? + retval == Command::VOID_VALUE + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands.rb new file mode 100644 index 0000000..4b85ada --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands.rb @@ -0,0 +1,6 @@ +# Default commands used by Pry. +Pry::Commands = Pry::CommandSet.new + +Dir[File.expand_path('../commands', __FILE__) << '/*.rb'].each do |file| + require file +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/amend_line.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/amend_line.rb new file mode 100644 index 0000000..d30c9a0 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/amend_line.rb @@ -0,0 +1,99 @@ +class Pry + class Command::AmendLine < Pry::ClassCommand + match(/amend-line(?: (-?\d+)(?:\.\.(-?\d+))?)?/) + group 'Editing' + description 'Amend a line of input in multi-line mode.' + command_options :interpolate => false, :listing => 'amend-line' + + banner <<-'BANNER' + Amend a line of input in multi-line mode. `amend-line N`, where the N represents + line to replace. Can also specify a range of lines using `amend-line N..M` + syntax. Passing "!" as replacement content deletes the line(s) instead. + + amend-line 1 puts 'new' # replace line 1 + amend-line 1..4 ! # delete lines 1..4 + amend-line 3 >puts 'bye' # insert before line 3 + amend-line puts 'appended' # no line number modifies immediately preceding line + BANNER + + def process + raise CommandError, "No input to amend." if eval_string.empty? + + eval_string.replace amended_input(eval_string) + run "fix-indent" + run "show-input" + end + + private + + # @param [String] string The string to amend. + # @return [String] A new string with the amendments applied to it. + def amended_input(string) + input_array = eval_string.each_line.to_a + + if arg_string == "!" + delete_from_array(input_array, line_range) + elsif arg_string.start_with?(">") + insert_into_array(input_array, line_range) + else + replace_in_array(input_array, line_range) + end + + input_array.join + end + + def delete_from_array(array, range) + array.slice!(range) + end + + def insert_into_array(array, range) + insert_slot = Array(range).first + array.insert(insert_slot, arg_string[1..-1] << "\n") + end + + def replace_in_array(array, range) + array[range] = arg_string + "\n" + end + + # @return [Fixnum] The number of lines currently in `eval_string` (the input buffer). + def line_count + eval_string.lines.count + end + + # Returns the (one-indexed) start and end lines given by the user. + # The lines in this range will be affected by the `amend-line`. + # Returns `nil` if no lines were specified by the user. + # @return [Array, nil] + def start_and_end_line_number + start_line_number, end_line_number = args + end_line_number ||= start_line_number.to_i + + [start_line_number.to_i, end_line_number.to_i] if start_line_number + end + + # Takes two numbers that are 1-indexed, and returns a range (or + # number) that is 0-indexed. 1-indexed means the first element is + # indentified by 1 rather than by 0 (as is the case for Ruby arrays). + # @param [Fixnum] start_line_number One-indexed number. + # @param [Fixnum] end_line_number One-indexed number. + # @return [Range] The zero-indexed range. + def zero_indexed_range_from_one_indexed_numbers(start_line_number, end_line_number) + # FIXME: one_index_number is a horrible name for this method + one_index_number(start_line_number)..one_index_number(end_line_number) + end + + # The lines (or line) that will be modified by the `amend-line`. + # @return [Range, Fixnum] The lines or line. + def line_range + start_line_number, end_line_number = start_and_end_line_number + if start_line_number + zero_indexed_range_from_one_indexed_numbers(start_line_number, + end_line_number) + else + line_count - 1 + end + end + end + + Pry::Commands.add_command(Pry::Command::AmendLine) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang.rb new file mode 100644 index 0000000..117835e --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang.rb @@ -0,0 +1,20 @@ +class Pry + class Command::Bang < Pry::ClassCommand + match /^\s*!\s*$/ + group 'Editing' + description 'Clear the input buffer.' + command_options :use_prefix => false + + banner <<-'BANNER' + Clear the input buffer. Useful if the parsing process goes wrong and you get + stuck in the read loop. + BANNER + + def process + output.puts 'Input buffer cleared!' + eval_string.replace('') + end + end + + Pry::Commands.add_command(Pry::Command::Bang) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang_pry.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang_pry.rb new file mode 100644 index 0000000..71f81ef --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang_pry.rb @@ -0,0 +1,17 @@ +class Pry + class Command::BangPry < Pry::ClassCommand + match '!pry' + group 'Navigating Pry' + description 'Start a Pry session on current self.' + + banner <<-'BANNER' + Start a Pry session on current self. Also works mid multi-line expression. + BANNER + + def process + target.pry + end + end + + Pry::Commands.add_command(Pry::Command::BangPry) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat.rb new file mode 100644 index 0000000..8ca537f --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat.rb @@ -0,0 +1,62 @@ +class Pry + class Command::Cat < Pry::ClassCommand + require 'pry/commands/cat/abstract_formatter.rb' + require 'pry/commands/cat/input_expression_formatter.rb' + require 'pry/commands/cat/exception_formatter.rb' + require 'pry/commands/cat/file_formatter.rb' + + match 'cat' + group 'Input and Output' + description "Show code from a file, Pry's input buffer, or the last exception." + + banner <<-'BANNER' + Usage: cat FILE + cat --ex [STACK_INDEX] + cat --in [INPUT_INDEX_OR_RANGE] + + `cat` is capable of showing part or all of a source file, the context of the + last exception, or an expression from Pry's input history. + + `cat --ex` defaults to showing the lines surrounding the location of the last + exception. Invoking it more than once travels up the exception's backtrace, and + providing a number shows the context of the given index of the backtrace. + BANNER + + def options(opt) + opt.on :ex, "Show the context of the last exception", :optional_argument => true, :as => Integer + opt.on :i, :in, "Show one or more entries from Pry's expression history", :optional_argument => true, :as => Range, :default => -5..-1 + opt.on :s, :start, "Starting line (defaults to the first line)", :optional_argument => true, :as => Integer + opt.on :e, :end, "Ending line (defaults to the last line)", :optional_argument => true, :as => Integer + opt.on :l, :'line-numbers', "Show line numbers" + opt.on :t, :type, "The file type for syntax highlighting (e.g., 'ruby' or 'python')", :argument => true, :as => Symbol + end + + def process + output = case + when opts.present?(:ex) + ExceptionFormatter.new(_pry_.last_exception, _pry_, opts).format + when opts.present?(:in) + InputExpressionFormatter.new(_pry_.input_array, opts).format + else + FileFormatter.new(args.first, _pry_, opts).format + end + + _pry_.pager.page output + end + + def complete(search) + super | load_path_completions + end + + def load_path_completions + $LOAD_PATH.flat_map do |path| + Dir[path + '/**/*'].map { |f| + next if File.directory?(f) + f.sub!(path + '/', '') + } + end + end + end + + Pry::Commands.add_command(Pry::Command::Cat) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/abstract_formatter.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/abstract_formatter.rb new file mode 100644 index 0000000..661f036 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/abstract_formatter.rb @@ -0,0 +1,27 @@ +class Pry + class Command::Cat + class AbstractFormatter + include Pry::Helpers::CommandHelpers + include Pry::Helpers::BaseHelpers + + private + def decorate(content) + content.code_type = code_type + content.between(*between_lines). + with_line_numbers(use_line_numbers?) + end + + def code_type + opts[:type] || :ruby + end + + def use_line_numbers? + opts.present?(:'line-numbers') || opts.present?(:ex) + end + + def between_lines + [opts[:start] || 1, opts[:end] || -1] + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/exception_formatter.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/exception_formatter.rb new file mode 100644 index 0000000..af10e9d --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/exception_formatter.rb @@ -0,0 +1,77 @@ +class Pry + class Command::Cat + class ExceptionFormatter < AbstractFormatter + attr_reader :ex + attr_reader :opts + attr_reader :_pry_ + + def initialize(exception, _pry_, opts) + @ex = exception + @opts = opts + @_pry_ = _pry_ + end + + def format + check_for_errors + set_file_and_dir_locals(backtrace_file, _pry_, _pry_.current_context) + code = decorate(Pry::Code.from_file(backtrace_file). + between(*start_and_end_line_for_code_window). + with_marker(backtrace_line)) + "#{header}#{code}" + end + + private + + def code_window_size + _pry_.config.default_window_size || 5 + end + + def backtrace_level + return @backtrace_level if @backtrace_level + + bl = if opts[:ex].nil? + ex.bt_index + else + ex.bt_index = absolute_index_number(opts[:ex], ex.backtrace.size) + end + + increment_backtrace_level + @backtrace_level = bl + end + + def increment_backtrace_level + ex.inc_bt_index + end + + def backtrace_file + Array(ex.bt_source_location_for(backtrace_level)).first + end + + def backtrace_line + Array(ex.bt_source_location_for(backtrace_level)).last + end + + def check_for_errors + raise CommandError, "No exception found." unless ex + raise CommandError, "The given backtrace level is out of bounds." unless backtrace_file + end + + def start_and_end_line_for_code_window + start_line = backtrace_line - code_window_size + start_line = 1 if start_line < 1 + + [start_line, backtrace_line + code_window_size] + end + + def header + unindent %{ + #{Helpers::Text.bold 'Exception:'} #{ex.class}: #{ex.message} + -- + #{Helpers::Text.bold('From:')} #{backtrace_file} @ line #{backtrace_line} @ #{Helpers::Text.bold("level: #{backtrace_level}")} of backtrace (of #{ex.backtrace.size - 1}). + + } + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/file_formatter.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/file_formatter.rb new file mode 100644 index 0000000..92c6268 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/file_formatter.rb @@ -0,0 +1,67 @@ +class Pry + class Command::Cat + class FileFormatter < AbstractFormatter + attr_reader :file_with_embedded_line + attr_reader :opts + attr_reader :_pry_ + + def initialize(file_with_embedded_line, _pry_, opts) + @file_with_embedded_line = file_with_embedded_line + @opts = opts + @_pry_ = _pry_ + @code_from_file = Pry::Code.from_file(file_name) + end + + def format + raise CommandError, "Must provide a filename, --in, or --ex." if !file_with_embedded_line + + set_file_and_dir_locals(file_name, _pry_, _pry_.current_context) + decorate(@code_from_file) + end + + def file_and_line + file_name, line_num = file_with_embedded_line.split(/:(?!\/|\\)/) + + [file_name, line_num ? line_num.to_i : nil] + end + + private + + def file_name + file_and_line.first + end + + def line_number + file_and_line.last + end + + def code_window_size + _pry_.config.default_window_size || 7 + end + + def decorate(content) + line_number ? super.around(line_number, code_window_size) : super + end + + def code_type + opts[:type] || detect_code_type_from_file(file_name) + end + + def detect_code_type_from_file(file_name) + code_type = @code_from_file.code_type + + if code_type == :unknown + name, ext = File.basename(file_name).split('.', 2) + case name + when "Rakefile", "Gemfile" + :ruby + else + :text + end + else + code_type + end + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/input_expression_formatter.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/input_expression_formatter.rb new file mode 100644 index 0000000..8791ac3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/input_expression_formatter.rb @@ -0,0 +1,43 @@ +class Pry + class Command::Cat + class InputExpressionFormatter < AbstractFormatter + attr_accessor :input_expressions + attr_accessor :opts + + def initialize(input_expressions, opts) + @input_expressions = input_expressions + @opts = opts + end + + def format + raise CommandError, "No input expressions!" if numbered_input_items.length < 1 + + if numbered_input_items.length > 1 + content = "" + numbered_input_items.each do |i, s| + content << "#{Helpers::Text.bold(i.to_s)}:\n" << decorate(Pry::Code(s).with_indentation(2)).to_s + end + + content + else + decorate(Pry::Code(selected_input_items.first)) + end + end + + private + + def selected_input_items + input_expressions[normalized_expression_range] || [] + end + + def numbered_input_items + @numbered_input_items ||= normalized_expression_range.zip(selected_input_items). + reject { |_, s| s.nil? || s == "" } + end + + def normalized_expression_range + absolute_index_range(opts[:i], input_expressions.length) + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cd.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cd.rb new file mode 100644 index 0000000..667453a --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cd.rb @@ -0,0 +1,41 @@ +class Pry + class Command::Cd < Pry::ClassCommand + match 'cd' + group 'Context' + description 'Move into a new context (object or scope).' + + banner <<-'BANNER' + Usage: cd [OPTIONS] [--help] + + Move into new context (object or scope). As in UNIX shells use `cd ..` to go + back, `cd /` to return to Pry top-level and `cd -` to toggle between last two + scopes. Complex syntax (e.g `cd ../@x/@y`) also supported. + + cd @x + cd .. + cd / + cd - + + https://github.com/pry/pry/wiki/State-navigation#wiki-Changing_scope + BANNER + + def process + state.old_stack ||= [] + + if arg_string.strip == "-" + unless state.old_stack.empty? + _pry_.binding_stack, state.old_stack = state.old_stack, _pry_.binding_stack + end + else + stack = ObjectPath.new(arg_string, _pry_.binding_stack).resolve + + if stack && stack != _pry_.binding_stack + state.old_stack = _pry_.binding_stack + _pry_.binding_stack = stack + end + end + end + end + + Pry::Commands.add_command(Pry::Command::Cd) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_inspector.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_inspector.rb new file mode 100644 index 0000000..183dec4 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_inspector.rb @@ -0,0 +1,27 @@ +class Pry::Command::ChangeInspector < Pry::ClassCommand + match 'change-inspector' + group 'Input and Output' + description 'Change the current inspector proc.' + command_options argument_required: true + banner <<-BANNER + Usage: change-inspector NAME + + Change the proc used to print return values. See list-inspectors for a list + of available procs and a short description of what each one does. + BANNER + + def process(inspector) + if inspector_map.key?(inspector) + _pry_.print = inspector_map[inspector][:value] + output.puts "Switched to the '#{inspector}' inspector!" + else + raise Pry::CommandError, "'#{inspector}' isn't a known inspector!" + end + end + +private + def inspector_map + Pry::Inspector::MAP + end + Pry::Commands.add_command(self) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_prompt.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_prompt.rb new file mode 100644 index 0000000..13d36cb --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_prompt.rb @@ -0,0 +1,26 @@ +class Pry::Command::ChangePrompt < Pry::ClassCommand + match 'change-prompt' + group 'Input and Output' + description 'Change the current prompt.' + command_options argument_required: true + banner <<-BANNER + Usage: change-prompt NAME + + Change the current prompt. See list-prompts for a list of available + prompts. + BANNER + + def process(prompt) + if prompt_map.key?(prompt) + _pry_.prompt = prompt_map[prompt][:value] + else + raise Pry::CommandError, "'#{prompt}' isn't a known prompt!" + end + end + +private + def prompt_map + Pry::Prompt::MAP + end + Pry::Commands.add_command(self) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/code_collector.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/code_collector.rb new file mode 100644 index 0000000..72e8181 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/code_collector.rb @@ -0,0 +1,165 @@ +class Pry + class Command::CodeCollector + include Helpers::CommandHelpers + + attr_reader :args + attr_reader :opts + attr_reader :_pry_ + + # The name of the explicitly given file (if any). + attr_accessor :file + + class << self + attr_accessor :input_expression_ranges + attr_accessor :output_result_ranges + end + + @input_expression_ranges = [] + @output_result_ranges = [] + + def initialize(args, opts, _pry_) + @args = args + @opts = opts + @_pry_ = _pry_ + end + + # Add the `--lines`, `-o`, `-i`, `-s`, `-d` options. + def self.inject_options(opt) + @input_expression_ranges = [] + @output_result_ranges = [] + + opt.on :l, :lines, "Restrict to a subset of lines. Takes a line number or range", + :optional_argument => true, :as => Range, :default => 1..-1 + opt.on :o, :out, "Select lines from Pry's output result history. Takes an index or range", + :optional_argument => true, :as => Range, :default => -5..-1 do |r| + output_result_ranges << (r || (-5..-1)) + end + opt.on :i, :in, "Select lines from Pry's input expression history. Takes an index or range", + :optional_argument => true, :as => Range, :default => -5..-1 do |r| + input_expression_ranges << (r || (-5..-1)) + end + opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors", + :as => :count + opt.on :d, :doc, "Select lines from the code object's documentation" + end + + # The content (i.e code/docs) for the selected object. + # If the user provided a bare code object, it returns the source. + # If the user provided the `-i` or `-o` switches, it returns the + # selected input/output lines joined as a string. If the user used + # `-d CODE_OBJECT` it returns the docs for that code object. + # + # @return [String] + def content + return @content if @content + raise CommandError, "Only one of --out, --in, --doc and CODE_OBJECT may be specified." if bad_option_combination? + + content = case + when opts.present?(:o) + pry_output_content + when opts.present?(:i) + pry_input_content + when opts.present?(:d) + code_object_doc + else + code_object_source_or_file + end + + @content ||= restrict_to_lines(content, line_range) + end + + # The code object + # + # @return [Pry::WrappedModule, Pry::Method, Pry::Command] + def code_object + Pry::CodeObject.lookup(obj_name, _pry_, :super => opts[:super]) + end + + # Given a string and a range, return the `range` lines of that + # string. + # + # @param [String] content + # @param [Range, Fixnum] range + # @return [String] The string restricted to the given range + def restrict_to_lines(content, range) + Array(content.lines.to_a[range]).join + end + + # The selected `_pry_.output_array` as a string, as specified by + # the `-o` switch. + # + # @return [String] + def pry_output_content + pry_array_content_as_string(_pry_.output_array, self.class.output_result_ranges) do |v| + _pry_.config.gist.inspecter.call(v) + end + end + + # The selected `_pry_.input_array` as a string, as specified by + # the `-i` switch. + # + # @return [String] + def pry_input_content + pry_array_content_as_string(_pry_.input_array, self.class.input_expression_ranges) { |v| v } + end + + # The line range passed to `--lines`, converted to a 0-indexed range. + def line_range + opts.present?(:lines) ? one_index_range_or_number(opts[:lines]) : 0..-1 + end + + # Name of the object argument + def obj_name + @obj_name ||= args.empty? ? "" : args.join(" ") + end + + private + + def bad_option_combination? + [opts.present?(:in), opts.present?(:out), + !args.empty?].count(true) > 1 + end + + def pry_array_content_as_string(array, ranges, &block) + all = '' + ranges.each do |range| + raise CommandError, "Minimum value for range is 1, not 0." if convert_to_range(range).first == 0 + + ranged_array = Array(array[range]) || [] + ranged_array.compact.each { |v| all << block.call(v) } + end + + all + end + + def code_object_doc + (code_object && code_object.doc) or could_not_locate(obj_name) + end + + def code_object_source_or_file + (code_object && code_object.source) || file_content + end + + def file_content + if File.exists?(obj_name) + # Set the file accessor. + self.file = obj_name + File.read(obj_name) + else + could_not_locate(obj_name) + end + end + + def could_not_locate(name) + raise CommandError, "Cannot locate: #{name}!" + end + + def convert_to_range(n) + if !n.is_a?(Range) + (n..n) + else + n + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disable_pry.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disable_pry.rb new file mode 100644 index 0000000..69bfc4e --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disable_pry.rb @@ -0,0 +1,27 @@ +class Pry + class Command::DisablePry < Pry::ClassCommand + match 'disable-pry' + group 'Navigating Pry' + description 'Stops all future calls to pry and exits the current session.' + + banner <<-'BANNER' + Usage: disable-pry + + After this command is run any further calls to pry will immediately return `nil` + without interrupting the flow of your program. This is particularly useful when + you've debugged the problem you were having, and now wish the program to run to + the end. + + As alternatives, consider using `exit!` to force the current Ruby process + to quit immediately; or using `edit-method -p` to remove the `binding.pry` + from the code. + BANNER + + def process + ENV['DISABLE_PRY'] = 'true' + _pry_.run_command "exit" + end + end + + Pry::Commands.add_command(Pry::Command::DisablePry) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disabled_commands.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disabled_commands.rb new file mode 100644 index 0000000..9866f90 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disabled_commands.rb @@ -0,0 +1,2 @@ +Pry::Commands.disabled_command("edit-method", "Use `edit` instead.") +Pry::Commands.disabled_command("show-command", "Use show-source [command_name] instead.") diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/easter_eggs.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/easter_eggs.rb new file mode 100644 index 0000000..84a97df --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/easter_eggs.rb @@ -0,0 +1,112 @@ +class Pry + Pry::Commands.instance_eval do + command "nyan-cat", "", :requires_gem => ["nyancat"] do + run ".nyancat" + end + + command(/!s\/(.*?)\/(.*?)/, "") do |source, dest| + eval_string.gsub!(/#{source}/) { dest } + run "show-input" + end + + command "get-naked", "" do + text = %{ + -- + We dont have to take our clothes off to have a good time. + We could dance & party all night And drink some cherry wine. + -- Jermaine Stewart } + output.puts text + text + end + + command "east-coker", "" do + text = %{ + -- + Now the light falls + Across the open field, leaving the deep lane + Shuttered with branches, dark in the afternoon, + Where you lean against a bank while a van passes, + And the deep lane insists on the direction + Into the village, in the electric heat + Hypnotised. In a warm haze the sultry light + Is absorbed, not refracted, by grey stone. + The dahlias sleep in the empty silence. + Wait for the early owl. + -- T.S Eliot + } + output.puts text + text + end + + command "cohen-poem", "" do + text = %{ + -- + When this American woman, + whose thighs are bound in casual red cloth, + comes thundering past my sitting place + like a forest-burning Mongol tribe, + the city is ravished + and brittle buildings of a hundred years + splash into the street; + and my eyes are burnt + for the embroidered Chinese girls, + already old, + and so small between the thin pines + on these enormous landscapes, + that if you turn your head + they are lost for hours. + -- Leonard Cohen + } + output.puts text + text + end + + command "pessoa-poem", "" do + output.puts <<-TEXT + -- + I've gone to bed with every feeling, + I've been the pimp of every emotion, + All felt sensations have bought me drinks, + I've traded glances with every motive for every act, + I've held hands with every urge to depart, + .. + Rage, foam, the vastness that doesn't fit in my handkerchief, + The dog in heat howling in the night, + The pond from the farm going in circles around my insomnia, + The woods as they were, on our late-afternoon walks, the rose, + The indifferent tuft of hair, the moss, the pines, + The rage of not containing all this, not retaining all this, + O abstract hunger for things, impotent libido for moments, + Intellectual orgy of feeling life! + -- Fernando Pessoa +TEXT + end + + command "test-ansi", "" do + prev_color = _pry_.config.color + _pry_.config.color = true + + picture = unindent <<-'EOS'.gsub(/[[:alpha:]!]/) { |s| text.red(s) } + ____ _______________________ + / \ | A W G | + / O O \ | N I O N ! | + | | | S S R I ! | + \ \__/ / __| I K ! | + \____/ \________________________| + EOS + + if windows_ansi? + move_up = proc { |n| "\e[#{n}F" } + else + move_up = proc { |n| "\e[#{n}A\e[0G" } + end + + output.puts "\n" * 6 + output.puts picture.lines.map(&:chomp).reverse.join(move_up[1]) + output.puts "\n" * 6 + output.puts "** ENV['TERM'] is #{ENV['TERM']} **\n\n" + + _pry_.config.color = prev_color + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit.rb new file mode 100644 index 0000000..cf2cc1c --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit.rb @@ -0,0 +1,195 @@ +class Pry + class Command::Edit < Pry::ClassCommand + require 'pry/commands/edit/exception_patcher' + require 'pry/commands/edit/file_and_line_locator' + + match 'edit' + group 'Editing' + description 'Invoke the default editor on a file.' + + banner <<-'BANNER' + Usage: edit [--no-reload|--reload|--patch] [--line LINE] [--temp|--ex|FILE[:LINE]|OBJECT|--in N] + + Open a text editor. When no FILE is given, edits the pry input buffer. + When a method/module/command is given, the code is opened in an editor. + Ensure `Pry.config.editor` or `_pry_.config.editor` is set to your editor of choice. + + edit sample.rb edit -p MyClass#my_method + edit sample.rb --line 105 edit MyClass + edit MyClass#my_method edit --ex + edit --method edit --ex -p + + https://github.com/pry/pry/wiki/Editor-integration#wiki-Edit_command + BANNER + + def options(opt) + opt.on :e, :ex, "Open the file that raised the most recent exception (_ex_.file)", + :optional_argument => true, :as => Integer + opt.on :i, :in, "Open a temporary file containing the Nth input expression. N may be a range", + :optional_argument => true, :as => Range, :default => -1..-1 + opt.on :t, :temp, "Open an empty temporary file" + opt.on :l, :line, "Jump to this line in the opened file", + :argument => true, :as => Integer + opt.on :n, :"no-reload", "Don't automatically reload the edited file" + opt.on :c, :current, "Open the current __FILE__ and at __LINE__ (as returned by `whereami`)" + opt.on :r, :reload, "Reload the edited code immediately (default for ruby files)" + opt.on :p, :patch, "Instead of editing the object's file, try to edit in a tempfile and apply as a monkey patch" + opt.on :m, :method, "Explicitly edit the _current_ method (when inside a method context)." + end + + def process + if bad_option_combination? + raise CommandError, "Only one of --ex, --temp, --in, --method and FILE may be specified." + end + + if repl_edit? + # code defined in pry, eval'd within pry. + repl_edit + elsif runtime_patch? + # patch code without persisting changes + apply_runtime_patch + else + # code stored in actual files, eval'd at top-level + file_edit + end + end + + def repl_edit? + !opts.present?(:ex) && !opts.present?(:current) && !opts.present?(:method) && + filename_argument.empty? + end + + def repl_edit + content = Pry::Editor.new(_pry_).edit_tempfile_with_content(initial_temp_file_content, + initial_temp_file_content.lines.count) + silence_warnings do + eval_string.replace content + end + end + + def file_based_exception? + opts.present?(:ex) && !opts.present?(:patch) + end + + def runtime_patch? + !file_based_exception? && (opts.present?(:patch) || pry_method?(code_object)) + end + + def apply_runtime_patch + if patch_exception? + ExceptionPatcher.new(_pry_, state, file_and_line_for_current_exception).perform_patch + else + if code_object.is_a?(Pry::Method) + code_object.redefine Pry::Editor.new(_pry_).edit_tempfile_with_content(code_object.source) + else + raise NotImplementedError, "Cannot yet patch #{code_object} objects!" + end + end + end + + def ensure_file_name_is_valid(file_name) + raise CommandError, "Cannot find a valid file for #{filename_argument}" if !file_name + raise CommandError, "#{file_name} is not a valid file name, cannot edit!" if not_a_real_file?(file_name) + end + + def file_and_line_for_current_exception + FileAndLineLocator.from_exception(_pry_.last_exception, opts[:ex].to_i) + end + + def file_and_line + file_name, line = if opts.present?(:current) + FileAndLineLocator.from_binding(target) + elsif opts.present?(:ex) + file_and_line_for_current_exception + elsif code_object + FileAndLineLocator.from_code_object(code_object, filename_argument) + else + # when file and line are passed as a single arg, e.g my_file.rb:30 + FileAndLineLocator.from_filename_argument(filename_argument) + end + + [file_name, opts.present?(:line) ? opts[:l].to_i : line] + end + + def file_edit + file_name, line = file_and_line + + ensure_file_name_is_valid(file_name) + + Pry::Editor.new(_pry_).invoke_editor(file_name, line, reload?(file_name)) + set_file_and_dir_locals(file_name) + + if reload?(file_name) + silence_warnings do + load file_name + end + end + end + + def filename_argument + args.join(' ') + end + + def code_object + @code_object ||= !probably_a_file?(filename_argument) && + Pry::CodeObject.lookup(filename_argument, _pry_) + end + + def pry_method?(code_object) + code_object.is_a?(Pry::Method) && + code_object.pry_method? + end + + def patch_exception? + opts.present?(:ex) && opts.present?(:patch) + end + + def bad_option_combination? + [opts.present?(:ex), opts.present?(:temp), + opts.present?(:in), opts.present?(:method), !filename_argument.empty?].count(true) > 1 + end + + def input_expression + case opts[:i] + when Range + (_pry_.input_array[opts[:i]] || []).join + when Fixnum + _pry_.input_array[opts[:i]] || "" + else + raise Pry::CommandError, "Not a valid range: #{opts[:i]}" + end + end + + def reloadable? + opts.present?(:reload) || opts.present?(:ex) + end + + def never_reload? + opts.present?(:'no-reload') || _pry_.config.disable_auto_reload + end + + def reload?(file_name="") + (reloadable? || file_name.end_with?(".rb")) && !never_reload? + end + + def initial_temp_file_content + case + when opts.present?(:temp) + "" + when opts.present?(:in) + input_expression + when eval_string.strip != "" + eval_string + else + _pry_.input_array.reverse_each.find { |x| x && x.strip != "" } || "" + end + end + + def probably_a_file?(str) + [".rb", ".c", ".py", ".yml", ".gemspec"].include?(File.extname(str)) || + str =~ /\/|\\/ + end + end + + Pry::Commands.add_command(Pry::Command::Edit) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/exception_patcher.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/exception_patcher.rb new file mode 100644 index 0000000..07e13bc --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/exception_patcher.rb @@ -0,0 +1,25 @@ +class Pry + class Command::Edit + class ExceptionPatcher + attr_accessor :_pry_ + attr_accessor :state + attr_accessor :file_and_line + + def initialize(_pry_, state, exception_file_and_line) + @_pry_ = _pry_ + @state = state + @file_and_line = exception_file_and_line + end + + # perform the patch + def perform_patch + file_name, _ = file_and_line + lines = state.dynamical_ex_file || File.read(file_name) + + source = Pry::Editor.new(_pry_).edit_tempfile_with_content(lines) + _pry_.evaluate_ruby source + state.dynamical_ex_file = source.split("\n") + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/file_and_line_locator.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/file_and_line_locator.rb new file mode 100644 index 0000000..5f712f3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/file_and_line_locator.rb @@ -0,0 +1,36 @@ +class Pry + class Command::Edit + module FileAndLineLocator + class << self + def from_binding(target) + [target.eval("__FILE__"), target.eval("__LINE__")] + end + + def from_code_object(code_object, filename_argument) + if File.exists?(code_object.source_file.to_s) + [code_object.source_file, code_object.source_line] + else + raise CommandError, "Cannot find a file for #{filename_argument}!" + end + end + + def from_exception(exception, backtrace_level) + raise CommandError, "No exception found." if exception.nil? + + file_name, line = exception.bt_source_location_for(backtrace_level) + raise CommandError, "Exception has no associated file." if file_name.nil? + raise CommandError, "Cannot edit exceptions raised in REPL." if Pry.eval_path == file_name + + [file_name, line] + end + + # when file and line are passed as a single arg, e.g my_file.rb:30 + def from_filename_argument(filename_argument) + f = File.expand_path(filename_argument) + l = f.sub!(/:(\d+)$/, "") ? $1.to_i : 1 + [f, l] + end + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit.rb new file mode 100644 index 0000000..32c0c2e --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit.rb @@ -0,0 +1,42 @@ +class Pry + class Command::Exit < Pry::ClassCommand + match 'exit' + group 'Navigating Pry' + description 'Pop the previous binding.' + command_options :keep_retval => true + + banner <<-'BANNER' + Usage: exit [OPTIONS] [--help] + Aliases: quit + + Pop the previous binding (does NOT exit program). It can be useful to exit a + context with a user-provided value. For instance an exit value can be used to + determine program flow. + + exit "pry this" + exit + + https://github.com/pry/pry/wiki/State-navigation#wiki-Exit_with_value + BANNER + + def process + if _pry_.binding_stack.one? + _pry_.run_command "exit-all #{arg_string}" + else + # otherwise just pop a binding and return user supplied value + process_pop_and_return + end + end + + def process_pop_and_return + popped_object = _pry_.binding_stack.pop.eval('self') + + # return a user-specified value if given otherwise return the object + return target.eval(arg_string) unless arg_string.empty? + popped_object + end + end + + Pry::Commands.add_command(Pry::Command::Exit) + Pry::Commands.alias_command 'quit', 'exit' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_all.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_all.rb new file mode 100644 index 0000000..1136de3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_all.rb @@ -0,0 +1,29 @@ +class Pry + class Command::ExitAll < Pry::ClassCommand + match 'exit-all' + group 'Navigating Pry' + description 'End the current Pry session.' + + banner <<-'BANNER' + Usage: exit-all [--help] + Aliases: !!@ + + End the current Pry session (popping all bindings and returning to caller). + Accepts optional return value. + BANNER + + def process + # calculate user-given value + exit_value = target.eval(arg_string) + + # clear the binding stack + _pry_.binding_stack.clear + + # break out of the repl loop + throw(:breakout, exit_value) + end + end + + Pry::Commands.add_command(Pry::Command::ExitAll) + Pry::Commands.alias_command '!!@', 'exit-all' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_program.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_program.rb new file mode 100644 index 0000000..a4d9168 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_program.rb @@ -0,0 +1,23 @@ +class Pry + class Command::ExitProgram < Pry::ClassCommand + match 'exit-program' + group 'Navigating Pry' + description 'End the current program.' + + banner <<-'BANNER' + Usage: exit-program [--help] + Aliases: quit-program + !!! + + End the current program. + BANNER + + def process + Kernel.exit target.eval(arg_string).to_i + end + end + + Pry::Commands.add_command(Pry::Command::ExitProgram) + Pry::Commands.alias_command 'quit-program', 'exit-program' + Pry::Commands.alias_command '!!!', 'exit-program' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/find_method.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/find_method.rb new file mode 100644 index 0000000..c1ee2c5 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/find_method.rb @@ -0,0 +1,193 @@ +class Pry + class Command::FindMethod < Pry::ClassCommand + extend Pry::Helpers::BaseHelpers + + match 'find-method' + group 'Context' + description 'Recursively search for a method within a Class/Module or the current namespace.' + command_options :shellwords => false + + banner <<-'BANNER' + Usage: find-method [-n|-c] METHOD [NAMESPACE] + + Recursively search for a method within a Class/Module or the current namespace. + Use the `-n` switch (the default) to search for methods whose name matches the + given regex. Use the `-c` switch to search for methods that contain the given + code. + + # Find all methods whose name match /re/ inside + # the Pry namespace. Matches Pry#repl, etc. + find-method re Pry + + # Find all methods that contain the code: + # output.puts inside the Pry namepsace. + find-method -c 'output.puts' Pry + BANNER + + def options(opt) + opt.on :n, :name, "Search for a method by name" + opt.on :c, :content, "Search for a method based on content in Regex form" + end + + def process + return if args.size < 1 + klass = search_class + + matches = if opts.content? + content_search(klass) + else + name_search(klass) + end + + show_search_results(matches) + end + + private + + # @return [Regexp] The pattern to search for. + def pattern + @pattern ||= ::Regexp.new args[0] + end + + # Output the result of the search. + # + # @param [Array] matches + def show_search_results(matches) + if matches.empty? + output.puts text.bold("No Methods Matched") + else + print_matches(matches) + end + end + + # The class to search for methods. + # We only search classes, so if the search object is an + # instance, return its class. If no search object is given + # search `target_self`. + def search_class + klass = if args[1] + target.eval(args[1]) + else + target_self + end + + klass.is_a?(Module) ? klass : klass.class + end + + # pretty-print a list of matching methods. + # + # @param [Array] matches + def print_matches(matches) + grouped = matches.group_by(&:owner) + order = grouped.keys.sort_by{ |x| x.name || x.to_s } + + order.each do |klass| + print_matches_for_class(klass, grouped) + end + end + + # Print matched methods for a class + def print_matches_for_class(klass, grouped) + output.puts text.bold(klass.name) + grouped[klass].each do |method| + header = method.name_with_owner + output.puts header + additional_info(header, method) + end + end + + # Return the matched lines of method source if `-c` is given or "" + # if `-c` was not given + def additional_info(header, method) + if opts.content? + ": " << colorize_code(matched_method_lines(header, method)) + else + "" + end + end + + def matched_method_lines(header, method) + method.source.split(/\n/).select {|x| x =~ pattern }.join("\n#{' ' * header.length}") + end + + # Run the given block against every constant in the provided namespace. + # + # @param [Module] klass The namespace in which to start the search. + # @param [Hash] done The namespaces we've already visited (private) + # @yieldparam klass Each class/module in the namespace. + # + def recurse_namespace(klass, done={}, &block) + return if !(Module === klass) || done[klass] + + done[klass] = true + + yield klass + + klass.constants.each do |name| + next if klass.autoload?(name) + begin + const = klass.const_get(name) + rescue RescuableException + # constant loading is an inexact science at the best of times, + # this often happens when a constant was .autoload? but someone + # tried to load it. It's now not .autoload? but will still raise + # a NameError when you access it. + else + recurse_namespace(const, done, &block) + end + end + end + + # Gather all the methods in a namespace that pass the given block. + # + # @param [Module] namespace The namespace in which to search. + # @yieldparam [Method] method The method to test + # @yieldreturn [Boolean] + # @return [Array] + # + def search_all_methods(namespace) + done = Hash.new{ |h,k| h[k] = {} } + matches = [] + + recurse_namespace(namespace) do |klass| + (Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).each do |method| + next if done[method.owner][method.name] + done[method.owner][method.name] = true + + matches << method if yield method + end + end + + matches + end + + # Search for all methods with a name that matches the given regex + # within a namespace. + # + # @param [Module] namespace The namespace to search + # @return [Array] + # + def name_search(namespace) + search_all_methods(namespace) do |meth| + meth.name =~ pattern + end + end + + # Search for all methods who's implementation matches the given regex + # within a namespace. + # + # @param [Module] namespace The namespace to search + # @return [Array] + # + def content_search(namespace) + search_all_methods(namespace) do |meth| + begin + meth.source =~ pattern + rescue RescuableException + false + end + end + end + end + + Pry::Commands.add_command(Pry::Command::FindMethod) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/fix_indent.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/fix_indent.rb new file mode 100644 index 0000000..75c48c7 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/fix_indent.rb @@ -0,0 +1,19 @@ +class Pry + class Command::FixIndent < Pry::ClassCommand + match 'fix-indent' + group 'Input and Output' + + description "Correct the indentation for contents of the input buffer" + + banner <<-USAGE + Usage: fix-indent + USAGE + + def process + indented_str = Pry::Indent.indent(eval_string) + eval_string.replace indented_str + end + end + + Pry::Commands.add_command(Pry::Command::FixIndent) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_cd.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_cd.rb new file mode 100644 index 0000000..da1907a --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_cd.rb @@ -0,0 +1,26 @@ +class Pry + class Command::GemCd < Pry::ClassCommand + match 'gem-cd' + group 'Gems' + description "Change working directory to specified gem's directory." + command_options :argument_required => true + + banner <<-'BANNER' + Usage: gem-cd GEM_NAME + + Change the current working directory to that in which the given gem is + installed. + BANNER + + def process(gem) + Dir.chdir(Rubygem.spec(gem).full_gem_path) + output.puts(Dir.pwd) + end + + def complete(str) + Rubygem.complete(str) + end + end + + Pry::Commands.add_command(Pry::Command::GemCd) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_install.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_install.rb new file mode 100644 index 0000000..873e106 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_install.rb @@ -0,0 +1,32 @@ +class Pry + class Command::GemInstall < Pry::ClassCommand + match 'gem-install' + group 'Gems' + description 'Install a gem and refresh the gem cache.' + command_options :argument_required => true + + banner <<-'BANNER' + Usage: gem-install GEM_NAME + + Installs the given gem, refreshes the gem cache, and requires the gem for you + based on a best guess from the gem name. + + gem-install pry-stack_explorer + BANNER + + def setup + require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller + end + + def process(gem) + Rubygem.install(gem) + output.puts "Gem `#{ text.green(gem) }` installed." + require gem + rescue LoadError + require_path = gem.split('-').join('/') + require require_path + end + end + + Pry::Commands.add_command(Pry::Command::GemInstall) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_list.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_list.rb new file mode 100644 index 0000000..e4a5d00 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_list.rb @@ -0,0 +1,33 @@ +class Pry + class Command::GemList < Pry::ClassCommand + match 'gem-list' + group 'Gems' + description 'List and search installed gems.' + + banner <<-'BANNER' + Usage: gem-list [REGEX] + + List all installed gems, when a regex is provided, limit the output to those + that match the regex. + BANNER + + def process(pattern = nil) + pattern = Regexp.compile(pattern || '') + gems = Rubygem.list(pattern).group_by(&:name) + + gems.each do |gem, specs| + specs.sort! do |a,b| + Gem::Version.new(b.version) <=> Gem::Version.new(a.version) + end + + versions = specs.each_with_index.map do |spec, index| + index == 0 ? text.bright_green(spec.version.to_s) : text.green(spec.version.to_s) + end + + output.puts "#{text.default gem} (#{versions.join ', '})" + end + end + end + + Pry::Commands.add_command(Pry::Command::GemList) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_open.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_open.rb new file mode 100644 index 0000000..e21723a --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_open.rb @@ -0,0 +1,29 @@ +class Pry + class Command::GemOpen < Pry::ClassCommand + match 'gem-open' + group 'Gems' + description 'Opens the working directory of the gem in your editor.' + command_options :argument_required => true + + banner <<-'BANNER' + Usage: gem-open GEM_NAME + + Change the current working directory to that in which the given gem is + installed, and then opens your text editor. + + gem-open pry-exception_explorer + BANNER + + def process(gem) + Dir.chdir(Rubygem.spec(gem).full_gem_path) do + Pry::Editor.invoke_editor(".", 0, false) + end + end + + def complete(str) + Rubygem.complete(str) + end + end + + Pry::Commands.add_command(Pry::Command::GemOpen) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gist.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gist.rb new file mode 100644 index 0000000..83cdf2b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gist.rb @@ -0,0 +1,101 @@ +class Pry + class Command::Gist < Pry::ClassCommand + match 'gist' + group 'Misc' + description 'Upload code, docs, history to https://gist.github.com/.' + command_options :requires_gem => "gist" + + banner <<-'BANNER' + Usage: gist [OPTIONS] [--help] + + The gist command enables you to gist code from files and methods to github. + + gist -i 20 --lines 1..3 + gist Pry#repl --lines 1..-1 + gist Rakefile --lines 5 + BANNER + + def setup + require 'gist' + end + + def options(opt) + CodeCollector.inject_options(opt) + opt.on :login, "Authenticate the gist gem with GitHub" + opt.on :p, :public, "Create a public gist (default: false)", :default => false + opt.on :clip, "Copy the selected content to clipboard instead, do NOT gist it", :default => false + end + + def process + return ::Gist.login! if opts.present?(:login) + cc = CodeCollector.new(args, opts, _pry_) + + if cc.content =~ /\A\s*\z/ + raise CommandError, "Found no code to gist." + end + + if opts.present?(:clip) + clipboard_content(cc.content) + else + # we're overriding the default behavior of the 'in' option (as + # defined on CodeCollector) with our local behaviour. + content = opts.present?(:in) ? input_content : cc.content + gist_content content, cc.file + end + end + + def clipboard_content(content) + ::Gist.copy(content) + output.puts "Copied content to clipboard!" + end + + def input_content + content = "" + CodeCollector.input_expression_ranges.each do |range| + input_expressions = _pry_.input_array[range] || [] + Array(input_expressions).each_with_index do |code, index| + corrected_index = index + range.first + if code && code != "" + content << code + if code !~ /;\Z/ + content << "#{comment_expression_result_for_gist(_pry_.config.gist.inspecter.call(_pry_.output_array[corrected_index]))}" + end + end + end + end + + content + end + + def comment_expression_result_for_gist(result) + content = "" + result.lines.each_with_index do |line, index| + if index == 0 + content << "# => #{line}" + else + content << "# #{line}" + end + end + + content + end + + def gist_content(content, filename) + response = ::Gist.gist(content, :filename => filename || "pry_gist.rb", :public => !!opts[:p]) + if response + url = response['html_url'] + message = "Gist created at URL #{url}" + begin + ::Gist.copy(url) + message << ", which is now in the clipboard." + rescue ::Gist::ClipboardError + end + + output.puts message + end + end + end + + Pry::Commands.add_command(Pry::Command::Gist) + Pry::Commands.alias_command 'clipit', 'gist --clip' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/help.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/help.rb new file mode 100644 index 0000000..3f29c2c --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/help.rb @@ -0,0 +1,164 @@ +class Pry + class Command::Help < Pry::ClassCommand + match 'help' + group 'Help' + description 'Show a list of commands or information about a specific command.' + + banner <<-'BANNER' + Usage: help [COMMAND] + + With no arguments, help lists all the available commands along with their + descriptions. When given a command name as an argument, shows the help + for that command. + BANNER + + # We only want to show commands that have descriptions, so that the + # easter eggs don't show up. + def visible_commands + visible = {} + commands.each do |key, command| + visible[key] = command if command.description && !command.description.empty? + end + visible + end + + # Get a hash of available commands grouped by the "group" name. + def command_groups + visible_commands.values.group_by(&:group) + end + + def process + if args.empty? + display_index(command_groups) + else + display_search(args.first) + end + end + + # Display the index view, with headings and short descriptions per command. + # + # @param [Hash>] groups + def display_index(groups) + help_text = [] + + sorted_group_names(groups).each do |group_name| + commands = sorted_commands(groups[group_name]) + + if commands.any? + help_text << help_text_for_commands(group_name, commands) + end + end + + _pry_.pager.page help_text.join("\n\n") + end + + # Given a group name and an array of commands, + # return the help string for those commands. + # + # @param [String] name The group name. + # @param [Array] commands + # @return [String] The generated help string. + def help_text_for_commands(name, commands) + "#{text.bold(name.capitalize)}\n" << commands.map do |command| + " #{command.options[:listing].to_s.ljust(18)} #{command.description.capitalize}" + end.join("\n") + end + + # @param [Hash] groups + # @return [Array] An array of sorted group names. + def sorted_group_names(groups) + groups.keys.sort_by(&method(:group_sort_key)) + end + + # Sort an array of commands by their `listing` name. + # + # @param [Array] commands The commands to sort + # @return [Array] commands sorted by listing name. + def sorted_commands(commands) + commands.sort_by{ |command| command.options[:listing].to_s } + end + + # Display help for an individual command or group. + # + # @param [String] search The string to search for. + def display_search(search) + if command = command_set.find_command_for_help(search) + display_command(command) + else + display_filtered_search_results(search) + end + end + + # Display help for a searched item, filtered first by group + # and if that fails, filtered by command name. + # + # @param [String] search The string to search for. + def display_filtered_search_results(search) + groups = search_hash(search, command_groups) + + if groups.size > 0 + display_index(groups) + else + display_filtered_commands(search) + end + end + + # Display help for a searched item, filtered by group + # + # @param [String] search The string to search for. + def display_filtered_commands(search) + filtered = search_hash(search, visible_commands) + raise CommandError, "No help found for '#{args.first}'" if filtered.empty? + + if filtered.size == 1 + display_command(filtered.values.first) + else + display_index({"'#{search}' commands" => filtered.values}) + end + end + + # Display help for an individual command. + # + # @param [Pry::Command] command + def display_command(command) + _pry_.pager.page command.new.help + end + + # Find a subset of a hash that matches the user's search term. + # + # If there's an exact match a Hash of one element will be returned, + # otherwise a sub-Hash with every key that matches the search will + # be returned. + # + # @param [String] search the search term + # @param [Hash] hash the hash to search + def search_hash(search, hash) + matching = {} + + hash.each_pair do |key, value| + next unless key.is_a?(String) + if normalize(key) == normalize(search) + return {key => value} + elsif normalize(key).start_with?(normalize(search)) + matching[key] = value + end + end + + matching + end + + # Clean search terms to make it easier to search group names + # + # @param [String] key + # @return [String] + def normalize(key) + key.downcase.gsub(/pry\W+/, '') + end + + def group_sort_key(group_name) + [%w(Help Context Editing Introspection Input_and_output Navigating_pry Gems Basic Commands).index(group_name.gsub(' ', '_')) || 99, group_name] + end + end + + Pry::Commands.add_command(Pry::Command::Help) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/hist.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/hist.rb new file mode 100644 index 0000000..083d3f5 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/hist.rb @@ -0,0 +1,180 @@ +class Pry + class Command::Hist < Pry::ClassCommand + match 'hist' + group 'Editing' + description 'Show and replay Readline history.' + + banner <<-'BANNER' + Usage: hist [--head|--tail] + hist --all + hist --head N + hist --tail N + hist --show START..END + hist --grep PATTERN + hist --clear + hist --replay START..END + hist --save [START..END] FILE + Aliases: history + + Show and replay Readline history. + BANNER + + def options(opt) + opt.on :a, :all, "Display all history" + opt.on :H, :head, "Display the first N items", :optional_argument => true, :as => Integer + opt.on :T, :tail, "Display the last N items", :optional_argument => true, :as => Integer + opt.on :s, :show, "Show the given range of lines", :optional_argument => true, :as => Range + opt.on :G, :grep, "Show lines matching the given pattern", :argument => true, :as => String + opt.on :c, :clear , "Clear the current session's history" + opt.on :r, :replay, "Replay a line or range of lines", :argument => true, :as => Range + opt.on :save, "Save history to a file", :argument => true, :as => Range + opt.on :e, :'exclude-pry', "Exclude Pry commands from the history" + opt.on :n, :'no-numbers', "Omit line numbers" + end + + def process + @history = find_history + + if opts.present?(:show) + @history = @history.between(opts[:show]) + end + + if opts.present?(:grep) + @history = @history.grep(opts[:grep]) + end + + @history = case + when opts.present?(:head) + @history.take_lines(1, opts[:head] || 10) + when opts.present?(:tail) + @history.take_lines(-(opts[:tail] || 10), opts[:tail] || 10) + when opts.present?(:show) + @history.between(opts[:show]) + else + @history + end + + if opts.present?(:'exclude-pry') + @history = @history.select do |loc| + !command_set.valid_command?(loc.line) + end + end + + if opts.present?(:save) + process_save + elsif opts.present?(:clear) + process_clear + elsif opts.present?(:replay) + process_replay + else + process_display + end + end + + private + + def process_display + unless opts.present?(:'no-numbers') + @history = @history.with_line_numbers + end + + _pry_.pager.open do |pager| + @history.print_to_output(pager, true) + end + end + + def process_save + case opts[:save] + when Range + @history = @history.between(opts[:save]) + + unless args.first + raise CommandError, "Must provide a file name." + end + + file_name = File.expand_path(args.first) + when String + file_name = File.expand_path(opts[:save]) + end + + output.puts "Saving history in #{file_name}..." + + File.open(file_name, 'w') { |f| f.write(@history.raw) } + + output.puts "History saved." + end + + def process_clear + Pry.history.clear + output.puts "History cleared." + end + + def process_replay + @history = @history.between(opts[:r]) + replay_sequence = @history.raw + + # If we met follow-up "hist" call, check for the "--replay" option + # presence. If "hist" command is called with other options, proceed + # further. + check_for_juxtaposed_replay(replay_sequence) + + replay_sequence.lines.each do |line| + _pry_.eval line, :generated => true + end + end + + # Checks +replay_sequence+ for the presence of neighboring replay calls. + # @example + # [1] pry(main)> hist --show 46894 + # 46894: hist --replay 46675..46677 + # [2] pry(main)> hist --show 46675..46677 + # 46675: 1+1 + # 46676: a = 100 + # 46677: hist --tail + # [3] pry(main)> hist --replay 46894 + # Error: Replay index 46894 points out to another replay call: `hist -r 46675..46677` + # [4] pry(main)> + # + # @raise [Pry::CommandError] If +replay_sequence+ contains another + # "hist --replay" call + # @param [String] replay_sequence The sequence of commands to be replayed + # (per saltum) + # @return [Boolean] `false` if +replay_sequence+ does not contain another + # "hist --replay" call + def check_for_juxtaposed_replay(replay_sequence) + if replay_sequence =~ /\Ahist(?:ory)?\b/ + # Create *fresh* instance of Options for parsing of "hist" command. + _slop = self.slop + _slop.parse replay_sequence.split(' ')[1..-1] + + if _slop.present?(:r) + replay_sequence = replay_sequence.split("\n").join('; ') + index = opts[:r] + index = index.min if index.min == index.max || index.max.nil? + + raise CommandError, "Replay index #{ index } points out to another replay call: `#{ replay_sequence }`" + end + else + false + end + end + + # Finds history depending on the given switch. + # + # @return [Pry::Code] if it finds `--all` (or `-a`) switch, returns all + # entries in history. Without the switch returns only the entries from the + # current Pry session. + def find_history + h = if opts.present?(:all) + Pry.history.to_a + else + Pry.history.to_a.last(Pry.history.session_line_count) + end + # The last value in history will be the 'hist' command itself. + Pry::Code(h[0..-2]) + end + end + + Pry::Commands.add_command(Pry::Command::Hist) + Pry::Commands.alias_command 'history', 'hist' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/import_set.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/import_set.rb new file mode 100644 index 0000000..5689883 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/import_set.rb @@ -0,0 +1,22 @@ +class Pry + class Command::ImportSet < Pry::ClassCommand + match 'import-set' + group 'Commands' + # TODO: Provide a better description with examples and a general conception + # of this command. + description 'Import a Pry command set.' + + banner <<-'BANNER' + Import a Pry command set. + BANNER + + def process(command_set_name) + raise CommandError, "Provide a command set name" if command_set.nil? + + set = target.eval(arg_string) + _pry_.commands.import set + end + end + + Pry::Commands.add_command(Pry::Command::ImportSet) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/install_command.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/install_command.rb new file mode 100644 index 0000000..acafe7b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/install_command.rb @@ -0,0 +1,53 @@ +class Pry + class Command::InstallCommand < Pry::ClassCommand + match 'install-command' + group 'Commands' + description 'Install a disabled command.' + + banner <<-'BANNER' + Usage: install-command COMMAND + + Installs the gems necessary to run the given COMMAND. You will generally not + need to run this unless told to by an error message. + BANNER + + def process(name) + require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller + command = find_command(name) + + unless command + output.puts "Command #{ text.green(name) } is not found" + return + end + + if command_dependencies_met?(command.options) + output.puts "Dependencies for #{ text.green(name) } are met. Nothing to do" + return + end + + output.puts "Attempting to install #{ text.green(name) } command..." + gems_to_install = Array(command.options[:requires_gem]) + + gems_to_install.each do |g| + next if Rubygem.installed?(g) + output.puts "Installing #{ text.green(g) } gem..." + Rubygem.install(g) + end + + gems_to_install.each do |g| + begin + require g + rescue LoadError + fail_msg = "Required gem #{ text.green(g) } installed but not found." + fail_msg += " Aborting command installation\n" + fail_msg += 'Tips: 1. Check your PATH; 2. Run `bundle update`' + raise CommandError, fail_msg + end + end + + output.puts "Installation of #{ text.green(name) } successful! Type `help #{name}` for information" + end + end + + Pry::Commands.add_command(Pry::Command::InstallCommand) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/jump_to.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/jump_to.rb new file mode 100644 index 0000000..4179fc7 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/jump_to.rb @@ -0,0 +1,29 @@ +class Pry + class Command::JumpTo < Pry::ClassCommand + match 'jump-to' + group 'Navigating Pry' + description 'Jump to a binding further up the stack.' + + banner <<-'BANNER' + Jump to a binding further up the stack, popping all bindings below. + BANNER + + def process(break_level) + break_level = break_level.to_i + nesting_level = _pry_.binding_stack.size - 1 + + case break_level + when nesting_level + output.puts "Already at nesting level #{nesting_level}" + when (0...nesting_level) + _pry_.binding_stack.slice!(break_level + 1, _pry_.binding_stack.size) + + else + max_nest_level = nesting_level - 1 + output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}." + end + end + end + + Pry::Commands.add_command(Pry::Command::JumpTo) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_inspectors.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_inspectors.rb new file mode 100644 index 0000000..c96c395 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_inspectors.rb @@ -0,0 +1,35 @@ +class Pry::Command::ListInspectors < Pry::ClassCommand + match 'list-inspectors' + group 'Input and Output' + description 'List the inspector procs available for use.' + banner <<-BANNER + Usage: list-inspectors + + List the inspector procs available to print return values. You can use + change-inspector to switch between them. + BANNER + + def process + output.puts heading("Available inspectors") + "\n" + inspector_map.each do |name, inspector| + output.write "Name: #{text.bold(name)}" + output.puts selected_inspector?(inspector) ? selected_text : "" + output.puts inspector[:description] + output.puts + end + end + +private + def inspector_map + Pry::Inspector::MAP + end + + def selected_text + text.red " (selected) " + end + + def selected_inspector?(inspector) + _pry_.print == inspector[:value] + end + Pry::Commands.add_command(self) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_prompts.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_prompts.rb new file mode 100644 index 0000000..436f719 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_prompts.rb @@ -0,0 +1,35 @@ +class Pry::Command::ListPrompts < Pry::ClassCommand + match 'list-prompts' + group 'Input and Output' + description 'List the prompts available for use.' + banner <<-BANNER + Usage: list-prompts + + List the available prompts. You can use change-prompt to switch between + them. + BANNER + + def process + output.puts heading("Available prompts") + "\n" + prompt_map.each do |name, prompt| + output.write "Name: #{text.bold(name)}" + output.puts selected_prompt?(prompt) ? selected_text : "" + output.puts prompt[:description] + output.puts + end + end + +private + def prompt_map + Pry::Prompt::MAP + end + + def selected_text + text.red " (selected) " + end + + def selected_prompt?(prompt) + _pry_.prompt == prompt[:value] + end + Pry::Commands.add_command(self) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls.rb new file mode 100644 index 0000000..9f0e68f --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls.rb @@ -0,0 +1,114 @@ +require 'pry/commands/ls/ls_entity' +class Pry + class Command::Ls < Pry::ClassCommand + DEFAULT_OPTIONS = { + :heading_color => :bright_blue, + :public_method_color => :default, + :private_method_color => :blue, + :protected_method_color => :blue, + :method_missing_color => :bright_red, + :local_var_color => :yellow, + :pry_var_color => :default, # e.g. _, _pry_, _file_ + :instance_var_color => :blue, # e.g. @foo + :class_var_color => :bright_blue, # e.g. @@foo + :global_var_color => :default, # e.g. $CODERAY_DEBUG, $eventmachine_library + :builtin_global_color => :cyan, # e.g. $stdin, $-w, $PID + :pseudo_global_color => :cyan, # e.g. $~, $1..$9, $LAST_MATCH_INFO + :constant_color => :default, # e.g. VERSION, ARGF + :class_constant_color => :blue, # e.g. Object, Kernel + :exception_constant_color => :magenta, # e.g. Exception, RuntimeError + :unloaded_constant_color => :yellow, # Any constant that is still in .autoload? state + :separator => " ", + :ceiling => [Object, Module, Class] + } + + + match 'ls' + group 'Context' + description 'Show the list of vars and methods in the current scope.' + command_options :shellwords => false, :interpolate => false + + banner <<-'BANNER' + Usage: ls [-m|-M|-p|-pM] [-q|-v] [-c|-i] [Object] + ls [-g] [-l] + + ls shows you which methods, constants and variables are accessible to Pry. By + default it shows you the local variables defined in the current shell, and any + public methods or instance variables defined on the current object. + + The colours used are configurable using Pry.config.ls.*_color, and the separator + is Pry.config.ls.separator. + + Pry.config.ls.ceiling is used to hide methods defined higher up in the + inheritance chain, this is by default set to [Object, Module, Class] so that + methods defined on all Objects are omitted. The -v flag can be used to ignore + this setting and show all methods, while the -q can be used to set the ceiling + much lower and show only methods defined on the object or its direct class. + + Also check out `find-method` command (run `help find-method`). + BANNER + + + def options(opt) + opt.on :m, :methods, "Show public methods defined on the Object" + opt.on :M, "instance-methods", "Show public methods defined in a Module or Class" + opt.on :p, :ppp, "Show public, protected (in yellow) and private (in green) methods" + opt.on :q, :quiet, "Show only methods defined on object.singleton_class and object.class" + opt.on :v, :verbose, "Show methods and constants on all super-classes (ignores Pry.config.ls.ceiling)" + opt.on :g, :globals, "Show global variables, including those builtin to Ruby (in cyan)" + opt.on :l, :locals, "Show hash of local vars, sorted by descending size" + opt.on :c, :constants, "Show constants, highlighting classes (in blue), and exceptions (in purple).\n" << + " " * 32 << "Constants that are pending autoload? are also shown (in yellow)" + opt.on :i, :ivars, "Show instance variables (in blue) and class variables (in bright blue)" + opt.on :G, :grep, "Filter output by regular expression", :argument => true + + if jruby? + opt.on :J, "all-java", "Show all the aliases for methods from java (default is to show only prettiest)" + end + end + + # Exclude -q, -v and --grep because they, + # don't specify what the user wants to see. + def no_user_opts? + !(opts[:methods] || opts['instance-methods'] || opts[:ppp] || + opts[:globals] || opts[:locals] || opts[:constants] || opts[:ivars]) + end + + def process + @interrogatee = args.empty? ? target_self : target.eval(args.join(' ')) + raise_errors_if_arguments_are_weird + ls_entity = LsEntity.new({ + :interrogatee => @interrogatee, + :no_user_opts => no_user_opts?, + :opts => opts, + :args => args, + :_pry_ => _pry_ + }) + + _pry_.pager.page ls_entity.entities_table + end + + private + + def error_list + any_args = args.any? + non_mod_interrogatee = !(Module === @interrogatee) + [ + ['-l does not make sense with a specified Object', :locals, any_args], + ['-g does not make sense with a specified Object', :globals, any_args], + ['-q does not make sense with -v', :quiet, opts.present?(:verbose)], + ['-M only makes sense with a Module or a Class', 'instance-methods', non_mod_interrogatee], + ['-c only makes sense with a Module or a Class', :constants, any_args && non_mod_interrogatee] + ] + end + + def raise_errors_if_arguments_are_weird + error_list.each do |message, option, invalid_expr| + raise Pry::CommandError, message if opts.present?(option) && invalid_expr + end + end + + end + + Pry::Commands.add_command(Pry::Command::Ls) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/constants.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/constants.rb new file mode 100644 index 0000000..3db8162 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/constants.rb @@ -0,0 +1,47 @@ +require 'pry/commands/ls/interrogatable' + +class Pry + class Command::Ls < Pry::ClassCommand + class Constants < Pry::Command::Ls::Formatter + include Pry::Command::Ls::Interrogatable + + + def initialize(interrogatee, no_user_opts, opts, _pry_) + super(_pry_) + @interrogatee = interrogatee + @no_user_opts = no_user_opts + @default_switch = opts[:constants] + @verbose_switch = opts[:verbose] + end + + def correct_opts? + super || (@no_user_opts && interrogating_a_module?) + end + + def output_self + mod = interrogatee_mod + constants = WrappedModule.new(mod).constants(@verbose_switch) + output_section('constants', grep.regexp[format(mod, constants)]) + end + + private + + def format(mod, constants) + constants.sort_by(&:downcase).map do |name| + if const = (!mod.autoload?(name) && (mod.const_get(name) || true) rescue nil) + if (const < Exception rescue false) + color(:exception_constant, name) + elsif (Module === mod.const_get(name) rescue false) + color(:class_constant, name) + else + color(:constant, name) + end + else + color(:unloaded_constant, name) + end + end + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/formatter.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/formatter.rb new file mode 100644 index 0000000..844a220 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/formatter.rb @@ -0,0 +1,49 @@ +class Pry + class Command::Ls < Pry::ClassCommand + class Formatter + attr_accessor :grep + attr_reader :_pry_ + + def initialize(_pry_) + @_pry_ = _pry_ + @target = _pry_.current_context + end + + def write_out + return false unless correct_opts? + output_self + end + + private + + def color(type, str) + Pry::Helpers::Text.send _pry_.config.ls["#{type}_color"], str + end + + # Add a new section to the output. + # Outputs nothing if the section would be empty. + def output_section(heading, body) + return '' if body.compact.empty? + fancy_heading = Pry::Helpers::Text.bold(color(:heading, heading)) + Pry::Helpers.tablify_or_one_line(fancy_heading, body) + end + + def format_value(value) + Pry::ColorPrinter.pp(value, '') + end + + def correct_opts? + @default_switch + end + + def output_self + raise NotImplementedError + end + + def grep + @grep || proc { |x| x } + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/globals.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/globals.rb new file mode 100644 index 0000000..2b3d0fd --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/globals.rb @@ -0,0 +1,48 @@ +class Pry + class Command::Ls < Pry::ClassCommand + class Globals < Pry::Command::Ls::Formatter + + # Taken from "puts global_variables.inspect". + BUILTIN_GLOBALS = + %w($" $$ $* $, $-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w $. $/ $\\ + $: $; $< $= $> $0 $ARGV $CONSOLE $DEBUG $DEFAULT_INPUT $DEFAULT_OUTPUT + $FIELD_SEPARATOR $FILENAME $FS $IGNORECASE $INPUT_LINE_NUMBER + $INPUT_RECORD_SEPARATOR $KCODE $LOADED_FEATURES $LOAD_PATH $NR $OFS + $ORS $OUTPUT_FIELD_SEPARATOR $OUTPUT_RECORD_SEPARATOR $PID $PROCESS_ID + $PROGRAM_NAME $RS $VERBOSE $deferr $defout $stderr $stdin $stdout) + + # `$SAFE` and `$?` are thread-local, the exception stuff only works in a + # rescue clause, everything else is basically a local variable with a `$` + # in its name. + PSEUDO_GLOBALS = + %w($! $' $& $` $@ $? $+ $_ $~ $1 $2 $3 $4 $5 $6 $7 $8 $9 + $CHILD_STATUS $SAFE $ERROR_INFO $ERROR_POSITION $LAST_MATCH_INFO + $LAST_PAREN_MATCH $LAST_READ_LINE $MATCH $POSTMATCH $PREMATCH) + + def initialize(opts, _pry_) + super(_pry_) + @default_switch = opts[:globals] + end + + def output_self + variables = format(@target.eval('global_variables')) + output_section('global variables', grep.regexp[variables]) + end + + private + + def format(globals) + globals.map(&:to_s).sort_by(&:downcase).map do |name| + if PSEUDO_GLOBALS.include?(name) + color(:pseudo_global, name) + elsif BUILTIN_GLOBALS.include?(name) + color(:builtin_global, name) + else + color(:global_var, name) + end + end + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/grep.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/grep.rb new file mode 100644 index 0000000..14e6b00 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/grep.rb @@ -0,0 +1,21 @@ +class Pry + class Command::Ls < Pry::ClassCommand + class Grep + + def initialize(grep_regexp) + @grep_regexp = grep_regexp + end + + def regexp + proc { |x| + if x.instance_of?(Array) + x.grep(@grep_regexp) + else + x =~ @grep_regexp + end + } + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/instance_vars.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/instance_vars.rb new file mode 100644 index 0000000..2f33677 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/instance_vars.rb @@ -0,0 +1,39 @@ +require 'pry/commands/ls/interrogatable' + +class Pry + class Command::Ls < Pry::ClassCommand + class InstanceVars < Pry::Command::Ls::Formatter + include Pry::Command::Ls::Interrogatable + + def initialize(interrogatee, no_user_opts, opts, _pry_) + super(_pry_) + @interrogatee = interrogatee + @no_user_opts = no_user_opts + @default_switch = opts[:ivars] + end + + def correct_opts? + super || @no_user_opts + end + + def output_self + ivars = if Object === @interrogatee + Pry::Method.safe_send(@interrogatee, :instance_variables) + else + [] #TODO: BasicObject support + end + kvars = Pry::Method.safe_send(interrogatee_mod, :class_variables) + ivars_out = output_section('instance variables', format(:instance_var, ivars)) + kvars_out = output_section('class variables', format(:class_var, kvars)) + ivars_out + kvars_out + end + + private + + def format(type, vars) + vars.sort_by { |var| var.to_s.downcase }.map { |var| color(type, var) } + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/interrogatable.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/interrogatable.rb new file mode 100644 index 0000000..5904d1b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/interrogatable.rb @@ -0,0 +1,18 @@ +module Pry::Command::Ls::Interrogatable + + private + + def interrogating_a_module? + Module === @interrogatee + end + + def interrogatee_mod + if interrogating_a_module? + @interrogatee + else + singleton = Pry::Method.singleton_class_of(@interrogatee) + singleton.ancestors.grep(::Class).reject { |c| c == singleton }.first + end + end + +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/jruby_hacks.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/jruby_hacks.rb new file mode 100644 index 0000000..0f73e08 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/jruby_hacks.rb @@ -0,0 +1,49 @@ +module Pry::Command::Ls::JRubyHacks + + private + + # JRuby creates lots of aliases for methods imported from java in an attempt + # to make life easier for ruby programmers. (e.g. getFooBar becomes + # get_foo_bar and foo_bar, and maybe foo_bar? if it returns a Boolean). The + # full transformations are in the assignAliases method of: + # https://github.com/jruby/jruby/blob/master/src/org/jruby/javasupport/JavaClass.java + # + # This has the unfortunate side-effect of making the output of ls even more + # incredibly verbose than it normally would be for these objects; and so we + # filter out all but the nicest of these aliases here. + # + # TODO: This is a little bit vague, better heuristics could be used. + # JRuby also has a lot of scala-specific logic, which we don't copy. + def trim_jruby_aliases(methods) + grouped = methods.group_by do |m| + m.name.sub(/\A(is|get|set)(?=[A-Z_])/, '').gsub(/[_?=]/, '').downcase + end + + grouped.map do |key, values| + values = values.sort_by do |m| + rubbishness(m.name) + end + + found = [] + values.select do |x| + (!found.any? { |y| x == y }) && found << x + end + end.flatten(1) + end + + # When removing jruby aliases, we want to keep the alias that is + # "least rubbish" according to this metric. + def rubbishness(name) + name.each_char.map { |x| + case x + when /[A-Z]/ + 1 + when '?', '=', '!' + -2 + else + 0 + end + }.inject(&:+) + (name.size / 100.0) + end + +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_names.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_names.rb new file mode 100644 index 0000000..9d6350b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_names.rb @@ -0,0 +1,35 @@ +class Pry + class Command::Ls < Pry::ClassCommand + class LocalNames < Pry::Command::Ls::Formatter + + def initialize(no_user_opts, args, _pry_) + super(_pry_) + @no_user_opts = no_user_opts + @args = args + @sticky_locals = _pry_.sticky_locals + end + + def correct_opts? + super || (@no_user_opts && @args.empty?) + end + + def output_self + local_vars = grep.regexp[@target.eval('local_variables')] + output_section('locals', format(local_vars)) + end + + private + + def format(locals) + locals.sort_by(&:downcase).map do |name| + if @sticky_locals.include?(name.to_sym) + color(:pry_var, name) + else + color(:local_var, name) + end + end + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_vars.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_vars.rb new file mode 100644 index 0000000..d48ddae --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_vars.rb @@ -0,0 +1,39 @@ +class Pry + class Command::Ls < Pry::ClassCommand + class LocalVars < Pry::Command::Ls::Formatter + + def initialize(opts, _pry_) + super(_pry_) + @default_switch = opts[:locals] + @sticky_locals = _pry_.sticky_locals + end + + def output_self + name_value_pairs = @target.eval('local_variables').reject { |e| + @sticky_locals.keys.include?(e.to_sym) + }.map { |name| + [name, (@target.eval(name.to_s))] + } + format(name_value_pairs).join('') + end + + private + + def format(name_value_pairs) + name_value_pairs.sort_by { |name, value| + value.to_s.size + }.reverse.map { |name, value| + colorized_assignment_style(name, format_value(value)) + } + end + + def colorized_assignment_style(lhs, rhs, desired_width = 7) + colorized_lhs = color(:local_var, lhs) + color_escape_padding = colorized_lhs.size - lhs.size + pad = desired_width + color_escape_padding + "%-#{pad}s = %s" % [color(:local_var, colorized_lhs), rhs] + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/ls_entity.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/ls_entity.rb new file mode 100644 index 0000000..3d69bcd --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/ls_entity.rb @@ -0,0 +1,70 @@ +require 'pry/commands/ls/grep' +require 'pry/commands/ls/formatter' +require 'pry/commands/ls/globals' +require 'pry/commands/ls/constants' +require 'pry/commands/ls/methods' +require 'pry/commands/ls/self_methods' +require 'pry/commands/ls/instance_vars' +require 'pry/commands/ls/local_names' +require 'pry/commands/ls/local_vars' + +class Pry + class Command::Ls < Pry::ClassCommand + + class LsEntity + attr_reader :_pry_ + + def initialize(opts) + @interrogatee = opts[:interrogatee] + @no_user_opts = opts[:no_user_opts] + @opts = opts[:opts] + @args = opts[:args] + @grep = Grep.new(Regexp.new(opts[:opts][:G] || '.')) + @_pry_ = opts.delete(:_pry_) + end + + def entities_table + entities.map(&:write_out).reject { |o| !o }.join('') + end + + private + + def grep(entity) + entity.tap { |o| o.grep = @grep } + end + + def globals + grep Globals.new(@opts, _pry_) + end + + def constants + grep Constants.new(@interrogatee, @no_user_opts, @opts, _pry_) + end + + def methods + grep(Methods.new(@interrogatee, @no_user_opts, @opts, _pry_)) + end + + def self_methods + grep SelfMethods.new(@interrogatee, @no_user_opts, @opts, _pry_) + end + + def instance_vars + grep InstanceVars.new(@interrogatee, @no_user_opts, @opts, _pry_) + end + + def local_names + grep LocalNames.new(@no_user_opts, @args, _pry_) + end + + def local_vars + LocalVars.new(@opts, _pry_) + end + + def entities + [globals, constants, methods, self_methods, instance_vars, local_names, + local_vars] + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods.rb new file mode 100644 index 0000000..c085f42 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods.rb @@ -0,0 +1,57 @@ +require 'pry/commands/ls/methods_helper' +require 'pry/commands/ls/interrogatable' + +class Pry + class Command::Ls < Pry::ClassCommand + class Methods < Pry::Command::Ls::Formatter + + include Pry::Command::Ls::Interrogatable + include Pry::Command::Ls::MethodsHelper + + def initialize(interrogatee, no_user_opts, opts, _pry_) + super(_pry_) + @interrogatee = interrogatee + @no_user_opts = no_user_opts + @default_switch = opts[:methods] + @instance_methods_switch = opts['instance-methods'] + @ppp_switch = opts[:ppp] + @jruby_switch = opts['all-java'] + @quiet_switch = opts[:quiet] + @verbose_switch = opts[:verbose] + end + + def output_self + methods = all_methods.group_by(&:owner) + # Reverse the resolution order so that the most useful information + # appears right by the prompt. + resolution_order.take_while(&below_ceiling).reverse.map do |klass| + methods_here = (methods[klass] || []).select { |m| grep.regexp[m.name] } + heading = "#{ Pry::WrappedModule.new(klass).method_prefix }methods" + output_section(heading, format(methods_here)) + end.join('') + end + + private + + def correct_opts? + super || @instance_methods_switch || @ppp_switch || @no_user_opts + end + + + # Get a lambda that can be used with `take_while` to prevent over-eager + # traversal of the Object's ancestry graph. + def below_ceiling + ceiling = if @quiet_switch + [Pry::Method.safe_send(interrogatee_mod, :ancestors)[1]] + + _pry_.config.ls.ceiling + elsif @verbose_switch + [] + else + _pry_.config.ls.ceiling.dup + end + lambda { |klass| !ceiling.include?(klass) } + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods_helper.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods_helper.rb new file mode 100644 index 0000000..f0b4414 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods_helper.rb @@ -0,0 +1,46 @@ +require 'pry/commands/ls/jruby_hacks' + +module Pry::Command::Ls::MethodsHelper + + include Pry::Command::Ls::JRubyHacks + + private + + # Get all the methods that we'll want to output. + def all_methods(instance_methods = false) + methods = if instance_methods || @instance_methods_switch + Pry::Method.all_from_class(@interrogatee) + else + Pry::Method.all_from_obj(@interrogatee) + end + + if Pry::Helpers::BaseHelpers.jruby? && !@jruby_switch + methods = trim_jruby_aliases(methods) + end + + methods.select { |method| @ppp_switch || method.visibility == :public } + end + + def resolution_order + if @instance_methods_switch + Pry::Method.instance_resolution_order(@interrogatee) + else + Pry::Method.resolution_order(@interrogatee) + end + end + + def format(methods) + methods.sort_by(&:name).map do |method| + if method.name == 'method_missing' + color(:method_missing, 'method_missing') + elsif method.visibility == :private + color(:private_method, method.name) + elsif method.visibility == :protected + color(:protected_method, method.name) + else + color(:public_method, method.name) + end + end + end + +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/self_methods.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/self_methods.rb new file mode 100644 index 0000000..91f3490 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/self_methods.rb @@ -0,0 +1,32 @@ +require 'pry/commands/ls/interrogatable' +require 'pry/commands/ls/methods_helper' + +class Pry + class Command::Ls < Pry::ClassCommand + class SelfMethods < Pry::Command::Ls::Formatter + include Pry::Command::Ls::Interrogatable + include Pry::Command::Ls::MethodsHelper + + def initialize(interrogatee, no_user_opts, opts, _pry_) + super(_pry_) + @interrogatee = interrogatee + @no_user_opts = no_user_opts + end + + def output_self + methods = all_methods(true).select do |m| + m.owner == @interrogatee && grep.regexp[m.name] + end + heading = "#{ Pry::WrappedModule.new(@interrogatee).method_prefix }methods" + output_section(heading, format(methods)) + end + + private + + def correct_opts? + @no_user_opts && interrogating_a_module? + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/nesting.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/nesting.rb new file mode 100644 index 0000000..f9c0297 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/nesting.rb @@ -0,0 +1,25 @@ +class Pry + class Command::Nesting < Pry::ClassCommand + match 'nesting' + group 'Navigating Pry' + description 'Show nesting information.' + + banner <<-'BANNER' + Show nesting information. + BANNER + + def process + output.puts 'Nesting status:' + output.puts '--' + _pry_.binding_stack.each_with_index do |obj, level| + if level == 0 + output.puts "#{level}. #{Pry.view_clip(obj.eval('self'))} (Pry top level)" + else + output.puts "#{level}. #{Pry.view_clip(obj.eval('self'))}" + end + end + end + end + + Pry::Commands.add_command(Pry::Command::Nesting) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/play.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/play.rb new file mode 100644 index 0000000..5498d38 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/play.rb @@ -0,0 +1,103 @@ +class Pry + class Command::Play < Pry::ClassCommand + match 'play' + group 'Editing' + description 'Playback a string variable, method, line, or file as input.' + + banner <<-'BANNER' + Usage: play [OPTIONS] [--help] + + The play command enables you to replay code from files and methods as if they + were entered directly in the Pry REPL. + + play --lines 149..153 # assumes current context + play -i 20 --lines 1..3 # assumes lines of the input expression at 20 + play -o 4 # the output of of an expression at 4 + play Pry#repl -l 1..-1 # play the contents of Pry#repl method + play -e 2 # play from specified line until end of valid expression + play hello.rb # play a file + play Rakefile -l 5 # play line 5 of a file + play -d hi # play documentation of hi method + play hi --open # play hi method and leave it open + + https://github.com/pry/pry/wiki/User-Input#wiki-Play + BANNER + + def options(opt) + CodeCollector.inject_options(opt) + + opt.on :open, 'Plays the selected content except the last line. Useful' \ + ' for replaying methods and leaving the method definition' \ + ' "open". `amend-line` can then be used to' \ + ' modify the method.' + + opt.on :e, :expression=, 'Executes until end of valid expression', :as => Integer + opt.on :p, :print, 'Prints executed code' + end + + def process + @cc = CodeCollector.new(args, opts, _pry_) + + perform_play + show_input + end + + def perform_play + eval_string << content_after_options + run "fix-indent" + end + + def show_input + if opts.present?(:print) or !Pry::Code.complete_expression?(eval_string) + run "show-input" + end + end + + + def content_after_options + if opts.present?(:open) + restrict_to_lines(content, (0..-2)) + elsif opts.present?(:expression) + content_at_expression + else + content + end + end + + def content_at_expression + code_object.expression_at(opts[:expression]) + end + + def code_object + Pry::Code.new(content) + end + + def should_use_default_file? + !args.first && !opts.present?(:in) && !opts.present?(:out) + end + + def content + if should_use_default_file? + file_content + else + @cc.content + end + end + + # The file to play from when no code object is specified. + # e.g `play --lines 4..10` + def default_file + target.eval("__FILE__") && File.expand_path(target.eval("__FILE__")) + end + + def file_content + if default_file && File.exists?(default_file) + @cc.restrict_to_lines(File.read(default_file), @cc.line_range) + else + raise CommandError, "File does not exist! File was: #{default_file.inspect}" + end + end + end + + Pry::Commands.add_command(Pry::Command::Play) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_backtrace.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_backtrace.rb new file mode 100644 index 0000000..6795aa3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_backtrace.rb @@ -0,0 +1,25 @@ +class Pry + class Command::PryBacktrace < Pry::ClassCommand + match 'pry-backtrace' + group 'Context' + description 'Show the backtrace for the Pry session.' + + banner <<-BANNER + Usage: pry-backtrace [OPTIONS] [--help] + + Show the backtrace for the position in the code where Pry was started. This can + be used to infer the behavior of the program immediately before it entered Pry, + just like the backtrace property of an exception. + + NOTE: if you are looking for the backtrace of the most recent exception raised, + just type: `_ex_.backtrace` instead. + See: https://github.com/pry/pry/wiki/Special-Locals + BANNER + + def process + _pry_.pager.page text.bold('Backtrace:') << "\n--\n" << _pry_.backtrace.join("\n") + end + end + + Pry::Commands.add_command(Pry::Command::PryBacktrace) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_version.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_version.rb new file mode 100644 index 0000000..8cb8fd8 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_version.rb @@ -0,0 +1,17 @@ +class Pry + class Command::Version < Pry::ClassCommand + match 'pry-version' + group 'Misc' + description 'Show Pry version.' + + banner <<-'BANNER' + Show Pry version. + BANNER + + def process + output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}." + end + end + + Pry::Commands.add_command(Pry::Command::Version) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/raise_up.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/raise_up.rb new file mode 100644 index 0000000..70ad087 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/raise_up.rb @@ -0,0 +1,32 @@ +class Pry + # N.B. using a regular expresion here so that "raise-up 'foo'" does the right thing. + class Command::RaiseUp < Pry::ClassCommand + match(/raise-up(!?\b.*)/) + group 'Context' + description 'Raise an exception out of the current pry instance.' + command_options :listing => 'raise-up' + + banner <<-BANNER + Raise up, like exit, allows you to quit pry. Instead of returning a value + however, it raises an exception. If you don't provide the exception to be + raised, it will use the most recent exception (in pry `_ex_`). + + When called as raise-up! (with an exclamation mark), this command raises the + exception through any nested prys you have created by "cd"ing into objects. + + raise-up "get-me-out-of-here" + + # This is equivalent to the command above. + raise "get-me-out-of-here" + raise-up + BANNER + + def process + return _pry.pager.page help if captures[0] =~ /(-h|--help)\b/ + # Handle 'raise-up', 'raise-up "foo"', 'raise-up RuntimeError, 'farble' in a rubyesque manner + target.eval("_pry_.raise_up#{captures[0]}") + end + end + + Pry::Commands.add_command(Pry::Command::RaiseUp) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reload_code.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reload_code.rb new file mode 100644 index 0000000..7041338 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reload_code.rb @@ -0,0 +1,62 @@ +class Pry + class Command::ReloadCode < Pry::ClassCommand + match 'reload-code' + group 'Misc' + description 'Reload the source file that contains the specified code object.' + + banner <<-'BANNER' + Reload the source file that contains the specified code object. + + e.g reload-code MyClass#my_method #=> reload a method + reload-code MyClass #=> reload a class + reload-code my-command #=> reload a pry command + reload-code self #=> reload the current object + reload-code #=> reload the current file or object + BANNER + + def process + if !args.empty? + reload_object(args.join(" ")) + elsif internal_binding?(target) + reload_object("self") + else + reload_current_file + end + end + + private + + def current_file + File.expand_path target.eval("__FILE__") + end + + def reload_current_file + if !File.exists?(current_file) + raise CommandError, "Current file: #{current_file} cannot be found on disk!" + end + + load current_file + output.puts "The current file: #{current_file} was reloaded!" + end + + def reload_object(identifier) + code_object = Pry::CodeObject.lookup(identifier, _pry_) + check_for_reloadability(code_object, identifier) + load code_object.source_file + output.puts "#{identifier} was reloaded!" + end + + def check_for_reloadability(code_object, identifier) + if !code_object || !code_object.source_file + raise CommandError, "Cannot locate #{identifier}!" + elsif !File.exists?(code_object.source_file) + raise CommandError, + "Cannot reload #{identifier} as it has no associated file on disk. " \ + "File found was: #{code_object.source_file}" + end + end + end + + Pry::Commands.add_command(Pry::Command::ReloadCode) + Pry::Commands.alias_command 'reload-method', 'reload-code' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reset.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reset.rb new file mode 100644 index 0000000..4414cbb --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reset.rb @@ -0,0 +1,18 @@ +class Pry + class Command::Reset < Pry::ClassCommand + match 'reset' + group 'Context' + description 'Reset the REPL to a clean state.' + + banner <<-'BANNER' + Reset the REPL to a clean state. + BANNER + + def process + output.puts 'Pry reset.' + exec 'pry' + end + end + + Pry::Commands.add_command(Pry::Command::Reset) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ri.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ri.rb new file mode 100644 index 0000000..d29c426 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ri.rb @@ -0,0 +1,60 @@ +class Pry + class Command::Ri < Pry::ClassCommand + match 'ri' + group 'Introspection' + description 'View ri documentation.' + + banner <<-'BANNER' + Usage: ri [spec] + + View ri documentation. Relies on the "rdoc" gem being installed. + See also "show-doc" command. + + ri Array#each + BANNER + + def process(spec) + # Lazily load RI + require 'rdoc/ri/driver' + + unless defined? RDoc::RI::PryDriver + + # Subclass RI so that it formats its output nicely, and uses `lesspipe`. + subclass = Class.new(RDoc::RI::Driver) # the hard way. + + subclass.class_eval do + def initialize(pager, opts) + @pager = pager + super opts + end + def page + paging_text = StringIO.new + yield paging_text + @pager.page(paging_text.string) + end + + def formatter(io) + if @formatter_klass + @formatter_klass.new + else + RDoc::Markup::ToAnsi.new + end + end + end + + RDoc::RI.const_set :PryDriver, subclass # hook it up! + end + + # Spin-up an RI insance. + ri = RDoc::RI::PryDriver.new _pry_.pager, :use_stdout => true, :interactive => false + + begin + ri.display_names [spec] # Get the documentation (finally!) + rescue RDoc::RI::Driver::NotFoundError => e + output.puts "error: '#{e.name}' not found" + end + end + end + + Pry::Commands.add_command(Pry::Command::Ri) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/save_file.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/save_file.rb new file mode 100644 index 0000000..d22a692 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/save_file.rb @@ -0,0 +1,61 @@ +require 'pry/commands/code_collector' + +class Pry + class Command::SaveFile < Pry::ClassCommand + match 'save-file' + group 'Input and Output' + description 'Export to a file using content from the REPL.' + + banner <<-'BANNER' + Usage: save-file [OPTIONS] --to [FILE] + + Export to a file using content from the REPL. + + save-file my_method --to hello.rb + save-file -i 1..10 --to hello.rb --append + save-file show-method --to my_command.rb + save-file sample_file.rb --lines 2..10 --to output_file.rb + BANNER + + def options(opt) + CodeCollector.inject_options(opt) + + opt.on :to=, "Specify the output file path" + opt.on :a, :append, "Append output to file" + end + + def process + @cc = CodeCollector.new(args, opts, _pry_) + raise CommandError, "Found no code to save." if @cc.content.empty? + + if !file_name + display_content + else + save_file + end + end + + def file_name + opts[:to] || nil + end + + def save_file + File.open(file_name, mode) do |f| + f.puts @cc.content + end + output.puts "#{file_name} successfully saved" + end + + def display_content + output.puts @cc.content + output.puts "\n\n--\nPlease use `--to FILE` to export to a file." + output.puts "No file saved!\n--" + end + + def mode + opts.present?(:append) ? "a" : "w" + end + end + + Pry::Commands.add_command(Pry::Command::SaveFile) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_command.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_command.rb new file mode 100644 index 0000000..78fccd5 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_command.rb @@ -0,0 +1,48 @@ +class Pry + class Command::ShellCommand < Pry::ClassCommand + match(/\.(.*)/) + group 'Input and Output' + description "All text following a '.' is forwarded to the shell." + command_options :listing => '.', :use_prefix => false, + :takes_block => true + + banner <<-'BANNER' + Usage: .COMMAND_NAME + + All text following a "." is forwarded to the shell. + + .ls -aF + .uname + BANNER + + def process(cmd) + if cmd =~ /^cd\s*(.*)/i + process_cd parse_destination($1) + else + pass_block(cmd) + if command_block + command_block.call `#{cmd}` + else + _pry_.config.system.call(output, cmd, _pry_) + end + end + end + + private + + def parse_destination(dest) + return "~" if dest.empty? + return dest unless dest == "-" + state.old_pwd || raise(CommandError, "No prior directory available") + end + + def process_cd(dest) + state.old_pwd = Dir.pwd + Dir.chdir File.expand_path(dest) + rescue Errno::ENOENT + raise CommandError, "No such directory: #{dest}" + end + end + + Pry::Commands.add_command(Pry::Command::ShellCommand) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_mode.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_mode.rb new file mode 100644 index 0000000..ee521d3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_mode.rb @@ -0,0 +1,25 @@ +class Pry + class Command::ShellMode < Pry::ClassCommand + match 'shell-mode' + group 'Input and Output' + description 'Toggle shell mode. Bring in pwd prompt and file completion.' + + banner <<-'BANNER' + Toggle shell mode. Bring in pwd prompt and file completion. + BANNER + + def process + case _pry_.prompt + when Pry::SHELL_PROMPT + _pry_.pop_prompt + _pry_.custom_completions = _pry_.config.file_completions + else + _pry_.push_prompt Pry::SHELL_PROMPT + _pry_.custom_completions = _pry_.config.command_completions + end + end + end + + Pry::Commands.add_command(Pry::Command::ShellMode) + Pry::Commands.alias_command 'file-mode', 'shell-mode' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_doc.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_doc.rb new file mode 100644 index 0000000..4969bcd --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_doc.rb @@ -0,0 +1,83 @@ +require 'pry/commands/show_info' + +class Pry + class Command::ShowDoc < Command::ShowInfo + include Pry::Helpers::DocumentationHelpers + + match 'show-doc' + group 'Introspection' + description 'Show the documentation for a method or class.' + + banner <<-BANNER + Usage: show-doc [OPTIONS] [METH] + Aliases: ? + + Show the documentation for a method or class. Tries instance methods first and + then methods by default. + + show-doc hi_method # docs for hi_method + show-doc Pry # for Pry class + show-doc Pry -a # for all definitions of Pry class (all monkey patches) + BANNER + + # The docs for code_object prepared for display. + def content_for(code_object) + Code.new(render_doc_markup_for(code_object), + start_line_for(code_object), :text). + with_line_numbers(use_line_numbers?).to_s + end + + # process the markup (if necessary) and apply colors + def render_doc_markup_for(code_object) + docs = docs_for(code_object) + + if code_object.command? + # command '--help' shouldn't use markup highlighting + docs + else + if docs.empty? + raise CommandError, "No docs found for: #{ + obj_name ? obj_name : 'current context' + }" + end + process_comment_markup(docs) + end + end + + # Return docs for the code_object, adjusting for whether the code_object + # has yard docs available, in which case it returns those. + # (note we only have to check yard docs for modules since they can + # have multiple docs, but methods can only be doc'd once so we + # dont need to check them) + def docs_for(code_object) + if code_object.module_with_yard_docs? + # yard docs + code_object.yard_doc + else + # normal docs (i.e comments above method/module/command) + code_object.doc + end + end + + # Which sections to include in the 'header', can toggle: :owner, + # :signature and visibility. + def header_options + super.merge :signature => true + end + + # figure out start line of docs by back-calculating based on + # number of lines in the comment and the start line of the code_object + # @return [Fixnum] start line of docs + def start_line_for(code_object) + if code_object.command? || opts.present?(:'base-one') + 1 + else + code_object.source_line.nil? ? 1 : + (code_object.source_line - code_object.doc.lines.count) + end + end + end + + Pry::Commands.add_command(Pry::Command::ShowDoc) + Pry::Commands.alias_command '?', 'show-doc' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_info.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_info.rb new file mode 100644 index 0000000..92958cb --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_info.rb @@ -0,0 +1,195 @@ +class Pry + class Command::ShowInfo < Pry::ClassCommand + extend Pry::Helpers::BaseHelpers + + command_options :shellwords => false, :interpolate => false + + def options(opt) + opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors", :as => :count + opt.on :l, "line-numbers", "Show line numbers" + opt.on :b, "base-one", "Show line numbers but start numbering at 1 (useful for `amend-line` and `play` commands)" + opt.on :a, :all, "Show all definitions and monkeypatches of the module/class" + end + + def process + code_object = Pry::CodeObject.lookup(obj_name, _pry_, :super => opts[:super]) + raise CommandError, no_definition_message if !code_object + @original_code_object = code_object + + if show_all_modules?(code_object) + # show all monkey patches for a module + + result = content_and_headers_for_all_module_candidates(code_object) + else + # show a specific code object + co = code_object_with_accessible_source(code_object) + result = content_and_header_for_code_object(co) + end + + set_file_and_dir_locals(code_object.source_file) + _pry_.pager.page result + end + + # This method checks whether the `code_object` is a WrappedModule, + # if it is, then it returns the first candidate (monkeypatch) with + # accessible source (or docs). If `code_object` is not a WrappedModule (i.e a + # method or a command) then the `code_object` itself is just + # returned. + # + # @return [Pry::WrappedModule, Pry::Method, Pry::Command] + def code_object_with_accessible_source(code_object) + if code_object.is_a?(WrappedModule) + candidate = code_object.candidates.find(&:source) + if candidate + return candidate + else + raise CommandError, no_definition_message if !valid_superclass?(code_object) + + @used_super = true + code_object_with_accessible_source(code_object.super) + end + else + code_object + end + end + + def valid_superclass?(code_object) + code_object.super && code_object.super.wrapped != Object + end + + def content_and_header_for_code_object(code_object) + header(code_object) << content_for(code_object) + end + + def content_and_headers_for_all_module_candidates(mod) + result = "Found #{mod.number_of_candidates} candidates for `#{mod.name}` definition:\n" + mod.number_of_candidates.times do |v| + candidate = mod.candidate(v) + begin + result << "\nCandidate #{v+1}/#{mod.number_of_candidates}: #{candidate.source_file} @ line #{candidate.source_line}:\n" + content = content_for(candidate) + + result << "Number of lines: #{content.lines.count}\n\n" << content + rescue Pry::RescuableException + result << "\nNo content found.\n" + next + end + end + result + end + + def no_definition_message + "Couldn't locate a definition for #{obj_name}!" + end + + # Generate a header (meta-data information) for all the code + # object types: methods, modules, commands, procs... + def header(code_object) + file_name, line_num = file_and_line_for(code_object) + h = "\n#{Pry::Helpers::Text.bold('From:')} #{file_name} " + h << code_object_header(code_object, line_num) + h << "\n#{Pry::Helpers::Text.bold('Number of lines:')} " << + "#{content_for(code_object).lines.count}\n\n" + h << Helpers::Text.bold('** Warning:') << " Cannot find code for #{@original_code_object.nonblank_name}. Showing superclass #{code_object.nonblank_name} instead. **\n\n" if @used_super + h + end + + def code_object_header(code_object, line_num) + if code_object.real_method_object? + method_header(code_object, line_num) + + # It sucks we have to test for both Pry::WrappedModule and WrappedModule::Candidate, + # probably indicates a deep refactor needs to happen in those classes. + elsif code_object.is_a?(Pry::WrappedModule) || code_object.is_a?(Pry::WrappedModule::Candidate) + module_header(code_object, line_num) + else + "" + end + end + + def method_header(code_object, line_num) + h = "" + h << (code_object.c_method? ? "(C Method):" : "@ line #{line_num}:") + h << method_sections(code_object)[:owner] + h << method_sections(code_object)[:visibility] + h << method_sections(code_object)[:signature] + h + end + + def module_header(code_object, line_num) + h = "" + h << "@ line #{line_num}:\n" + h << text.bold(code_object.module? ? "Module" : "Class") + h << " #{text.bold('name:')} #{code_object.nonblank_name}" + + if code_object.number_of_candidates > 1 + h << (text.bold("\nNumber of monkeypatches: ") << code_object.number_of_candidates.to_s) + h << ". Use the `-a` option to display all available monkeypatches" + end + h + end + + def method_sections(code_object) + { + :owner => "\n#{text.bold("Owner:")} #{code_object.owner || "N/A"}\n", + :visibility => "#{text.bold("Visibility:")} #{code_object.visibility}", + :signature => "\n#{text.bold("Signature:")} #{code_object.signature}" + }.merge(header_options) { |key, old, new| (new && old).to_s } + end + + def header_options + { + :owner => true, + :visibility => true, + :signature => nil + } + end + + def show_all_modules?(code_object) + code_object.is_a?(Pry::WrappedModule) && opts.present?(:all) + end + + def obj_name + @obj_name ||= args.empty? ? nil : args.join(' ') + end + + def use_line_numbers? + opts.present?(:b) || opts.present?(:l) + end + + def start_line_for(code_object) + if opts.present?(:'base-one') + 1 + else + code_object.source_line || 1 + end + end + + # takes into account possible yard docs, and returns yard_file / yard_line + # Also adjusts for start line of comments (using start_line_for), which it has to infer + # by subtracting number of lines of comment from start line of code_object + def file_and_line_for(code_object) + if code_object.module_with_yard_docs? + [code_object.yard_file, code_object.yard_line] + else + [code_object.source_file, start_line_for(code_object)] + end + end + + def complete(input) + if input =~ /([^ ]*)#([a-z0-9_]*)\z/ + prefix, search = [$1, $2] + methods = begin + Pry::Method.all_from_class(binding.eval(prefix)) + rescue RescuableException + return super + end + methods.map do |method| + [prefix, method.name].join('#') if method.name.start_with?(search) + end.compact + else + super + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_input.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_input.rb new file mode 100644 index 0000000..8b72787 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_input.rb @@ -0,0 +1,17 @@ +class Pry + class Command::ShowInput < Pry::ClassCommand + match 'show-input' + group 'Editing' + description 'Show the contents of the input buffer for the current multi-line expression.' + + banner <<-'BANNER' + Show the contents of the input buffer for the current multi-line expression. + BANNER + + def process + output.puts Code.new(eval_string).with_line_numbers + end + end + + Pry::Commands.add_command(Pry::Command::ShowInput) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_source.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_source.rb new file mode 100644 index 0000000..f3f069e --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_source.rb @@ -0,0 +1,50 @@ +require 'pry/commands/show_info' + +class Pry + class Command::ShowSource < Command::ShowInfo + match 'show-source' + group 'Introspection' + description 'Show the source for a method or class.' + + banner <<-'BANNER' + Usage: show-source [OPTIONS] [METH|CLASS] + Aliases: $, show-method + + Show the source for a method or class. Tries instance methods first and then + methods by default. + + show-source hi_method + show-source hi_method + show-source Pry#rep # source for Pry#rep method + show-source Pry # for Pry class + show-source Pry -a # for all Pry class definitions (all monkey patches) + show-source Pry.foo -e # for class of the return value of expression `Pry.foo` + show-source Pry --super # for superclass of Pry (Object class) + + https://github.com/pry/pry/wiki/Source-browsing#wiki-Show_method + BANNER + + def options(opt) + opt.on :e, :eval, "evaluate the command's argument as a ruby expression and show the class its return value" + super(opt) + end + + def process + if opts.present?(:e) + obj = target.eval(args.first) + self.args = Array.new(1) { Module === obj ? obj.name : obj.class.name } + end + super + end + + # The source for code_object prepared for display. + def content_for(code_object) + Code.new(code_object.source, start_line_for(code_object)). + with_line_numbers(use_line_numbers?) + end + end + + Pry::Commands.add_command(Pry::Command::ShowSource) + Pry::Commands.alias_command 'show-method', 'show-source' + Pry::Commands.alias_command '$', 'show-source' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/simple_prompt.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/simple_prompt.rb new file mode 100644 index 0000000..4d1e6ec --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/simple_prompt.rb @@ -0,0 +1,22 @@ +class Pry + class Command::SimplePrompt < Pry::ClassCommand + match 'simple-prompt' + group 'prompts' + description 'Toggle the simple prompt.' + + banner <<-'BANNER' + Toggle the simple prompt. + BANNER + + def process + case _pry_.prompt + when Pry::SIMPLE_PROMPT + _pry_.pop_prompt + else + _pry_.push_prompt Pry::SIMPLE_PROMPT + end + end + end + + Pry::Commands.add_command(Pry::Command::SimplePrompt) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/stat.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/stat.rb new file mode 100644 index 0000000..06a191b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/stat.rb @@ -0,0 +1,40 @@ +class Pry + class Command::Stat < Pry::ClassCommand + match 'stat' + group 'Introspection' + description 'View method information and set _file_ and _dir_ locals.' + command_options :shellwords => false + + banner <<-'BANNER' + Usage: stat [OPTIONS] [METH] + + Show method information for method METH and set _file_ and _dir_ locals. + + stat hello_method + BANNER + + def options(opt) + method_options(opt) + end + + def process + meth = method_object + aliases = meth.aliases + + output.puts unindent <<-EOS + Method Information: + -- + Name: #{meth.name} + Alias#{ "es" if aliases.length > 1 }: #{ aliases.any? ? aliases.join(", ") : "None." } + Owner: #{meth.owner ? meth.owner : "Unknown"} + Visibility: #{meth.visibility} + Type: #{meth.is_a?(::Method) ? "Bound" : "Unbound"} + Arity: #{meth.arity} + Method Signature: #{meth.signature} + Source Location: #{meth.source_location ? meth.source_location.join(":") : "Not found."} + EOS + end + end + + Pry::Commands.add_command(Pry::Command::Stat) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/switch_to.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/switch_to.rb new file mode 100644 index 0000000..ad3e71c --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/switch_to.rb @@ -0,0 +1,23 @@ +class Pry + class Command::SwitchTo < Pry::ClassCommand + match 'switch-to' + group 'Navigating Pry' + description 'Start a new subsession on a binding in the current stack.' + + banner <<-'BANNER' + Start a new subsession on a binding in the current stack (numbered by nesting). + BANNER + + def process(selection) + selection = selection.to_i + + if selection < 0 || selection > _pry_.binding_stack.size - 1 + raise CommandError, "Invalid binding index #{selection} - use `nesting` command to view valid indices." + else + Pry.start(_pry_.binding_stack[selection]) + end + end + end + + Pry::Commands.add_command(Pry::Command::SwitchTo) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/toggle_color.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/toggle_color.rb new file mode 100644 index 0000000..602c293 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/toggle_color.rb @@ -0,0 +1,24 @@ +class Pry + class Command::ToggleColor < Pry::ClassCommand + match 'toggle-color' + group 'Misc' + description 'Toggle syntax highlighting.' + + banner <<-'BANNER' + Usage: toggle-color + + Toggle syntax highlighting. + BANNER + + def process + _pry_.color = color_toggle + output.puts "Syntax highlighting #{_pry_.color ? "on" : "off"}" + end + + def color_toggle + !_pry_.color + end + + Pry::Commands.add_command(self) + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression.rb new file mode 100644 index 0000000..52a88af --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression.rb @@ -0,0 +1,105 @@ +class Pry + class Command::WatchExpression < Pry::ClassCommand + require 'pry/commands/watch_expression/expression.rb' + + match 'watch' + group 'Context' + description 'Watch the value of an expression and print a notification whenever it changes.' + command_options :use_prefix => false + + banner <<-'BANNER' + Usage: watch [EXPRESSION] + watch + watch --delete [INDEX] + + watch [EXPRESSION] adds an expression to the list of those being watched. + It will be re-evaluated every time you hit enter in pry. If its value has + changed, the new value will be printed to the console. + + This is useful if you are step-through debugging and want to see how + something changes over time. It's also useful if you're trying to write + a method inside pry and want to check that it gives the right answers + every time you redefine it. + + watch on its own displays all the currently watched expressions and their + values, and watch --delete [INDEX] allows you to delete expressions from + the list being watched. + BANNER + + def options(opt) + opt.on :d, :delete, + "Delete the watch expression with the given index. If no index is given; clear all watch expressions.", + :optional_argument => true, :as => Integer + opt.on :l, :list, + "Show all current watch expressions and their values. Calling watch with no expressions or options will also show the watch expressions." + end + + def process + case + when opts.present?(:delete) + delete opts[:delete] + when opts.present?(:list) || args.empty? + list + else + add_hook + add_expression(args) + end + end + + private + + def expressions + _pry_.config.watch_expressions ||= [] + end + + def delete(index) + if index + output.puts "Deleting watch expression ##{index}: #{expressions[index-1]}" + expressions.delete_at(index-1) + else + output.puts "Deleting all watched expressions" + expressions.clear + end + end + + def list + if expressions.empty? + output.puts "No watched expressions" + else + _pry_.pager.open do |pager| + pager.puts "Listing all watched expressions:" + pager.puts "" + expressions.each_with_index do |expr, index| + pager.print text.with_line_numbers(expr.to_s, index+1) + end + pager.puts "" + end + end + end + + def eval_and_print_changed(output) + expressions.each do |expr| + expr.eval! + if expr.changed? + output.puts "#{text.blue "watch"}: #{expr.to_s}" + end + end + end + + def add_expression(arguments) + expressions << Expression.new(_pry_, target, arg_string) + output.puts "Watching #{Code.new(arg_string)}" + end + + def add_hook + hook = [:after_eval, :watch_expression] + unless _pry_.hooks.hook_exists?(*hook) + _pry_.hooks.add_hook(*hook) do |_, _pry_| + eval_and_print_changed _pry_.output + end + end + end + end + + Pry::Commands.add_command(Pry::Command::WatchExpression) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression/expression.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression/expression.rb new file mode 100644 index 0000000..a73b401 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression/expression.rb @@ -0,0 +1,38 @@ +class Pry + class Command::WatchExpression + class Expression + attr_reader :target, :source, :value, :previous_value, :_pry_ + + def initialize(_pry_, target, source) + @_pry_ = _pry_ + @target = target + @source = source.strip + end + + def eval! + @previous_value = @value + @value = Pry::ColorPrinter.pp(target_eval(target, source), "") + end + + def to_s + "#{Code.new(source).strip} => #{value}" + end + + # Has the value of the expression changed? + # + # We use the pretty-printed string represenation to detect differences + # as this avoids problems with dup (causes too many differences) and == (causes too few) + def changed? + (value != previous_value) + end + + private + + def target_eval(target, source) + target.eval(source) + rescue => e + e + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/whereami.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/whereami.rb new file mode 100644 index 0000000..695ecc9 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/whereami.rb @@ -0,0 +1,190 @@ +class Pry + class Command::Whereami < Pry::ClassCommand + + class << self + attr_accessor :method_size_cutoff + end + + @method_size_cutoff = 30 + + match 'whereami' + description 'Show code surrounding the current context.' + group 'Context' + + banner <<-'BANNER' + Usage: whereami [-qn] [LINES] + + Describe the current location. If you use `binding.pry` inside a method then + whereami will print out the source for that method. + + If a number is passed, then LINES lines before and after the current line will be + shown instead of the method itself. + + The `-q` flag can be used to suppress error messages in the case that there's + no code to show. This is used by pry in the default before_session hook to show + you when you arrive at a `binding.pry`. + + The `-n` flag can be used to hide line numbers so that code can be copy/pasted + effectively. + + When pry was started on an Object and there is no associated method, whereami + will instead output a brief description of the current object. + BANNER + + def setup + @file = expand_path(target.eval('__FILE__')) + @line = target.eval('__LINE__') + @method = Pry::Method.from_binding(target) + end + + def options(opt) + opt.on :q, :quiet, "Don't display anything in case of an error" + opt.on :n, :"no-line-numbers", "Do not display line numbers" + opt.on :m, :"method", "Show the complete source for the current method." + opt.on :c, :"class", "Show the complete source for the current class or module." + opt.on :f, :"file", "Show the complete source for the current file." + end + + def code + @code ||= if opts.present?(:m) + method_code or raise CommandError, "Cannot find method code." + elsif opts.present?(:c) + class_code or raise CommandError, "Cannot find class code." + elsif opts.present?(:f) + Pry::Code.from_file(@file) + elsif args.any? + code_window + else + default_code + end + end + + def code? + !!code + rescue MethodSource::SourceNotFoundError + false + end + + def bad_option_combination? + [opts.present?(:m), opts.present?(:f), + opts.present?(:c), args.any?].count(true) > 1 + end + + def location + "#{@file} @ line #{@line} #{@method && @method.name_with_owner}" + end + + def process + if bad_option_combination? + raise CommandError, "Only one of -m, -c, -f, and LINES may be specified." + end + + if nothing_to_do? + return + elsif internal_binding?(target) + handle_internal_binding + return + end + + set_file_and_dir_locals(@file) + + out = "\n#{text.bold('From:')} #{location}:\n\n" << + code.with_line_numbers(use_line_numbers?).with_marker(marker) << "\n" + + _pry_.pager.page out + end + + private + + def nothing_to_do? + opts.quiet? && (internal_binding?(target) || !code?) + end + + def use_line_numbers? + !opts.present?(:n) + end + + def marker + !opts.present?(:n) && @line + end + + def top_level? + target_self == Pry.main + end + + def handle_internal_binding + if top_level? + output.puts "At the top level." + else + output.puts "Inside #{Pry.view_clip(target_self)}." + end + end + + def small_method? + @method.source_range.count < self.class.method_size_cutoff + end + + def default_code + if method_code && small_method? + method_code + else + code_window + end + end + + def code_window + Pry::Code.from_file(@file).around(@line, window_size) + end + + def method_code + return @method_code if @method_code + + if valid_method? + @method_code = Pry::Code.from_method(@method) + end + end + + # This either returns the `target_self` + # or it returns the class of `target_self` if `target_self` is not a class. + # @return [Pry::WrappedModule] + def target_class + target_self.is_a?(Module) ? Pry::WrappedModule(target_self) : + Pry::WrappedModule(target_self.class) + end + + def class_code + return @class_code if @class_code + + mod = @method ? Pry::WrappedModule(@method.owner) : target_class + + idx = mod.candidates.find_index { |v| expand_path(v.source_file) == @file } + @class_code = idx && Pry::Code.from_module(mod, idx) + end + + def valid_method? + @method && @method.source? && expand_path(@method.source_file) == @file && + @method.source_range.include?(@line) + end + + def expand_path(f) + return if !f + + if Pry.eval_path == f + f + else + File.expand_path(f) + end + end + + def window_size + if args.empty? + _pry_.config.default_window_size + else + args.first.to_i + end + end + end + + Pry::Commands.add_command(Pry::Command::Whereami) + Pry::Commands.alias_command '@', 'whereami' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/wtf.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/wtf.rb new file mode 100644 index 0000000..2d47dfa --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/wtf.rb @@ -0,0 +1,57 @@ +class Pry + class Command::Wtf < Pry::ClassCommand + match(/wtf([?!]*)/) + group 'Context' + description 'Show the backtrace of the most recent exception.' + options :listing => 'wtf?' + + banner <<-'BANNER' + Usage: wtf[?|!] + + Show's a few lines of the backtrace of the most recent exception (also available + as `_ex_.backtrace`). If you want to see more lines, add more question marks or + exclamation marks. + + wtf? + wtf?!???!?!? + + # To see the entire backtrace, pass the `-v` or `--verbose` flag. + wtf -v + BANNER + + def options(opt) + opt.on :v, :verbose, "Show the full backtrace" + end + + def process + raise Pry::CommandError, "No most-recent exception" unless exception + + output.puts "#{text.bold('Exception:')} #{exception.class}: #{exception}\n--" + if opts.verbose? + output.puts with_line_numbers(backtrace) + else + output.puts with_line_numbers(backtrace.first(size_of_backtrace)) + end + end + + private + + def exception + _pry_.last_exception + end + + def with_line_numbers(bt) + Pry::Code.new(bt, 0, :text).with_line_numbers.to_s + end + + def backtrace + exception.backtrace + end + + def size_of_backtrace + [captures[0].size, 0.5].max * 10 + end + end + + Pry::Commands.add_command(Pry::Command::Wtf) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/config.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/config.rb new file mode 100644 index 0000000..73b7742 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/config.rb @@ -0,0 +1,24 @@ +class Pry::Config + require_relative 'config/behavior' + require_relative 'config/default' + require_relative 'config/convenience' + include Pry::Config::Behavior + + def self.shortcuts + Convenience::SHORTCUTS + end + + # + # FIXME + # @param [Pry::Hooks] hooks + # + def hooks=(hooks) + if hooks.is_a?(Hash) + warn "Hash-based hooks are now deprecated! Use a `Pry::Hooks` object " \ + "instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks" + self["hooks"] = Pry::Hooks.from_hash(hooks) + else + self["hooks"] = hooks + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/config/behavior.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/config/behavior.rb new file mode 100644 index 0000000..1cb98da --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/config/behavior.rb @@ -0,0 +1,139 @@ +module Pry::Config::Behavior + ASSIGNMENT = "=".freeze + NODUP = [TrueClass, FalseClass, NilClass, Symbol, Numeric, Module, Proc].freeze + INSPECT_REGEXP = /#{Regexp.escape "default=#<"}/ + + module Builder + def from_hash(hash, default = nil) + new(default).tap do |config| + config.merge!(hash) + end + end + end + + def self.included(klass) + unless defined?(RESERVED_KEYS) + const_set :RESERVED_KEYS, instance_methods(false).map(&:to_s).freeze + end + klass.extend(Builder) + end + + def initialize(default = Pry.config) + @default = default + @lookup = {} + end + + # + # @return [Pry::Config::Behavior] + # returns the default used if a matching value for a key isn't found in self + # + def default + @default + end + + def [](key) + @lookup[key.to_s] + end + + def []=(key, value) + key = key.to_s + if RESERVED_KEYS.include?(key) + raise ArgumentError, "few things are reserved by pry, but using '#{key}' as a configuration key is." + end + @lookup[key] = value + end + + def method_missing(name, *args, &block) + key = name.to_s + if key[-1] == ASSIGNMENT + short_key = key[0..-2] + self[short_key] = args[0] + elsif key?(key) + self[key] + elsif @default.respond_to?(name) + value = @default.public_send(name, *args, &block) + # FIXME: refactor Pry::Hook so that it stores config on the config object, + # so that we can use the normal strategy. + self[key] = value.dup if key == 'hooks' + value + else + nil + end + end + + def merge!(other) + other = try_convert_to_hash(other) + raise TypeError, "unable to convert argument into a Hash" unless other + other.each do |key, value| + self[key] = value + end + end + + def ==(other) + @lookup == try_convert_to_hash(other) + end + alias_method :eql?, :== + + def respond_to_missing?(key, include_private=false) + key?(key) or @default.respond_to?(key) or super(key, include_private) + end + + def key?(key) + key = key.to_s + @lookup.key?(key) + end + + def clear + @lookup.clear + true + end + alias_method :refresh, :clear + + def forget(key) + @lookup.delete(key.to_s) + end + + def keys + @lookup.keys + end + + def to_hash + @lookup.dup + end + alias_method :to_h, :to_hash + + + def inspect + key_str = keys.map { |key| "'#{key}'" }.join(",") + "#<#{_clip_inspect(self)} local_keys=[#{key_str}] default=#{@default.inspect}>" + end + + def pretty_print(q) + q.text inspect[1..-1].gsub(INSPECT_REGEXP, "default=<") + end + +private + def _clip_inspect(obj) + "#{obj.class}:0x%x" % obj.object_id << 1 + end + + def _dup(value) + if NODUP.any? { |klass| klass === value } + value + else + value.dup + end + end + + def try_convert_to_hash(obj) + if Hash === obj + obj + elsif obj.respond_to?(:to_h) + obj.to_h + elsif obj.respond_to?(:to_hash) + obj.to_hash + else + nil + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/config/convenience.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/config/convenience.rb new file mode 100644 index 0000000..9d9273d --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/config/convenience.rb @@ -0,0 +1,26 @@ +module Pry::Config::Convenience + SHORTCUTS = [ + :input, + :output, + :commands, + :print, + :exception_handler, + :quiet?, + :hooks, + :color, + :pager, + :editor, + :memory_size, + :extra_sticky_locals + ] + + + def config_shortcut(*names) + names.each do |name| + reader = name + setter = "#{name}=" + define_method(reader) { config.public_send(name) } + define_method(setter) { |value| config.public_send(setter, value) } + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/config/default.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/config/default.rb new file mode 100644 index 0000000..587e27d --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/config/default.rb @@ -0,0 +1,165 @@ +class Pry::Config::Default + include Pry::Config::Behavior + + default = { + input: proc { + lazy_readline + }, + output: proc { + $stdout + }, + commands: proc { + Pry::Commands + }, + prompt_name: proc { + Pry::DEFAULT_PROMPT_NAME + }, + prompt: proc { + Pry::DEFAULT_PROMPT + }, + prompt_safe_objects: proc { + Pry::DEFAULT_PROMPT_SAFE_OBJECTS + }, + print: proc { + Pry::DEFAULT_PRINT + }, + quiet: proc { + false + }, + exception_handler: proc { + Pry::DEFAULT_EXCEPTION_HANDLER + }, + exception_whitelist: proc { + Pry::DEFAULT_EXCEPTION_WHITELIST + }, + hooks: proc { + Pry::DEFAULT_HOOKS + }, + pager: proc { + true + }, + system: proc { + Pry::DEFAULT_SYSTEM + }, + color: proc { + Pry::Helpers::BaseHelpers.use_ansi_codes? + }, + default_window_size: proc { + 5 + }, + editor: proc { + Pry.default_editor_for_platform + }, # TODO: Pry::Platform.editor + should_load_rc: proc { + true + }, + should_load_local_rc: proc { + true + }, + should_trap_interrupts: proc { + Pry::Helpers::BaseHelpers.jruby? + }, # TODO: Pry::Platform.jruby? + disable_auto_reload: proc { + false + }, + command_prefix: proc { + "" + }, + auto_indent: proc { + Pry::Helpers::BaseHelpers.use_ansi_codes? + }, + correct_indent: proc { + true + }, + collision_warning: proc { + false + }, + output_prefix: proc { + "=> " + }, + requires: proc { + [] + }, + should_load_requires: proc { + true + }, + should_load_plugins: proc { + true + }, + windows_console_warning: proc { + true + }, + control_d_handler: proc { + Pry::DEFAULT_CONTROL_D_HANDLER + }, + memory_size: proc { + 100 + }, + extra_sticky_locals: proc { + {} + }, + command_completions: proc { + proc { commands.keys } + }, + file_completions: proc { + proc { Dir["."] } + }, + ls: proc { + Pry::Config.from_hash(Pry::Command::Ls::DEFAULT_OPTIONS) + }, + completer: proc { + require "pry/input_completer" + Pry::InputCompleter + } + } + + def initialize + super(nil) + configure_gist + configure_history + end + + def quiet? + quiet + end + + default.each do |key, value| + define_method(key) do + if default[key].equal?(value) + default[key] = instance_eval(&value) + end + default[key] + end + end + +private + # TODO: + # all of this configure_* stuff is a relic of old code. + # we should try move this code to being command-local. + def configure_gist + self["gist"] = Pry::Config.from_hash(inspecter: proc(&:pretty_inspect)) + end + + def configure_history + self["history"] = Pry::Config.from_hash "should_save" => true, + "should_load" => true + history.file = File.expand_path("~/.pry_history") rescue nil + if history.file.nil? + self.should_load_rc = false + history.should_save = false + history.should_load = false + end + end + + def lazy_readline + require 'readline' + Readline + rescue LoadError + warn "Sorry, you can't use Pry without Readline or a compatible library." + warn "Possible solutions:" + warn " * Rebuild Ruby with Readline support using `--with-readline`" + warn " * Use the rb-readline gem, which is a pure-Ruby port of Readline" + warn " * Use the pry-coolline gem, a pure-ruby alternative to Readline" + raise + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/core_extensions.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/core_extensions.rb new file mode 100644 index 0000000..a418daf --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/core_extensions.rb @@ -0,0 +1,131 @@ +class Pry + # @return [Array] Code of the method used when implementing Pry's + # __binding__, along with line indication to be used with instance_eval (and + # friends). + # + # @see Object#__binding__ + BINDING_METHOD_IMPL = [<<-METHOD, __FILE__, __LINE__ + 1] + # Get a binding with 'self' set to self, and no locals. + # + # The default definee is determined by the context in which the + # definition is eval'd. + # + # Please don't call this method directly, see {__binding__}. + # + # @return [Binding] + def __pry__ + binding + end + METHOD +end + +class Object + # Start a Pry REPL on self. + # + # If `self` is a Binding then that will be used to evaluate expressions; + # otherwise a new binding will be created. + # + # @param [Object] object the object or binding to pry + # (__deprecated__, use `object.pry`) + # @param [Hash] hash the options hash + # @example With a binding + # binding.pry + # @example On any object + # "dummy".pry + # @example With options + # def my_method + # binding.pry :quiet => true + # end + # my_method() + # @see Pry.start + def pry(object=nil, hash={}) + if object.nil? || Hash === object + Pry.start(self, object || {}) + else + Pry.start(object, hash) + end + end + + # Return a binding object for the receiver. + # + # The `self` of the binding is set to the current object, and it contains no + # local variables. + # + # The default definee (http://yugui.jp/articles/846) is set such that: + # + # * If `self` is a class or module, then new methods created in the binding + # will be defined in that class or module (as in `class Foo; end`). + # * If `self` is a normal object, then new methods created in the binding will + # be defined on its singleton class (as in `class << self; end`). + # * If `self` doesn't have a real singleton class (i.e. it is a Fixnum, Float, + # Symbol, nil, true, or false), then new methods will be created on the + # object's class (as in `self.class.class_eval{ }`) + # + # Newly created constants, including classes and modules, will also be added + # to the default definee. + # + # @return [Binding] + def __binding__ + # If you ever feel like changing this method, be careful about variables + # that you use. They shouldn't be inserted into the binding that will + # eventually be returning. + + # When you're cd'd into a class, methods you define should be added to it. + if is_a?(Module) + # class_eval sets both self and the default definee to this class. + return class_eval "binding" + end + + unless respond_to?(:__pry__) + # The easiest way to check whether an object has a working singleton class + # is to try and define a method on it. (just checking for the presence of + # the singleton class gives false positives for `true` and `false`). + # __pry__ is just the closest method we have to hand, and using + # it has the nice property that we can memoize this check. + begin + # instance_eval sets the default definee to the object's singleton class + instance_eval(*Pry::BINDING_METHOD_IMPL) + + # If we can't define methods on the Object's singleton_class. Then we fall + # back to setting the default definee to be the Object's class. That seems + # nicer than having a REPL in which you can't define methods. + rescue TypeError, Pry::FrozenObjectException + # class_eval sets the default definee to self.class + self.class.class_eval(*Pry::BINDING_METHOD_IMPL) + end + end + + __pry__ + end +end + +class BasicObject + # Return a binding object for the receiver. + # + # The `self` of the binding is set to the current object, and it contains no + # local variables. + # + # The default definee (http://yugui.jp/articles/846) is set such that new + # methods defined will be added to the singleton class of the BasicObject. + # + # @return [Binding] + def __binding__ + # BasicObjects don't have respond_to?, so we just define the method + # every time. As they also don't have `.freeze`, this call won't + # fail as it can for normal Objects. + (class << self; self; end).class_eval <<-EOF, __FILE__, __LINE__ + 1 + # Get a binding with 'self' set to self, and no locals. + # + # The default definee is determined by the context in which the + # definition is eval'd. + # + # Please don't call this method directly, see {__binding__}. + # + # @return [Binding] + def __pry__ + ::Kernel.binding + end + EOF + self.__pry__ + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/editor.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/editor.rb new file mode 100644 index 0000000..a833f70 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/editor.rb @@ -0,0 +1,133 @@ +class Pry + class Editor + include Pry::Helpers::BaseHelpers + include Pry::Helpers::CommandHelpers + + attr_reader :_pry_ + + def initialize(_pry_) + @_pry_ = _pry_ + end + + def edit_tempfile_with_content(initial_content, line=1) + temp_file do |f| + f.puts(initial_content) + f.flush + f.close(false) + invoke_editor(f.path, line, true) + File.read(f.path) + end + end + + def invoke_editor(file, line, blocking=true) + raise CommandError, "Please set Pry.config.editor or export $VISUAL or $EDITOR" unless _pry_.config.editor + + editor_invocation = build_editor_invocation_string(file, line, blocking) + return nil unless editor_invocation + + if jruby? + open_editor_on_jruby(editor_invocation) + else + open_editor(editor_invocation) + end + end + + private + + # Generate the string that's used to start the editor. This includes + # all the flags we want as well as the file and line number we + # want to open at. + def build_editor_invocation_string(file, line, blocking) + + if _pry_.config.editor.respond_to?(:call) + args = [file, line, blocking][0...(_pry_.config.editor.arity)] + _pry_.config.editor.call(*args) + else + sanitized_file = if windows? + file.gsub(/\//, '\\') + else + Shellwords.escape(file) + end + + "#{_pry_.config.editor} #{blocking_flag_for_editor(blocking)} #{start_line_syntax_for_editor(sanitized_file, line)}" + end + end + + # Start the editor running, using the calculated invocation string + def open_editor(editor_invocation) + # Note we dont want to use Pry.config.system here as that + # may be invoked non-interactively (i.e via Open4), whereas we want to + # ensure the editor is always interactive + system(*Shellwords.split(editor_invocation)) or raise CommandError, "`#{editor_invocation}` gave exit status: #{$?.exitstatus}" + end + + # We need JRuby specific code here cos just shelling out using + # system() appears to be pretty broken :/ + def open_editor_on_jruby(editor_invocation) + begin + require 'spoon' + pid = Spoon.spawnp(*Shellwords.split(editor_invocation)) + Process.waitpid(pid) + rescue FFI::NotFoundError + system(editor_invocation) + end + end + + # Some editors that run outside the terminal allow you to control whether or + # not to block the process from which they were launched (in this case, Pry). + # For those editors, return the flag that produces the desired behavior. + def blocking_flag_for_editor(blocking) + case editor_name + when /^emacsclient/ + '--no-wait' unless blocking + when /^[gm]vim/ + '--nofork' if blocking + when /^jedit/ + '-wait' if blocking + when /^mate/, /^subl/ + '-w' if blocking + end + end + + # Return the syntax for a given editor for starting the editor + # and moving to a particular line within that file + def start_line_syntax_for_editor(file_name, line_number) + # special case for 1st line + return file_name if line_number <= 1 + + case editor_name + when /^[gm]?vi/, /^emacs/, /^nano/, /^pico/, /^gedit/, /^kate/ + "+#{line_number} #{file_name}" + when /^mate/, /^geany/ + "-l #{line_number} #{file_name}" + when /^subl/ + "#{file_name}:#{line_number}" + when /^uedit32/ + "#{file_name}/#{line_number}" + when /^jedit/ + "#{file_name} +line:#{line_number}" + else + if windows? + "#{file_name}" + else + "+#{line_number} #{file_name}" + end + end + end + + # Get the name of the binary that Pry.config.editor points to. + # + # This is useful for deciding which flags we pass to the editor as + # we can just use the program's name and ignore any absolute paths. + # + # @example + # Pry.config.editor="/home/conrad/bin/textmate -w" + # editor_name + # # => textmate + # + def editor_name + File.basename(_pry_.config.editor).split(" ").first + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/exceptions.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/exceptions.rb new file mode 100644 index 0000000..0204d84 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/exceptions.rb @@ -0,0 +1,77 @@ +class Pry + + # As a REPL, we often want to catch any unexpected exceptions that may have + # been raised; however we don't want to go overboard and prevent the user + # from exiting Pry when they want to. + module RescuableException + def self.===(exception) + case exception + # Catch when the user hits ^C (Interrupt < SignalException), and assume + # that they just wanted to stop the in-progress command (just like bash + # etc.) + when Interrupt + true + # Don't catch signals (particularly not SIGTERM) as these are unlikely + # to be intended for pry itself. We should also make sure that + # Kernel#exit works. + when *Pry.config.exception_whitelist + false + # All other exceptions will be caught. + else + true + end + end + end + + # Catches SecurityErrors if $SAFE is set + module Pry::TooSafeException + def self.===(exception) + $SAFE > 0 && SecurityError === exception + end + end + + # An Exception Tag (cf. Exceptional Ruby) that instructs Pry to show the error + # in a more user-friendly manner. This should be used when the exception + # happens within Pry itself as a direct consequence of the user typing + # something wrong. + # + # This allows us to distinguish between the user typing: + # + # pry(main)> def ) + # SyntaxError: unexpected ) + # + # pry(main)> method_that_evals("def )") + # SyntaxError: (eval):1: syntax error, unexpected ')' + # from ./a.rb:2 in `eval' + module UserError; end + + # When we try to get a binding for an object, we try to define a method on + # that Object's singleton class. This doesn't work for "frozen" Object's, and + # the exception is just a vanilla RuntimeError. + module FrozenObjectException + def self.===(exception) + ["can't modify frozen class/module", + "can't modify frozen Class", + ].include?(exception.message) + end + end + + # Don't catch these exceptions + DEFAULT_EXCEPTION_WHITELIST = [SystemExit, + SignalException, + Pry::TooSafeException] + + # CommandErrors are caught by the REPL loop and displayed to the user. They + # indicate an exceptional condition that's fatal to the current command. + class CommandError < StandardError; end + class MethodNotFound < CommandError; end + + # indicates obsolete API + class ObsoleteError < StandardError; end + + # This is to keep from breaking under Rails 3.2 for people who are doing that + # IRB = Pry thing. + module ExtendCommandBundle + end + +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers.rb new file mode 100644 index 0000000..f59c308 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers.rb @@ -0,0 +1,5 @@ +require "pry/helpers/base_helpers" +require "pry/helpers/options_helpers" +require "pry/helpers/command_helpers" +require "pry/helpers/text" +require "pry/helpers/table" diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/base_helpers.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/base_helpers.rb new file mode 100644 index 0000000..5dade46 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/base_helpers.rb @@ -0,0 +1,113 @@ +class Pry + module Helpers + + module BaseHelpers + + module_function + + def silence_warnings + old_verbose = $VERBOSE + $VERBOSE = nil + begin + yield + ensure + $VERBOSE = old_verbose + end + end + + # Acts like send but ignores any methods defined below Object or Class in the + # inheritance hierarchy. + # This is required to introspect methods on objects like Net::HTTP::Get that + # have overridden the `method` method. + def safe_send(obj, method, *args, &block) + (Module === obj ? Module : Object).instance_method(method).bind(obj).call(*args, &block) + end + public :safe_send + + def find_command(name, set = Pry::Commands) + command_match = set.find do |_, command| + (listing = command.options[:listing]) == name && listing != nil + end + command_match.last if command_match + end + + def not_a_real_file?(file) + file =~ /(\(.*\))|<.*>/ || file =~ /__unknown__/ || file == "" || file == "-e" + end + + def command_dependencies_met?(options) + return true if !options[:requires_gem] + Array(options[:requires_gem]).all? do |g| + Rubygem.installed?(g) + end + end + + def use_ansi_codes? + windows_ansi? || ENV['TERM'] && ENV['TERM'] != "dumb" + end + + def colorize_code(code) + CodeRay.scan(code, :ruby).term + end + + def highlight(string, regexp, highlight_color=:bright_yellow) + string.gsub(regexp) { |match| "<#{highlight_color}>#{match}" } + end + + # formatting + def heading(text) + text = "#{text}\n--" + "\e[1m#{text}\e[0m" + end + + # have fun on the Windows platform. + def windows? + RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ + end + + # are we able to use ansi on windows? + def windows_ansi? + defined?(Win32::Console) || ENV['ANSICON'] || (windows? && mri_2?) + end + + def jruby? + RbConfig::CONFIG['ruby_install_name'] == 'jruby' + end + + def jruby_19? + jruby? && RbConfig::CONFIG['ruby_version'] == '1.9' + end + + def rbx? + RbConfig::CONFIG['ruby_install_name'] == 'rbx' + end + + def mri? + RbConfig::CONFIG['ruby_install_name'] == 'ruby' + end + + def mri_19? + mri? && RUBY_VERSION =~ /^1\.9/ + end + + def mri_2? + mri? && RUBY_VERSION =~ /^2/ + end + + def mri_20? + mri? && RUBY_VERSION =~ /^2\.0/ + end + + def mri_21? + mri? && RUBY_VERSION =~ /^2\.1/ + end + + # Send the given text through the best available pager (if Pry.config.pager is + # enabled). Infers where to send the output if used as a mixin. + # DEPRECATED. + def stagger_output(text, out = nil) + Pry.new.pager.page text + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/command_helpers.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/command_helpers.rb new file mode 100644 index 0000000..7f7e226 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/command_helpers.rb @@ -0,0 +1,156 @@ +class Pry + module Helpers + + module CommandHelpers + include OptionsHelpers + + module_function + + # Open a temp file and yield it to the block, closing it after + # @return [String] The path of the temp file + def temp_file(ext='.rb') + file = Tempfile.new(['pry', ext]) + yield file + ensure + file.close(true) if file + end + + def internal_binding?(target) + m = target.eval("::Kernel.__method__").to_s + # class_eval is here because of http://jira.codehaus.org/browse/JRUBY-6753 + ["__binding__", "__pry__", "class_eval"].include?(m) + end + + def get_method_or_raise(name, target, opts={}, omit_help=false) + meth = Pry::Method.from_str(name, target, opts) + + if name && !meth + command_error("The method '#{name}' could not be found.", omit_help, MethodNotFound) + end + + (opts[:super] || 0).times do + if meth.super + meth = meth.super + else + command_error("'#{meth.name_with_owner}' has no super method.", omit_help, MethodNotFound) + end + end + + if !meth || (!name && internal_binding?(target)) + command_error("No method name given, and context is not a method.", omit_help, MethodNotFound) + end + + set_file_and_dir_locals(meth.source_file) + meth + end + + def command_error(message, omit_help, klass=CommandError) + message += " Type `#{command_name} --help` for help." unless omit_help + raise klass, message + end + + # Remove any common leading whitespace from every line in `text`. + # + # This can be used to make a HEREDOC line up with the left margin, without + # sacrificing the indentation level of the source code. + # + # e.g. + # opt.banner unindent <<-USAGE + # Lorem ipsum dolor sit amet, consectetur adipisicing elit, + # sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + # "Ut enim ad minim veniam." + # USAGE + # + # Heavily based on textwrap.dedent from Python, which is: + # Copyright (C) 1999-2001 Gregory P. Ward. + # Copyright (C) 2002, 2003 Python Software Foundation. + # Written by Greg Ward + # + # Licensed under + # From + # + # @param [String] text The text from which to remove indentation + # @return [String] The text with indentation stripped. + def unindent(text, left_padding = 0) + # Empty blank lines + text = text.sub(/^[ \t]+$/, '') + + # Find the longest common whitespace to all indented lines + # Ignore lines containing just -- or ++ as these seem to be used by + # comment authors as delimeters. + margin = text.scan(/^[ \t]*(?!--\n|\+\+\n)(?=[^ \t\n])/).inject do |current_margin, next_indent| + if next_indent.start_with?(current_margin) + current_margin + elsif current_margin.start_with?(next_indent) + next_indent + else + "" + end + end + + text.gsub(/^#{margin}/, ' ' * left_padding) + end + + # Restrict a string to the given range of lines (1-indexed) + # @param [String] content The string. + # @param [Range, Fixnum] lines The line(s) to restrict it to. + # @return [String] The resulting string. + def restrict_to_lines(content, lines) + line_range = one_index_range_or_number(lines) + Array(content.lines.to_a[line_range]).join + end + + def one_index_number(line_number) + if line_number > 0 + line_number - 1 + else + line_number + end + end + + # convert a 1-index range to a 0-indexed one + def one_index_range(range) + Range.new(one_index_number(range.begin), one_index_number(range.end)) + end + + def one_index_range_or_number(range_or_number) + case range_or_number + when Range + one_index_range(range_or_number) + else + one_index_number(range_or_number) + end + end + + def absolute_index_number(line_number, array_length) + if line_number >= 0 + line_number + else + [array_length + line_number, 0].max + end + end + + def absolute_index_range(range_or_number, array_length) + case range_or_number + when Range + a = absolute_index_number(range_or_number.begin, array_length) + b = absolute_index_number(range_or_number.end, array_length) + else + a = b = absolute_index_number(range_or_number, array_length) + end + + Range.new(a, b) + end + + def set_file_and_dir_locals(file_name, _pry_=_pry_(), target=target()) + return if !target or !file_name + _pry_.last_file = File.expand_path(file_name) + _pry_.inject_local("_file_", _pry_.last_file, target) + + _pry_.last_dir = File.dirname(_pry_.last_file) + _pry_.inject_local("_dir_", _pry_.last_dir, target) + end + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/documentation_helpers.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/documentation_helpers.rb new file mode 100644 index 0000000..9f9870e --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/documentation_helpers.rb @@ -0,0 +1,75 @@ +class Pry + module Helpers + + # This class contains methods useful for extracting + # documentation from methods and classes. + module DocumentationHelpers + + module_function + + def process_rdoc(comment) + comment = comment.dup + comment.gsub(/(?:\s*\n)?(.*?)\s*<\/code>/m) { CodeRay.scan($1, :ruby).term }. + gsub(/(?:\s*\n)?(.*?)\s*<\/em>/m) { "\e[1m#{$1}\e[0m" }. + gsub(/(?:\s*\n)?(.*?)\s*<\/i>/m) { "\e[1m#{$1}\e[0m" }. + gsub(/\B\+(\w+?)\+\B/) { "\e[32m#{$1}\e[0m" }. + gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { CodeRay.scan($1, :ruby).term }. + gsub(/`(?:\s*\n)?([^\e]*?)\s*`/) { "`#{CodeRay.scan($1, :ruby).term}`" } + end + + def process_yardoc_tag(comment, tag) + in_tag_block = nil + comment.lines.map do |v| + if in_tag_block && v !~ /^\S/ + Pry::Helpers::Text.strip_color Pry::Helpers::Text.strip_color(v) + elsif in_tag_block + in_tag_block = false + v + else + in_tag_block = true if v =~ /^@#{tag}/ + v + end + end.join + end + + def process_yardoc(comment) + yard_tags = ["param", "return", "option", "yield", "attr", "attr_reader", "attr_writer", + "deprecate", "example", "raise"] + (yard_tags - ["example"]).inject(comment) { |a, v| process_yardoc_tag(a, v) }. + gsub(/^@(#{yard_tags.join("|")})/) { "\e[33m#{$1}\e[0m" } + end + + def process_comment_markup(comment) + process_yardoc process_rdoc(comment) + end + + # @param [String] code + # @return [String] + def strip_comments_from_c_code(code) + code.sub(/\A\s*\/\*.*?\*\/\s*/m, '') + end + + # Given a string that makes up a comment in a source-code file parse out the content + # that the user is intended to read. (i.e. without leading indentation, #-characters + # or shebangs) + # + # @param [String] comment + # @return [String] + def get_comment_content(comment) + comment = comment.dup + # Remove #!/usr/bin/ruby + comment.gsub!(/\A\#!.*$/, '') + # Remove leading empty comment lines + comment.gsub!(/\A\#+?$/, '') + comment.gsub!(/^\s*#/, '') + strip_leading_whitespace(comment) + end + + # @param [String] text + # @return [String] + def strip_leading_whitespace(text) + Pry::Helpers::CommandHelpers.unindent(text) + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/options_helpers.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/options_helpers.rb new file mode 100644 index 0000000..e566d3b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/options_helpers.rb @@ -0,0 +1,27 @@ +class Pry + module Helpers + module OptionsHelpers + module_function + + # Add method options to the Slop instance + def method_options(opt) + @method_target = target + opt.on :M, "instance-methods", "Operate on instance methods." + opt.on :m, :methods, "Operate on methods." + opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors.", :as => :count + opt.on :c, :context, "Select object context to run under.", :argument => true do |context| + @method_target = Pry.binding_for(target.eval(context)) + end + end + + # Get the method object parsed by the slop instance + def method_object + @method_object ||= get_method_or_raise(args.empty? ? nil : args.join(" "), @method_target, + :super => opts[:super], + :instance => opts.present?(:'instance-methods') && !opts.present?(:'methods'), + :methods => opts.present?(:'methods') && !opts.present?(:'instance-methods') + ) + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/table.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/table.rb new file mode 100644 index 0000000..56e7e59 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/table.rb @@ -0,0 +1,109 @@ +class Pry + module Helpers + def self.tablify_or_one_line(heading, things) + plain_heading = Pry::Helpers::Text.strip_color(heading) + attempt = Table.new(things, :column_count => things.size) + if attempt.fits_on_line?(Terminal.width! - plain_heading.size - 2) + "#{heading}: #{attempt}\n" + else + "#{heading}: \n#{tablify_to_screen_width(things, :indent => ' ')}\n" + end + end + + def self.tablify_to_screen_width(things, options = {}) + things = things.compact + if indent = options[:indent] + usable_width = Terminal.width! - indent.size + tablify(things, usable_width).to_s.gsub(/^/, indent) + else + tablify(things, Terminal.width!).to_s + end + end + + def self.tablify(things, line_length) + table = Table.new(things, :column_count => things.size) + table.column_count -= 1 until 1 == table.column_count or + table.fits_on_line?(line_length) + table + end + + class Table + attr_reader :items, :column_count + def initialize items, args = {} + @column_count = args[:column_count] + self.items = items + end + + def to_s + rows_to_s.join("\n") + end + + def rows_to_s style = :color_on + widths = columns.map{|e| _max_width(e)} + @rows_without_colors.map do |r| + padded = [] + r.each_with_index do |e,i| + next unless e + item = e.ljust(widths[i]) + item.sub! e, _recall_color_for(e) if :color_on == style + padded << item + end + padded.join(Pry.config.ls.separator) + end + end + + def items= items + @items = items + _rebuild_colorless_cache + _recolumn + items + end + + def column_count= n + @column_count = n + _recolumn + end + + def fits_on_line? line_length + _max_width(rows_to_s :no_color) <= line_length + end + + def columns + @rows_without_colors.transpose + end + + def ==(other); items == other.to_a end + def to_a; items.to_a end + + private + def _max_width(things) + things.compact.map(&:size).max || 0 + end + + def _rebuild_colorless_cache + @colorless_cache = {} + @plain_items = [] + items.map do |e| + plain = Pry::Helpers::Text.strip_color(e) + @colorless_cache[plain] = e + @plain_items << plain + end + end + + def _recolumn + @rows_without_colors = [] + return if items.size.zero? + row_count = (items.size.to_f/column_count).ceil + row_count.times do |i| + row_indices = (0...column_count).map{|e| row_count*e+i} + @rows_without_colors << row_indices.map{|e| @plain_items[e]} + end + end + + def _recall_color_for thing + @colorless_cache[thing] + end + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/text.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/text.rb new file mode 100644 index 0000000..13867cf --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/text.rb @@ -0,0 +1,107 @@ +class Pry + module Helpers + + # The methods defined on {Text} are available to custom commands via {Pry::Command#text}. + module Text + + COLORS = + { + "black" => 0, + "red" => 1, + "green" => 2, + "yellow" => 3, + "blue" => 4, + "purple" => 5, + "magenta" => 5, + "cyan" => 6, + "white" => 7 + } + + class << self + + COLORS.each_pair do |color, value| + define_method color do |text| + "\033[0;#{30+value}m#{text}\033[0m" + end + + define_method "bright_#{color}" do |text| + "\033[1;#{30+value}m#{text}\033[0m" + end + end + + # Remove any color codes from _text_. + # + # @param [String, #to_s] text + # @return [String] _text_ stripped of any color codes. + def strip_color(text) + text.to_s.gsub(/\e\[.*?(\d)+m/ , '') + end + + # Returns _text_ as bold text for use on a terminal. + # + # @param [String, #to_s] text + # @return [String] _text_ + def bold(text) + "\e[1m#{text}\e[0m" + end + + # Returns `text` in the default foreground colour. + # Use this instead of "black" or "white" when you mean absence of colour. + # + # @param [String, #to_s] text + # @return [String] + def default(text) + text.to_s + end + alias_method :bright_default, :bold + + # Executes the block with `Pry.config.color` set to false. + # @yield + # @return [void] + def no_color(&block) + boolean = Pry.config.color + Pry.config.color = false + yield + ensure + Pry.config.color = boolean + end + + # Executes the block with `Pry.config.pager` set to false. + # @yield + # @return [void] + def no_pager(&block) + boolean = Pry.config.pager + Pry.config.pager = false + yield + ensure + Pry.config.pager = boolean + end + + # Returns _text_ in a numbered list, beginning at _offset_. + # + # @param [#each_line] text + # @param [Fixnum] offset + # @return [String] + def with_line_numbers(text, offset, color=:blue) + lines = text.each_line.to_a + max_width = (offset + lines.count).to_s.length + lines.each_with_index.map do |line, index| + adjusted_index = (index + offset).to_s.rjust(max_width) + "#{self.send(color, adjusted_index)}: #{line}" + end.join + end + + # Returns _text_ indented by _chars_ spaces. + # + # @param [String] text + # @param [Fixnum] chars + def indent(text, chars) + text.lines.map { |l| "#{' ' * chars}#{l}" }.join + end + end + + end + + end +end + diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/history.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/history.rb new file mode 100644 index 0000000..1bef4a2 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/history.rb @@ -0,0 +1,125 @@ +class Pry + # The History class is responsible for maintaining the user's input history, + # both internally and within Readline. + class History + attr_accessor :loader, :saver, :pusher, :clearer + + # @return [Fixnum] Number of lines in history when Pry first loaded. + attr_reader :original_lines + + def initialize(options={}) + @history = [] + @original_lines = 0 + @file_path = options[:file_path] + restore_default_behavior + end + + # Assign the default methods for loading, saving, pushing, and clearing. + def restore_default_behavior + Pry.config.input # force Readline to load if applicable + + @loader = method(:read_from_file) + @saver = method(:save_to_file) + + if defined?(Readline) + @pusher = method(:push_to_readline) + @clearer = method(:clear_readline) + else + @pusher = proc { } + @clearer = proc { } + end + end + + # Load the input history using `History.loader`. + # @return [Integer] The number of lines loaded + def load + @loader.call do |line| + @pusher.call(line.chomp) + @history << line.chomp + @original_lines += 1 + end + end + + # Add a line to the input history, ignoring blank and duplicate lines. + # @param [String] line + # @return [String] The same line that was passed in + def push(line) + unless line.empty? || (@history.last && line == @history.last) + @pusher.call(line) + @history << line + @saver.call(line) if Pry.config.history.should_save + end + line + end + alias << push + + # Clear this session's history. This won't affect the contents of the + # history file. + def clear + @clearer.call + @history = [] + end + + # @return [Fixnum] The number of lines in history. + def history_line_count + @history.count + end + + # @return [Fixnum] The number of lines in history from just this session. + def session_line_count + @history.count - @original_lines + end + + # Return an Array containing all stored history. + # @return [Array] An Array containing all lines of history loaded + # or entered by the user in the current session. + def to_a + @history.dup + end + + private + + # The default loader. Yields lines from `Pry.history.config.file`. + def read_from_file + filename = File.expand_path(Pry.config.history.file) + + if File.exists?(filename) + File.foreach(filename) { |line| yield(line) } + end + rescue => error + warn "History file not loaded: #{error.message}" + end + + # The default pusher. Appends the given line to Readline::HISTORY. + # @param [String] line + def push_to_readline(line) + Readline::HISTORY << line + end + + # The default clearer. Clears Readline::HISTORY. + def clear_readline + Readline::HISTORY.shift until Readline::HISTORY.empty? + end + + # The default saver. Appends the given line to `Pry.history.config.file`. + def save_to_file(line) + history_file.puts line if history_file + end + + # The history file, opened for appending. + def history_file + if defined?(@history_file) + @history_file + else + @history_file = File.open(file_path, 'a', 0600).tap { |f| f.sync = true } + end + rescue Errno::EACCES + warn 'History not saved; unable to open your history file for writing.' + @history_file = false + end + + def file_path + @file_path || Pry.config.history.file + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/history_array.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/history_array.rb new file mode 100644 index 0000000..60e41bc --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/history_array.rb @@ -0,0 +1,121 @@ +class Pry + # A history array is an array to which you can only add elements. Older + # entries are removed progressively, so that the array never contains more than + # N elements. + # + # History arrays are used by Pry to store the output of the last commands. + # + # @example + # ary = Pry::HistoryArray.new 10 + # ary << 1 << 2 << 3 + # ary[0] # => 1 + # ary[1] # => 2 + # 10.times { |n| ary << n } + # ary[0] # => nil + # ary[-1] # => 9 + class HistoryArray + include Enumerable + + # @param [Integer] size Maximum amount of objects in the array + def initialize(size) + @max_size = size + + @hash = {} + @count = 0 + end + + # Pushes an object at the end of the array + # @param [Object] value Object to be added + def <<(value) + @hash[@count] = value + + if @hash.size > max_size + @hash.delete(@count - max_size) + end + + @count += 1 + + self + end + + # @overload [](index) + # @param [Integer] index Index of the item to access. + # @return [Object, nil] Item at that index or nil if it has been removed. + # @overload [](index, size) + # @param [Integer] index Index of the first item to access. + # @param [Integer] size Amount of items to access + # @return [Array, nil] The selected items. Nil if index is greater than + # the size of the array. + # @overload [](range) + # @param [Range] range Range of indices to access. + # @return [Array, nil] The selected items. Nil if index is greater than + # the size of the array. + def [](index_or_range, size = nil) + if index_or_range.is_a? Integer + index = convert_index(index_or_range) + + if size + end_index = index + size + index > @count ? nil : (index...[end_index, @count].min).map do |n| + @hash[n] + end + else + @hash[index] + end + else + range = convert_range(index_or_range) + range.begin > @count ? nil : range.map { |n| @hash[n] } + end + end + + # @return [Integer] Amount of objects in the array + def size + @count + end + alias count size + alias length size + + def empty? + size == 0 + end + + def each + ((@count - size)...@count).each do |n| + yield @hash[n] + end + end + + def to_a + ((@count - size)...@count).map { |n| @hash[n] } + end + + # Returns [Hash] copy of the internal @hash history + def to_h + @hash.dup + end + + def pop! + @hash.delete @count - 1 + @count -= 1 + end + + def inspect + "#<#{self.class} size=#{size} first=#{@count - size} max_size=#{max_size}>" + end + + # @return [Integer] Maximum amount of objects in the array + attr_reader :max_size + + private + def convert_index(n) + n >= 0 ? n : @count + n + end + + def convert_range(range) + end_index = convert_index(range.end) + end_index += 1 unless range.exclude_end? + + Range.new(convert_index(range.begin), [end_index, @count].min, true) + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/hooks.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/hooks.rb new file mode 100644 index 0000000..48291ee --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/hooks.rb @@ -0,0 +1,230 @@ +class Pry + + # Implements a hooks system for Pry. A hook is a callable that is + # associated with an event. A number of events are currently + # provided by Pry, these include: `:when_started`, `:before_session`, `:after_session`. + # A hook must have a name, and is connected with an event by the + # `Pry::Hooks#add_hook` method. + # @example Adding a hook for the `:before_session` event. + # Pry.config.hooks.add_hook(:before_session, :say_hi) do + # puts "hello" + # end + class Hooks + + # Converts a hash to a `Pry::Hooks` instance. All hooks defined + # this way are anonymous. This functionality is primarily to + # provide backwards-compatibility with the old hash-based hook + # system in Pry versions < 0.9.8 + # @param [Hash] hash The hash to convert to `Pry::Hooks`. + # @return [Pry::Hooks] The resulting `Pry::Hooks` instance. + def self.from_hash(hash) + return hash if hash.instance_of?(self) + instance = new + hash.each do |k, v| + instance.add_hook(k, nil, v) + end + instance + end + + def initialize + @hooks = {} + end + + # Ensure that duplicates have their @hooks object + def initialize_copy(orig) + hooks_dup = @hooks.dup + @hooks.each do |k, v| + hooks_dup[k] = v.dup + end + + @hooks = hooks_dup + end + + def hooks + @hooks + end + protected :hooks + + def errors + @errors ||= [] + end + + # Destructively merge the contents of two `Pry:Hooks` instances. + # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge + # @return [Pry:Hooks] Returns the receiver. + # @example + # hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # Pry::Hooks.new.merge!(hooks) + def merge!(other) + @hooks.merge!(other.dup.hooks) do |key, v1, v2| + merge_arrays(v1, v2) + end + + self + end + + def merge_arrays(array1, array2) + uniq_keeping_last(array1 + array2, &:first) + end + private :merge_arrays + + def uniq_keeping_last(input, &block) + hash, output = {}, [] + input.reverse.each{ |i| hash[block[i]] ||= (output.unshift i) } + output + end + private :uniq_keeping_last + + # Return a new `Pry::Hooks` instance containing a merge of the contents of two `Pry:Hooks` instances, + # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge + # @return [Pry::Hooks] The new hash. + # @example + # hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # Pry::Hooks.new.merge(hooks) + def merge(other) + self.dup.tap do |v| + v.merge!(other) + end + end + + # Add a new hook to be executed for the `name` even. + # @param [Symbol] event_name The name of the event. + # @param [Symbol] hook_name The name of the hook. + # @param [#call] callable The callable. + # @yield The block to use as the callable (if `callable` parameter not provided) + # @return [Pry:Hooks] Returns the receiver. + # @example + # Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + def add_hook(event_name, hook_name, callable=nil, &block) + @hooks[event_name] ||= [] + + # do not allow duplicates, but allow multiple `nil` hooks + # (anonymous hooks) + if hook_exists?(event_name, hook_name) && !hook_name.nil? + raise ArgumentError, "Hook with name '#{hook_name}' already defined!" + end + + if !block && !callable + raise ArgumentError, "Must provide a block or callable." + end + + # ensure we only have one anonymous hook + @hooks[event_name].delete_if { |h, k| h.nil? } if hook_name.nil? + + if block + @hooks[event_name] << [hook_name, block] + elsif callable + @hooks[event_name] << [hook_name, callable] + end + + self + end + + # Execute the list of hooks for the `event_name` event. + # @param [Symbol] event_name The name of the event. + # @param [Array] args The arguments to pass to each hook function. + # @return [Object] The return value of the last executed hook. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.exec_hook(:before_session) #=> OUTPUT: "hi!" + def exec_hook(event_name, *args, &block) + @hooks[event_name] ||= [] + + @hooks[event_name].map do |hook_name, callable| + begin + callable.call(*args, &block) + rescue RescuableException => e + errors << e + e + end + end.last + end + + # Return the number of hook functions registered for the `event_name` event. + # @param [Symbol] event_name The name of the event. + # @return [Fixnum] The number of hook functions for `event_name`. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.count(:before_session) #=> 1 + def hook_count(event_name) + @hooks[event_name] ||= [] + @hooks[event_name].size + end + + # Return a specific hook for a given event. + # @param [Symbol] event_name The name of the event. + # @param [Symbol] hook_name The name of the hook + # @return [#call] The requested hook. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.get_hook(:before_session, :say_hi).call #=> "hi!" + def get_hook(event_name, hook_name) + @hooks[event_name] ||= [] + hook = @hooks[event_name].find { |current_hook_name, callable| current_hook_name == hook_name } + hook.last if hook + end + + # Return the hash of hook names / hook functions for a + # given event. (Note that modifying the returned hash does not + # alter the hooks, use add_hook/delete_hook for that). + # @param [Symbol] event_name The name of the event. + # @return [Hash] The hash of hook names / hook functions. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.get_hooks(:before_session) #=> {:say_hi=>#} + def get_hooks(event_name) + @hooks[event_name] ||= [] + Hash[@hooks[event_name]] + end + + # Delete a hook for an event. + # @param [Symbol] event_name The name of the event. + # @param [Symbol] hook_name The name of the hook. + # to delete. + # @return [#call] The deleted hook. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.delete_hook(:before_session, :say_hi) + def delete_hook(event_name, hook_name) + @hooks[event_name] ||= [] + deleted_callable = nil + + @hooks[event_name].delete_if do |current_hook_name, callable| + if current_hook_name == hook_name + deleted_callable = callable + true + else + false + end + end + deleted_callable + end + + # Clear all hooks functions for a given event. + # @param [String] event_name The name of the event. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.delete_hook(:before_session) + def delete_hooks(event_name) + @hooks[event_name] = [] + end + + alias_method :clear, :delete_hooks + + # Remove all events and hooks, clearing out the Pry::Hooks + # instance completely. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.clear_all + def clear_all + @hooks = {} + end + + # @param [Symbol] event_name Name of the event. + # @param [Symbol] hook_name Name of the hook. + # @return [Boolean] Whether the hook by the name `hook_name` + def hook_exists?(event_name, hook_name) + !!(@hooks[event_name] && @hooks[event_name].find { |name, _| name == hook_name }) + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/indent.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/indent.rb new file mode 100644 index 0000000..72fbf69 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/indent.rb @@ -0,0 +1,406 @@ +require 'coderay' + +class Pry + ## + # Pry::Indent is a class that can be used to indent a number of lines + # containing Ruby code similar as to how IRB does it (but better). The class + # works by tokenizing a string using CodeRay and then looping over those + # tokens. Based on the tokens in a line of code that line (or the next one) + # will be indented or un-indented by correctly. + # + class Indent + include Helpers::BaseHelpers + + # Raised if {#module_nesting} would not work. + class UnparseableNestingError < StandardError; end + + # @return [String] String containing the spaces to be inserted before the next line. + attr_reader :indent_level + + # @return [Array] The stack of open tokens. + attr_reader :stack + + # The amount of spaces to insert for each indent level. + SPACES = ' ' + + # Hash containing all the tokens that should increase the indentation + # level. The keys of this hash are open tokens, the values the matching + # tokens that should prevent a line from being indented if they appear on + # the same line. + OPEN_TOKENS = { + 'def' => 'end', + 'class' => 'end', + 'module' => 'end', + 'do' => 'end', + 'if' => 'end', + 'unless' => 'end', + 'while' => 'end', + 'until' => 'end', + 'for' => 'end', + 'case' => 'end', + 'begin' => 'end', + '[' => ']', + '{' => '}', + '(' => ')' + } + + # Which tokens can either be open tokens, or appear as modifiers on + # a single-line. + SINGLELINE_TOKENS = %w(if while until unless rescue) + + # Which tokens can be followed by an optional "do" keyword. + OPTIONAL_DO_TOKENS = %w(for while until) + + # Collection of token types that should be ignored. Without this list + # keywords such as "class" inside strings would cause the code to be + # indented incorrectly. + # + # :pre_constant and :preserved_constant are the CodeRay 0.9.8 and 1.0.0 + # classifications of "true", "false", and "nil". + IGNORE_TOKENS = [:space, :content, :string, :method, :ident, + :constant, :pre_constant, :predefined_constant] + + # Tokens that indicate the end of a statement (i.e. that, if they appear + # directly before an "if" indicates that that if applies to the same line, + # not the next line) + # + # :reserved and :keywords are the CodeRay 0.9.8 and 1.0.0 respectively + # classifications of "super", "next", "return", etc. + STATEMENT_END_TOKENS = IGNORE_TOKENS + [:regexp, :integer, :float, :keyword, + :delimiter, :reserved] + + # Collection of tokens that should appear dedented even though they + # don't affect the surrounding code. + MIDWAY_TOKENS = %w(when else elsif ensure rescue) + + # Clean the indentation of a fragment of ruby. + # + # @param [String] str + # @return [String] + def self.indent(str) + new.indent(str) + end + + # Get the module nesting at the given point in the given string. + # + # NOTE If the line specified contains a method definition, then the nesting + # at the start of the method definition is used. Otherwise the nesting from + # the end of the line is used. + # + # @param [String] str The ruby code to analyze + # @param [Fixnum] line_number The line number (starting from 1) + # @return [Array] + def self.nesting_at(str, line_number) + indent = new + lines = str.split("\n") + n = line_number - 1 + to_indent = lines[0...n] << (lines[n] || "").split("def").first(1) + indent.indent(to_indent.join("\n") << "\n") + indent.module_nesting + end + + def initialize + reset + end + + # reset internal state + def reset + @stack = [] + @indent_level = '' + @heredoc_queue = [] + @close_heredocs = {} + @string_start = nil + @awaiting_class = false + @module_nesting = [] + self + end + + # Indents a string and returns it. This string can either be a single line + # or multiple ones. + # + # @example + # str = <] + def module_nesting + @module_nesting.map do |(kind, token)| + raise UnparseableNestingError, @module_nesting.inspect if token.nil? + + "#{kind} #{token}" + end + end + + # Return a string which, when printed, will rewrite the previous line with + # the correct indentation. Mostly useful for fixing 'end'. + # + # @param [String] prompt The user's prompt + # @param [String] code The code the user just typed in. + # @param [Fixnum] overhang (0) The number of chars to erase afterwards (i.e., + # the difference in length between the old line and the new one). + # @return [String] + def correct_indentation(prompt, code, overhang=0) + prompt = prompt.delete("\001\002") + line_to_measure = Pry::Helpers::Text.strip_color(prompt) << code + whitespace = ' ' * overhang + + _, cols = Terminal.screen_size + + cols = cols.to_i + lines = (cols != 0 ? (line_to_measure.length / cols + 1) : 1).to_i + + if Pry::Helpers::BaseHelpers.windows_ansi? + move_up = "\e[#{lines}F" + move_down = "\e[#{lines}E" + else + move_up = "\e[#{lines}A\e[0G" + move_down = "\e[#{lines}B\e[0G" + end + + "#{move_up}#{prompt}#{colorize_code(code)}#{whitespace}#{move_down}" + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/input_completer.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/input_completer.rb new file mode 100644 index 0000000..363baa4 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/input_completer.rb @@ -0,0 +1,242 @@ +# taken from irb +# Implements tab completion for Readline in Pry +class Pry::InputCompleter + NUMERIC_REGEXP = /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/ + ARRAY_REGEXP = /^([^\]]*\])\.([^.]*)$/ + SYMBOL_REGEXP = /^(:[^:.]*)$/ + SYMBOL_METHOD_CALL_REGEXP = /^(:[^:.]+)\.([^.]*)$/ + REGEX_REGEXP = /^(\/[^\/]*\/)\.([^.]*)$/ + PROC_OR_HASH_REGEXP = /^([^\}]*\})\.([^.]*)$/ + TOPLEVEL_LOOKUP_REGEXP = /^::([A-Z][^:\.\(]*)$/ + CONSTANT_REGEXP = /^([A-Z][A-Za-z0-9]*)$/ + CONSTANT_OR_METHOD_REGEXP = /^([A-Z].*)::([^:.]*)$/ + HEX_REGEXP = /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/ + GLOBALVARIABLE_REGEXP = /^(\$[^.]*)$/ + VARIABLE_REGEXP = /^([^."].*)\.([^.]*)$/ + + ReservedWords = [ + "BEGIN", "END", + "alias", "and", + "begin", "break", + "case", "class", + "def", "defined", "do", + "else", "elsif", "end", "ensure", + "false", "for", + "if", "in", + "module", + "next", "nil", "not", + "or", + "redo", "rescue", "retry", "return", + "self", "super", + "then", "true", + "undef", "unless", "until", + "when", "while", + "yield" ] + + Operators = [ + "%", "&", "*", "**", "+", "-", "/", + "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>", + "[]", "[]=", "^", "!", "!=", "!~" + ] + + WORD_ESCAPE_STR = " \t\n\"\\'`><=;|&{(" + + def initialize(input, pry = nil) + @pry = pry + @input = input + @input.basic_word_break_characters = WORD_ESCAPE_STR if @input.respond_to?(:basic_word_break_characters=) + @input.completion_append_character = nil if @input.respond_to?(:completion_append_character=) + end + + # + # Return a new completion proc for use by Readline. + # + def call(str, options = {}) + custom_completions = options[:custom_completions] || [] + # if there are multiple contexts e.g. cd 1/2/3 + # get new target for 1/2 and find candidates for 3 + path, input = build_path(str) + + if path.call.empty? + target = options[:target] + else + # Assume the user is tab-completing the 'cd' command + begin + target = Pry::ObjectPath.new(path.call, @pry.binding_stack).resolve.last + # but if that doesn't work, assume they're doing division with no spaces + rescue Pry::CommandError + target = options[:target] + end + end + + begin + bind = target + # Complete stdlib symbols + case input + when REGEX_REGEXP # Regexp + receiver = $1 + message = Regexp.quote($2) + candidates = Regexp.instance_methods.collect(&:to_s) + select_message(path, receiver, message, candidates) + when ARRAY_REGEXP # Array + receiver = $1 + message = Regexp.quote($2) + candidates = Array.instance_methods.collect(&:to_s) + select_message(path, receiver, message, candidates) + when PROC_OR_HASH_REGEXP # Proc or Hash + receiver = $1 + message = Regexp.quote($2) + candidates = Proc.instance_methods.collect(&:to_s) + candidates |= Hash.instance_methods.collect(&:to_s) + select_message(path, receiver, message, candidates) + when SYMBOL_REGEXP # Symbol + if Symbol.respond_to?(:all_symbols) + sym = Regexp.quote($1) + candidates = Symbol.all_symbols.collect{|s| ":" << s.id2name} + candidates.grep(/^#{sym}/) + else + [] + end + when TOPLEVEL_LOOKUP_REGEXP # Absolute Constant or class methods + receiver = $1 + candidates = Object.constants.collect(&:to_s) + candidates.grep(/^#{receiver}/).collect{|e| "::" << e} + when CONSTANT_REGEXP # Constant + message = $1 + begin + context = target.eval("self") + context = context.class unless context.respond_to? :constants + candidates = context.constants.collect(&:to_s) + rescue + candidates = [] + end + candidates = candidates.grep(/^#{message}/).collect(&path) + when CONSTANT_OR_METHOD_REGEXP # Constant or class methods + receiver = $1 + message = Regexp.quote($2) + begin + candidates = eval("#{receiver}.constants.collect(&:to_s)", bind) + candidates |= eval("#{receiver}.methods.collect(&:to_s)", bind) + rescue Pry::RescuableException + candidates = [] + end + candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e} + when SYMBOL_METHOD_CALL_REGEXP # method call on a Symbol + receiver = $1 + message = Regexp.quote($2) + candidates = Symbol.instance_methods.collect(&:to_s) + select_message(path, receiver, message, candidates) + when NUMERIC_REGEXP + # Numeric + receiver = $1 + message = Regexp.quote($5) + begin + candidates = eval(receiver, bind).methods.collect(&:to_s) + rescue Pry::RescuableException + candidates = [] + end + select_message(path, receiver, message, candidates) + when HEX_REGEXP + # Numeric(0xFFFF) + receiver = $1 + message = Regexp.quote($2) + begin + candidates = eval(receiver, bind).methods.collect(&:to_s) + rescue Pry::RescuableException + candidates = [] + end + select_message(path, receiver, message, candidates) + when GLOBALVARIABLE_REGEXP # global + regmessage = Regexp.new(Regexp.quote($1)) + candidates = global_variables.collect(&:to_s).grep(regmessage) + when VARIABLE_REGEXP # variable + receiver = $1 + message = Regexp.quote($2) + + gv = eval("global_variables", bind).collect(&:to_s) + lv = eval("local_variables", bind).collect(&:to_s) + cv = eval("self.class.constants", bind).collect(&:to_s) + + if (gv | lv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver + # foo.func and foo is local var. OR + # Foo::Bar.func + begin + candidates = eval("#{receiver}.methods", bind).collect(&:to_s) + rescue Pry::RescuableException + candidates = [] + end + else + # func1.func2 + candidates = [] + ObjectSpace.each_object(Module){|m| + begin + name = m.name.to_s + rescue Pry::RescuableException + name = "" + end + next if name != "IRB::Context" and + /^(IRB|SLex|RubyLex|RubyToken)/ =~ name + + # jruby doesn't always provide #instance_methods() on each + # object. + if m.respond_to?(:instance_methods) + candidates.concat m.instance_methods(false).collect(&:to_s) + end + } + candidates.sort! + candidates.uniq! + end + select_message(path, receiver, message, candidates) + when /^\.([^.]*)$/ + # Unknown(maybe String) + receiver = "" + message = Regexp.quote($1) + candidates = String.instance_methods(true).collect(&:to_s) + select_message(path, receiver, message, candidates) + else + candidates = eval( + "methods | private_methods | local_variables | " \ + "self.class.constants | instance_variables", + bind + ).collect(&:to_s) + + if eval("respond_to?(:class_variables)", bind) + candidates += eval("class_variables", bind).collect(&:to_s) + end + candidates = (candidates|ReservedWords|custom_completions).grep(/^#{Regexp.quote(input)}/) + candidates.collect(&path) + end + rescue Pry::RescuableException + [] + end + end + + def select_message(path, receiver, message, candidates) + candidates.grep(/^#{message}/).collect { |e| + case e + when /^[a-zA-Z_]/ + path.call(receiver + "." << e) + when /^[0-9]/ + when *Operators + #receiver + " " << e + end + }.compact + end + + # build_path seperates the input into two parts: path and input. + # input is the partial string that should be completed + # path is a proc that takes an input and builds a full path. + def build_path(input) + # check to see if the input is a regex + return proc {|i| i.to_s }, input if input[/\/\./] + trailing_slash = input.end_with?('/') + contexts = input.chomp('/').split(/\//) + input = contexts[-1] + path = proc do |i| + p = contexts[0..-2].push(i).join('/') + p += '/' if trailing_slash && !i.nil? + p + end + return path, input + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/input_lock.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/input_lock.rb new file mode 100644 index 0000000..8adfed4 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/input_lock.rb @@ -0,0 +1,132 @@ +require 'thread' + +class Pry + # There is one InputLock per input (such as STDIN) as two REPLs on the same + # input makes things delirious. InputLock serializes accesses to the input so + # that threads to not conflict with each other. The latest thread to request + # ownership of the input wins. + class InputLock + class Interrupt < Exception; end + + class << self + attr_accessor :input_locks + attr_accessor :global_lock + end + + self.input_locks = {} + self.global_lock = Mutex.new + + def self.for(input) + # XXX This method leaks memory, as we never unregister an input once we + # are done with it. Fortunately, the leak is tiny (or so we hope). In + # usual scenarios, we would leak the StringIO that is passed to be + # evaluated from the command line. + global_lock.synchronize do + input_locks[input] ||= Pry::InputLock.new + end + end + + def initialize + @mutex = Mutex.new + @cond = ConditionVariable.new + @owners = [] + @interruptible = false + end + + # Adds ourselves to the ownership list. The last one in the list may access + # the input through interruptible_region(). + def __with_ownership(&block) + @mutex.synchronize do + # Three cases: + # 1) There are no owners, in this case we are good to go. + # 2) The current owner of the input is not reading the input (it might + # just be evaluating some ruby that the user typed). + # The current owner will figure out that it cannot go back to reading + # the input since we are adding ourselves to the @owners list, which + # in turns makes us the current owner. + # 3) The owner of the input is in the interruptible region, reading from + # the input. It's safe to send an Interrupt exception to interrupt + # the owner. It will then proceed like in case 2). + # We wait until the owner sets the interruptible flag back + # to false, meaning that he's out of the interruptible region. + # Note that the owner may receive multiple interrupts since, but that + # should be okay (and trying to avoid it is futile anyway). + while @interruptible + @owners.last.raise Interrupt + @cond.wait(@mutex) + end + @owners << Thread.current + end + + block.call + + ensure + @mutex.synchronize do + # We are releasing any desire to have the input ownership by removing + # ourselves from the list. + @owners.delete(Thread.current) + + # We need to wake up the thread at the end of the @owners list, but + # sadly Ruby doesn't allow us to choose which one we wake up, so we wake + # them all up. + @cond.broadcast + end + end + + def with_ownership(&block) + # If we are in a nested with_ownership() call (nested pry context), we do nothing. + nested = @mutex.synchronize { @owners.include?(Thread.current) } + nested ? block.call : __with_ownership(&block) + end + + def enter_interruptible_region + @mutex.synchronize do + # We patiently wait until we are the owner. This may happen as another + # thread calls with_ownership() because of a binding.pry happening in + # another thread. + @cond.wait(@mutex) until @owners.last == Thread.current + + # We are the legitimate owner of the input. We mark ourselves as + # interruptible, so other threads can send us an Interrupt exception + # while we are blocking from reading the input. + @interruptible = true + end + end + + def leave_interruptible_region + @mutex.synchronize do + # We check if we are still the owner, because we could have received an + # Interrupt right after the following @cond.broadcast, making us retry. + @interruptible = false if @owners.last == Thread.current + @cond.broadcast + end + rescue Interrupt + # We need to guard against a spurious interrupt delivered while we are + # trying to acquire the lock (the rescue block is no longer in our scope). + retry + end + + def interruptible_region(&block) + enter_interruptible_region + + # XXX Note that there is a chance that we get the interrupt right after + # the readline call succeeded, but we'll never know, and we will retry the + # call, discarding that piece of input. + block.call + + rescue Interrupt + # We were asked to back off. The one requesting the interrupt will be + # waiting on the conditional for the interruptible flag to change to false. + # Note that there can be some inefficiency, as we could immediately + # succeed in enter_interruptible_region(), even before the one requesting + # the ownership has the chance to register itself as an owner. + # To mitigate the issue, we sleep a little bit. + leave_interruptible_region + sleep 0.01 + retry + + ensure + leave_interruptible_region + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/inspector.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/inspector.rb new file mode 100644 index 0000000..c56b02f --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/inspector.rb @@ -0,0 +1,27 @@ +class Pry::Inspector + MAP = { + "default" => { + value: Pry::DEFAULT_PRINT, + description: <<-DESCRIPTION.each_line.map(&:lstrip!) + The default Pry inspector. It has paging and color support, and uses + pretty_inspect when printing an object. + DESCRIPTION + }, + + "simple" => { + value: Pry::SIMPLE_PRINT, + description: <<-DESCRIPTION.each_line.map(&:lstrip) + A simple inspector that uses #puts and #inspect when printing an + object. It has no pager, color, or pretty_inspect support. + DESCRIPTION + }, + + "clipped" => { + value: Pry::CLIPPED_PRINT, + description: <<-DESCRIPTION.each_line.map(&:lstrip) + The clipped inspector has the same features as the 'simple' inspector + but prints large objects as a smaller string. + DESCRIPTION + } + } +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/last_exception.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/last_exception.rb new file mode 100644 index 0000000..2841113 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/last_exception.rb @@ -0,0 +1,61 @@ +# +# {Pry::LastException} is a proxy class who wraps an Exception object for +# {Pry#last_exception}. it extends the exception object with methods that +# help pry commands be useful. +# +# the original exception object is not modified and method calls are forwarded +# to the wrapped exception object. +# +class Pry::LastException < BasicObject + attr_accessor :bt_index + + def initialize(e) + @e = e + @bt_index = 0 + @file, @line = bt_source_location_for(0) + end + + def method_missing(name, *args, &block) + if @e.respond_to?(name) + @e.public_send(name, *args, &block) + else + super + end + end + + def respond_to_missing?(name, include_private = false) + @e.respond_to?(name) + end + + # + # @return [String] + # returns the path to a file for the current backtrace. see {#bt_index}. + # + def file + @file + end + + # + # @return [Fixnum] + # returns the line for the current backtrace. see {#bt_index}. + # + def line + @line + end + + # @return [Exception] + # returns the wrapped exception + # + def wrapped_exception + @e + end + + def bt_source_location_for(index) + backtrace[index] =~ /(.*):(\d+)/ + [$1, $2.to_i] + end + + def inc_bt_index + @bt_index = (@bt_index + 1) % backtrace.size + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/method.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/method.rb new file mode 100644 index 0000000..03eb60a --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/method.rb @@ -0,0 +1,546 @@ +require 'pry/helpers/documentation_helpers' + +class Pry + class << self + # If the given object is a `Pry::Method`, return it unaltered. If it's + # anything else, return it wrapped in a `Pry::Method` instance. + def Method(obj) + if obj.is_a? Pry::Method + obj + else + Pry::Method.new(obj) + end + end + end + + # This class wraps the normal `Method` and `UnboundMethod` classes + # to provide extra functionality useful to Pry. + class Method + require 'pry/method/weird_method_locator' + require 'pry/method/disowned' + require 'pry/method/patcher' + + extend Helpers::BaseHelpers + include Helpers::BaseHelpers + include Helpers::DocumentationHelpers + include CodeObject::Helpers + + class << self + # Given a string representing a method name and optionally a binding to + # search in, find and return the requested method wrapped in a `Pry::Method` + # instance. + # + # @param [String] name The name of the method to retrieve. + # @param [Binding] target The context in which to search for the method. + # @param [Hash] options + # @option options [Boolean] :instance Look for an instance method if `name` doesn't + # contain any context. + # @option options [Boolean] :methods Look for a bound/singleton method if `name` doesn't + # contain any context. + # @return [Pry::Method, nil] A `Pry::Method` instance containing the requested + # method, or `nil` if name is `nil` or no method could be located matching the parameters. + def from_str(name, target=TOPLEVEL_BINDING, options={}) + if name.nil? + nil + elsif name.to_s =~ /(.+)\#(\S+)\Z/ + context, meth_name = $1, $2 + from_module(target.eval(context), meth_name, target) + elsif name.to_s =~ /(.+)(\[\])\Z/ + context, meth_name = $1, $2 + from_obj(target.eval(context), meth_name, target) + elsif name.to_s =~ /(.+)(\.|::)(\S+)\Z/ + context, meth_name = $1, $3 + from_obj(target.eval(context), meth_name, target) + elsif options[:instance] + from_module(target.eval("self"), name, target) + elsif options[:methods] + from_obj(target.eval("self"), name, target) + else + from_str(name, target, :instance => true) or + from_str(name, target, :methods => true) + end + + rescue Pry::RescuableException + nil + end + + # Given a `Binding`, try to extract the `::Method` it originated from and + # use it to instantiate a `Pry::Method`. Return `nil` if this isn't + # possible. + # + # @param [Binding] b + # @return [Pry::Method, nil] + # + def from_binding(b) + meth_name = b.eval('::Kernel.__method__') + if [:__script__, nil].include?(meth_name) + nil + else + method = begin + if Object === b.eval('self') + new(Kernel.instance_method(:method).bind(b.eval("self")).call(meth_name)) + else + new(b.eval('class << self; self; end.instance_method(::Kernel.__method__).bind(self)')) + end + rescue NameError, NoMethodError + Disowned.new(b.eval('self'), meth_name.to_s) + end + + if WeirdMethodLocator.weird_method?(method, b) + WeirdMethodLocator.new(method, b).get_method || method + else + method + end + end + end + + # In order to support 2.0 Refinements we need to look up methods + # inside the relevant Binding. + # @param [Object] obj The owner/receiver of the method. + # @param [Symbol] method_name The name of the method. + # @param [Symbol] method_type The type of method: :method or :instance_method + # @param [Binding] target The binding where the method is looked up. + # @return [Method, UnboundMethod] The 'refined' method object. + def lookup_method_via_binding(obj, method_name, method_type, target=TOPLEVEL_BINDING) + Pry.current[:obj] = obj + Pry.current[:name] = method_name + receiver = obj.is_a?(Module) ? "Module" : "Kernel" + target.eval("::#{receiver}.instance_method(:#{method_type}).bind(Pry.current[:obj]).call(Pry.current[:name])") + ensure + Pry.current[:obj] = Pry.current[:name] = nil + end + + # Given a `Class` or `Module` and the name of a method, try to + # instantiate a `Pry::Method` containing the instance method of + # that name. Return `nil` if no such method exists. + # + # @param [Class, Module] klass + # @param [String] name + # @param [Binding] target The binding where the method is looked up. + # @return [Pry::Method, nil] + def from_class(klass, name, target=TOPLEVEL_BINDING) + new(lookup_method_via_binding(klass, name, :instance_method, target)) rescue nil + end + alias from_module from_class + + # Given an object and the name of a method, try to instantiate + # a `Pry::Method` containing the method of that name bound to + # that object. Return `nil` if no such method exists. + # + # @param [Object] obj + # @param [String] name + # @param [Binding] target The binding where the method is looked up. + # @return [Pry::Method, nil] + def from_obj(obj, name, target=TOPLEVEL_BINDING) + new(lookup_method_via_binding(obj, name, :method, target)) rescue nil + end + + # Get all of the instance methods of a `Class` or `Module` + # @param [Class,Module] klass + # @param [Boolean] include_super Whether to include methods from ancestors. + # @return [Array[Pry::Method]] + def all_from_class(klass, include_super=true) + %w(public protected private).map do |visibility| + safe_send(klass, :"#{visibility}_instance_methods", include_super).map do |method_name| + new(safe_send(klass, :instance_method, method_name), :visibility => visibility.to_sym) + end + end.flatten(1) + end + + # + # Get all of the methods on an `Object` + # + # @param [Object] obj + # + # @param [Boolean] include_super + # indicates whether or not to include methods from ancestors. + # + # @return [Array[Pry::Method]] + # + def all_from_obj(obj, include_super=true) + all_from_class(singleton_class_of(obj), include_super) + end + + # + # @deprecated + # please use {#all_from_obj} instead. + # the `method_type` argument is ignored. + # + def all_from_common(obj, method_type = nil, include_super=true) + all_from_obj(obj, include_super) + end + + # Get every `Class` and `Module`, in order, that will be checked when looking + # for an instance method to call on this object. + # @param [Object] obj + # @return [Array[Class, Module]] + def resolution_order(obj) + if Class === obj + singleton_class_resolution_order(obj) + instance_resolution_order(Class) + else + klass = singleton_class_of(obj) rescue obj.class + instance_resolution_order(klass) + end + end + + # Get every `Class` and `Module`, in order, that will be checked when looking + # for methods on instances of the given `Class` or `Module`. + # This does not treat singleton classes of classes specially. + # @param [Class, Module] klass + # @return [Array[Class, Module]] + def instance_resolution_order(klass) + # include klass in case it is a singleton class, + ([klass] + Pry::Method.safe_send(klass, :ancestors)).uniq + end + + def method_definition?(name, definition_line) + singleton_method_definition?(name, definition_line) || + instance_method_definition?(name, definition_line) + end + + def singleton_method_definition?(name, definition_line) + /^define_singleton_method\(?\s*[:\"\']#{Regexp.escape(name)}|^def\s*self\.#{Regexp.escape(name)}/ =~ definition_line.strip + end + + def instance_method_definition?(name, definition_line) + /^define_method\(?\s*[:\"\']#{Regexp.escape(name)}|^def\s*#{Regexp.escape(name)}/ =~ definition_line.strip + end + + # Get the singleton classes of superclasses that could define methods on + # the given class object, and any modules they include. + # If a module is included at multiple points in the ancestry, only + # the lowest copy will be returned. + def singleton_class_resolution_order(klass) + ancestors = Pry::Method.safe_send(klass, :ancestors) + resolution_order = ancestors.grep(Class).map do |anc| + [singleton_class_of(anc), *singleton_class_of(anc).included_modules] + end.flatten(1) + + resolution_order.reverse.uniq.reverse - Class.included_modules + end + + def singleton_class_of(obj) + begin + class << obj; self; end + rescue TypeError # can't define singleton. Fixnum, Symbol, Float, ... + obj.class + end + end + end + + # A new instance of `Pry::Method` wrapping the given `::Method`, `UnboundMethod`, or `Proc`. + # + # @param [::Method, UnboundMethod, Proc] method + # @param [Hash] known_info Can be used to pre-cache expensive to compute stuff. + # @return [Pry::Method] + def initialize(method, known_info={}) + @method = method + @visibility = known_info[:visibility] + end + + # Get the name of the method as a String, regardless of the underlying Method#name type. + # @return [String] + def name + @method.name.to_s + end + + # Get the owner of the method as a Pry::Module + # @return [Pry::Module] + def wrapped_owner + @wrapped_owner ||= Pry::WrappedModule.new(owner) + end + + # Get underlying object wrapped by this Pry::Method instance + # @return [Method, UnboundMethod, Proc] + def wrapped + @method + end + + # Is the method undefined? (aka `Disowned`) + # @return [Boolean] false + def undefined? + false + end + + # Get the name of the method including the class on which it was defined. + # @example + # method(:puts).method_name + # => "Kernel.puts" + # @return [String] + def name_with_owner + "#{wrapped_owner.method_prefix}#{name}" + end + + # @return [String, nil] The source code of the method, or `nil` if it's unavailable. + def source + @source ||= case source_type + when :c + c_source + when :ruby + ruby_source + end + end + + # Update the live copy of the method's source. + def redefine(source) + Patcher.new(self).patch_in_ram source + Pry::Method(owner.instance_method(name)) + end + + # Can we get the source code for this method? + # @return [Boolean] + def source? + !!source + rescue MethodSource::SourceNotFoundError + false + end + + # @return [String, nil] The documentation for the method, or `nil` if it's + # unavailable. + def doc + @doc ||= case source_type + when :c + info = pry_doc_info + info.docstring if info + when :ruby + get_comment_content(comment) + end + end + + # @return [Symbol] The source type of the method. The options are + # `:ruby` for Ruby methods or `:c` for methods written in C. + def source_type + source_location.nil? ? :c : :ruby + end + + # @return [String, nil] The name of the file the method is defined in, or + # `nil` if the filename is unavailable. + def source_file + if source_location.nil? + if !rbx? and source_type == :c + info = pry_doc_info + info.file if info + end + else + source_location.first + end + end + + # @return [Fixnum, nil] The line of code in `source_file` which begins + # the method's definition, or `nil` if that information is unavailable. + def source_line + source_location.nil? ? nil : source_location.last + end + + # @return [Range, nil] The range of lines in `source_file` which contain + # the method's definition, or `nil` if that information is unavailable. + def source_range + source_location.nil? ? nil : (source_line)..(source_line + source.lines.count - 1) + end + + # @return [Symbol] The visibility of the method. May be `:public`, + # `:protected`, or `:private`. + def visibility + @visibility ||= if owner.public_instance_methods.any? { |m| m.to_s == name } + :public + elsif owner.protected_instance_methods.any? { |m| m.to_s == name } + :protected + elsif owner.private_instance_methods.any? { |m| m.to_s == name } + :private + else + :none + end + end + + # @return [String] A representation of the method's signature, including its + # name and parameters. Optional and "rest" parameters are marked with `*` + # and block parameters with `&`. If the parameter names are unavailable, + # they're given numbered names instead. + # Paraphrased from `awesome_print` gem. + def signature + if respond_to?(:parameters) + args = parameters.inject([]) do |arr, (type, name)| + name ||= (type == :block ? 'block' : "arg#{arr.size + 1}") + arr << case type + when :req then name.to_s + when :opt then "#{name}=?" + when :rest then "*#{name}" + when :block then "&#{name}" + else '?' + end + end + else + args = (1..arity.abs).map { |i| "arg#{i}" } + args[-1] = "*#{args[-1]}" if arity < 0 + end + + "#{name}(#{args.join(', ')})" + end + + # @return [Pry::Method, nil] The wrapped method that is called when you + # use "super" in the body of this method. + def super(times=1) + if UnboundMethod === @method + sup = super_using_ancestors(Pry::Method.instance_resolution_order(owner), times) + else + sup = super_using_ancestors(Pry::Method.resolution_order(receiver), times) + sup &&= sup.bind(receiver) + end + Pry::Method.new(sup) if sup + end + + # @return [String, nil] The original name the method was defined under, + # before any aliasing, or `nil` if it can't be determined. + def original_name + return nil if source_type != :ruby + method_name_from_first_line(source.lines.first) + end + + # @return [Boolean] Was the method defined outside a source file? + def dynamically_defined? + !!(source_file and source_file =~ /(\(.*\))|<.*>/) + end + + # @return [Boolean] Whether the method is unbound. + def unbound_method? + is_a?(::UnboundMethod) + end + + # @return [Boolean] Whether the method is bound. + def bound_method? + is_a?(::Method) + end + + # @return [Boolean] Whether the method is a singleton method. + def singleton_method? + wrapped_owner.singleton_class? + end + + # @return [Boolean] Was the method defined within the Pry REPL? + def pry_method? + source_file == Pry.eval_path + end + + # @return [Array] All known aliases for the method. + def aliases + owner = @method.owner + # Avoid using `to_sym` on {Method#name}, which returns a `String`, because + # it won't be garbage collected. + name = @method.name + + all_methods_to_compare = owner.instance_methods | owner.private_instance_methods + alias_list = all_methods_to_compare.combination(2).select do |pair| + pair.include?(name) && + owner.instance_method(pair.first) == owner.instance_method(pair.last) + end.flatten + alias_list.delete(name) + + alias_list.map(&:to_s) + end + + # @return [Boolean] Is the method definitely an alias? + def alias? + name != original_name + end + + # @return [Boolean] + def ==(obj) + if obj.is_a? Pry::Method + obj == @method + else + @method == obj + end + end + + # @param [Class] klass + # @return [Boolean] + def is_a?(klass) + klass == Pry::Method or @method.is_a?(klass) + end + alias kind_of? is_a? + + # @param [String, Symbol] method_name + # @return [Boolean] + def respond_to?(method_name) + super or @method.respond_to?(method_name) + end + + # Delegate any unknown calls to the wrapped method. + def method_missing(method_name, *args, &block) + @method.send(method_name, *args, &block) + end + + def comment + Pry::Code.from_file(source_file).comment_describing(source_line) + end + + private + + # @return [YARD::CodeObjects::MethodObject] + # @raise [CommandError] when the method can't be found or `pry-doc` isn't installed. + def pry_doc_info + if Pry.config.has_pry_doc + Pry::MethodInfo.info_for(@method) or raise CommandError, "Cannot locate this method: #{name}. (source_location returns nil)" + else + fail_msg = "Cannot locate this method: #{name}." + if mri? + fail_msg += ' Try `gem-install pry-doc` to get access to Ruby Core documentation.' + end + raise CommandError, fail_msg + end + end + + # @param [Class, Module] ancestors The ancestors to investigate + # @return [Method] The unwrapped super-method + def super_using_ancestors(ancestors, times=1) + next_owner = self.owner + times.times do + i = ancestors.index(next_owner) + 1 + while ancestors[i] && !(ancestors[i].method_defined?(name) || ancestors[i].private_method_defined?(name)) + i += 1 + end + next_owner = ancestors[i] or return nil + end + + safe_send(next_owner, :instance_method, name) rescue nil + end + + # @param [String] first_ln The first line of a method definition. + # @return [String, nil] + def method_name_from_first_line(first_ln) + return nil if first_ln.strip !~ /^def / + + tokens = CodeRay.scan(first_ln, :ruby) + tokens = tokens.tokens.each_slice(2) if tokens.respond_to?(:tokens) + tokens.each_cons(2) do |t1, t2| + if t2.last == :method || t2.last == :ident && t1 == [".", :operator] + return t2.first + end + end + + nil + end + + def c_source + info = pry_doc_info + if info and info.source + strip_comments_from_c_code(info.source) + end + end + + def ruby_source + # clone of MethodSource.source_helper that knows to use our + # hacked version of source_location for rbx core methods, and + # our input buffer for methods defined in (pry) + file, line = *source_location + raise SourceNotFoundError, "Could not locate source for #{name_with_owner}!" unless file + + begin + code = Pry::Code.from_file(file).expression_at(line) + rescue SyntaxError => e + raise MethodSource::SourceNotFoundError.new(e.message) + end + strip_leading_whitespace(code) + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/method/disowned.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/method/disowned.rb new file mode 100644 index 0000000..35908c9 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/method/disowned.rb @@ -0,0 +1,53 @@ +class Pry + class Method + # A Disowned Method is one that's been removed from the class on which it was defined. + # + # e.g. + # class C + # def foo + # C.send(:undefine_method, :foo) + # Pry::Method.from_binding(binding) + # end + # end + # + # In this case we assume that the "owner" is the singleton class of the receiver. + # + # This occurs mainly in Sinatra applications. + class Disowned < Method + attr_reader :receiver, :name + + # Create a new Disowned method. + # + # @param [Object] receiver + # @param [String] method_name + def initialize(receiver, method_name, binding=nil) + @receiver, @name = receiver, method_name + end + + # Is the method undefined? (aka `Disowned`) + # @return [Boolean] true + def undefined? + true + end + + # Can we get the source for this method? + # @return [Boolean] false + def source? + false + end + + # Get the hypothesized owner of the method. + # + # @return [Object] + def owner + class << receiver; self; end + end + + # Raise a more useful error message instead of trying to forward to nil. + def method_missing(meth_name, *args, &block) + raise "Cannot call '#{meth_name}' on an undef'd method." if method(:name).respond_to?(meth_name) + Object.instance_method(:method_missing).bind(self).call(meth_name, *args, &block) + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/method/patcher.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/method/patcher.rb new file mode 100644 index 0000000..3f736f6 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/method/patcher.rb @@ -0,0 +1,125 @@ +class Pry + class Method + class Patcher + attr_accessor :method + + @@source_cache = {} + + def initialize(method) + @method = method + end + + def self.code_for(filename) + @@source_cache[filename] + end + + # perform the patch + def patch_in_ram(source) + if method.alias? + with_method_transaction do + redefine source + end + else + redefine source + end + end + + private + + def redefine(source) + @@source_cache[cache_key] = source + TOPLEVEL_BINDING.eval wrap(source), cache_key + end + + def cache_key + "pry-redefined(0x#{method.owner.object_id.to_s(16)}##{method.name})" + end + + # Run some code ensuring that at the end target#meth_name will not have changed. + # + # When we're redefining aliased methods we will overwrite the method at the + # unaliased name (so that super continues to work). By wrapping that code in a + # transation we make that not happen, which means that alias_method_chains, etc. + # continue to work. + # + # @param [String] meth_name The method name before aliasing + # @param [Module] target The owner of the method + + def with_method_transaction + temp_name = "__pry_#{method.original_name}__" + method = self.method + method.owner.class_eval do + alias_method temp_name, method.original_name + yield + alias_method method.name, method.original_name + alias_method method.original_name, temp_name + end + + ensure + method.send(:remove_method, temp_name) rescue nil + end + + # Update the definition line so that it can be eval'd directly on the Method's + # owner instead of from the original context. + # + # In particular this takes `def self.foo` and turns it into `def foo` so that we + # don't end up creating the method on the singleton class of the singleton class + # by accident. + # + # This is necessarily done by String manipulation because we can't find out what + # syntax is needed for the argument list by ruby-level introspection. + # + # @param [String] line The original definition line. e.g. def self.foo(bar, baz=1) + # @return [String] The new definition line. e.g. def foo(bar, baz=1) + def definition_for_owner(line) + if line =~ /\Adef (?:.*?\.)?#{Regexp.escape(method.original_name)}(?=[\(\s;]|$)/ + "def #{method.original_name}#{$'}" + else + raise CommandError, "Could not find original `def #{method.original_name}` line to patch." + end + end + + # Apply wrap_for_owner and wrap_for_nesting successively to `source` + # @param [String] source + # @return [String] The wrapped source. + def wrap(source) + wrap_for_nesting(wrap_for_owner(source)) + end + + # Update the source code so that when it has the right owner when eval'd. + # + # This (combined with definition_for_owner) is backup for the case that + # wrap_for_nesting fails, to ensure that the method will stil be defined in + # the correct place. + # + # @param [String] source The source to wrap + # @return [String] + def wrap_for_owner(source) + Pry.current[:pry_owner] = method.owner + owner_source = definition_for_owner(source) + visibility_fix = "#{method.visibility.to_s} #{method.name.to_sym.inspect}" + "Pry.current[:pry_owner].class_eval do; #{owner_source}\n#{visibility_fix}\nend" + end + + # Update the new source code to have the correct Module.nesting. + # + # This method uses syntactic analysis of the original source file to determine + # the new nesting, so that we can tell the difference between: + # + # class A; def self.b; end; end + # class << A; def b; end; end + # + # The resulting code should be evaluated in the TOPLEVEL_BINDING. + # + # @param [String] source The source to wrap. + # @return [String] + def wrap_for_nesting(source) + nesting = Pry::Code.from_file(method.source_file).nesting_at(method.source_line) + + (nesting + [source] + nesting.map{ "end" } + [""]).join(";") + rescue Pry::Indent::UnparseableNestingError + source + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/method/weird_method_locator.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/method/weird_method_locator.rb new file mode 100644 index 0000000..b64b710 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/method/weird_method_locator.rb @@ -0,0 +1,186 @@ +class Pry + class Method + + # This class is responsible for locating the *real* `Pry::Method` + # object captured by a binding. + # + # Given a `Binding` from inside a method and a 'seed' Pry::Method object, + # there are primarily two situations where the seed method doesn't match + # the Binding: + # 1. The Pry::Method is from a subclass 2. The Pry::Method represents a method of the same name + # while the original was renamed to something else. For 1. we + # search vertically up the inheritance chain, + # and for 2. we search laterally along the object's method table. + # + # When we locate the method that matches the Binding we wrap it in + # Pry::Method and return it, or return nil if we fail. + class WeirdMethodLocator + class << self + + # Whether the given method object matches the associated binding. + # If the method object does not match the binding, then it's + # most likely not the method captured by the binding, and we + # must commence a search. + # + # @param [Pry::Method] method + # @param [Binding] b + # @return [Boolean] + def normal_method?(method, b) + method && (method.source_file && method.source_range rescue false) && + File.expand_path(method.source_file) == File.expand_path(b.eval('__FILE__')) && + method.source_range.include?(b.eval('__LINE__')) + end + + def weird_method?(method, b) + !normal_method?(method, b) + end + end + + attr_accessor :method + attr_accessor :target + + # @param [Pry::Method] method The seed method. + # @param [Binding] target The Binding that captures the method + # we want to locate. + def initialize(method, target) + @method, @target = method, target + end + + # @return [Pry::Method, nil] The Pry::Method that matches the + # given binding. + def get_method + find_method_in_superclass || find_renamed_method + end + + # @return [Boolean] Whether the Pry::Method is unrecoverable + # This usually happens when the method captured by the Binding + # has been subsequently deleted. + def lost_method? + !!(get_method.nil? && renamed_method_source_location) + end + + private + + def normal_method?(method) + self.class.normal_method?(method, target) + end + + def target_self + target.eval('self') + end + + def target_file + pry_file? ? target.eval('__FILE__') : File.expand_path(target.eval('__FILE__')) + end + + def target_line + target.eval('__LINE__') + end + + def pry_file? + Pry.eval_path == target.eval('__FILE__') + end + + # it's possible in some cases that the method we find by this approach is a sub-method of + # the one we're currently in, consider: + # + # class A; def b; binding.pry; end; end + # class B < A; def b; super; end; end + # + # Given that we can normally find the source_range of methods, and that we know which + # __FILE__ and __LINE__ the binding is at, we can hope to disambiguate these cases. + # + # This obviously won't work if the source is unavaiable for some reason, or if both + # methods have the same __FILE__ and __LINE__, or if we're in rbx where b.eval('__LINE__') + # is broken. + # + # @return [Pry::Method, nil] The Pry::Method representing the + # superclass method. + def find_method_in_superclass + guess = method + + while guess + # needs rescue if this is a Disowned method or a C method or something... + # TODO: Fix up the exception handling so we don't need a bare rescue + if normal_method?(guess) + return guess + else + guess = guess.super + end + end + + # Uhoh... none of the methods in the chain had the right __FILE__ and __LINE__ + # This may be caused by rbx https://github.com/rubinius/rubinius/issues/953, + # or other unknown circumstances (TODO: we should warn the user when this happens) + nil + end + + # This is the case where the name of a method has changed + # (via alias_method) so we locate the Method object for the + # renamed method. + # + # @return [Pry::Method, nil] The Pry::Method representing the + # renamed method + def find_renamed_method + return if !valid_file?(target_file) + alias_name = all_methods_for(target_self).find do |v| + expanded_source_location(target_self.method(v).source_location) == renamed_method_source_location + end + + alias_name && Pry::Method(target_self.method(alias_name)) + end + + def expanded_source_location(sl) + return if !sl + + if pry_file? + sl + else + [File.expand_path(sl.first), sl.last] + end + end + + # Use static analysis to locate the start of the method definition. + # We have the `__FILE__` and `__LINE__` from the binding and the + # original name of the method so we search up until we find a + # def/define_method, etc defining a method of the appropriate name. + # + # @return [Array] The `source_location` of the + # renamed method + def renamed_method_source_location + return @original_method_source_location if defined?(@original_method_source_location) + + source_index = lines_for_file(target_file)[0..(target_line - 1)].rindex do |v| + Pry::Method.method_definition?(method.name, v) + end + + @original_method_source_location = source_index && + [target_file, index_to_line_number(source_index)] + end + + def index_to_line_number(index) + # Pry.line_buffer is 0-indexed + pry_file? ? index : index + 1 + end + + def valid_file?(file) + (File.exists?(file) && !File.directory?(file)) || Pry.eval_path == file + end + + def lines_for_file(file) + @lines_for_file ||= {} + @lines_for_file[file] ||= if Pry.eval_path == file + Pry.line_buffer + else + File.readlines(file) + end + end + + def all_methods_for(obj) + obj.public_methods(false) + + obj.private_methods(false) + + obj.protected_methods(false) + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/module_candidate.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/module_candidate.rb new file mode 100644 index 0000000..4c97f13 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/module_candidate.rb @@ -0,0 +1,136 @@ +require 'pry/helpers/documentation_helpers' +require 'forwardable' + +class Pry + class WrappedModule + + # This class represents a single candidate for a module/class definition. + # It provides access to the source, documentation, line and file + # for a monkeypatch (reopening) of a class/module. + class Candidate + include Pry::Helpers::DocumentationHelpers + include Pry::CodeObject::Helpers + extend Forwardable + + # @return [String] The file where the module definition is located. + attr_reader :file + alias_method :source_file, :file + + # @return [Fixnum] The line where the module definition is located. + attr_reader :line + alias_method :source_line, :line + + # Methods to delegate to associated `Pry::WrappedModule + # instance`. + private_delegates = [:lines_for_file, :method_candidates, + :yard_docs?] + + public_delegates = [:wrapped, :module?, :class?, :name, :nonblank_name, + :number_of_candidates] + + def_delegators :@wrapper, *(private_delegates + public_delegates) + private(*private_delegates) + public(*public_delegates) + + # @raise [Pry::CommandError] If `rank` is out of bounds. + # @param [Pry::WrappedModule] wrapper The associated + # `Pry::WrappedModule` instance that owns the candidates. + # @param [Fixnum] rank The rank of the candidate to + # retrieve. Passing 0 returns 'primary candidate' (the candidate with largest + # number of methods), passing 1 retrieves candidate with + # second largest number of methods, and so on, up to + # `Pry::WrappedModule#number_of_candidates() - 1` + def initialize(wrapper, rank) + @wrapper = wrapper + + if number_of_candidates <= 0 + raise CommandError, "Cannot find a definition for #{name} module!" + elsif rank > (number_of_candidates - 1) + raise CommandError, "No such module candidate. Allowed candidates range is from 0 to #{number_of_candidates - 1}" + end + + @rank = rank + @file, @line = source_location + end + + # @raise [Pry::CommandError] If source code cannot be found. + # @return [String] The source for the candidate, i.e the + # complete module/class definition. + def source + return nil if file.nil? + return @source if @source + + @source = strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line, number_of_lines_in_first_chunk)) + end + + # @raise [Pry::CommandError] If documentation cannot be found. + # @return [String] The documentation for the candidate. + def doc + return nil if file.nil? + return @doc if @doc + + @doc = get_comment_content(Pry::Code.from_file(file).comment_describing(line)) + end + + # @return [Array, nil] A `[String, Fixnum]` pair representing the + # source location (file and line) for the candidate or `nil` + # if no source location found. + def source_location + return @source_location if @source_location + + file, line = first_method_source_location + return nil if !file.is_a?(String) + + @source_location = [file, first_line_of_module_definition(file, line)] + rescue Pry::RescuableException + nil + end + + private + + # Locate the first line of the module definition. + # @param [String] file The file that contains the module + # definition (somewhere). + # @param [Fixnum] line The module definition should appear + # before this line (if it exists). + # @return [Fixnum] The line where the module is defined. This + # line number is one-indexed. + def first_line_of_module_definition(file, line) + searchable_lines = lines_for_file(file)[0..(line - 2)] + searchable_lines.rindex { |v| class_regexes.any? { |r| r =~ v } } + 1 + end + + def class_regexes + mod_type_string = wrapped.class.to_s.downcase + [/^\s*#{mod_type_string}\s+(?:(?:\w*)::)*?#{wrapped.name.split(/::/).last}/, + /^\s*(::)?#{wrapped.name.split(/::/).last}\s*?=\s*?#{wrapped.class}/, + /^\s*(::)?#{wrapped.name.split(/::/).last}\.(class|instance)_eval/] + end + + # This method is used by `Candidate#source_location` as a + # starting point for the search for the candidate's definition. + # @return [Array] The source location of the base method used to + # calculate the source location of the candidate. + def first_method_source_location + @first_method_source_location ||= method_candidates[@rank].first.source_location + end + + # @return [Array] The source location of the last method in this + # candidate's module definition. + def last_method_source_location + @end_method_source_location ||= method_candidates[@rank].last.source_location + end + + # Return the number of lines between the start of the class definition + # and the start of the last method. We use this value so we can + # quickly grab these lines from the file (without having to + # check each intervening line for validity, which is expensive) speeding up source extraction. + # @return [Fixum] Number of lines. + def number_of_lines_in_first_chunk + end_method_line = last_method_source_location.last + + end_method_line - line + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/object_path.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/object_path.rb new file mode 100644 index 0000000..5bffb02 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/object_path.rb @@ -0,0 +1,82 @@ +class Pry + # `ObjectPath` implements the resolution of "object paths", which are strings + # that are similar to filesystem paths but meant for traversing Ruby objects. + # Examples of valid object paths include: + # + # x + # @foo/@bar + # "string"/upcase + # Pry/Method + # + # Object paths are mostly relevant in the context of the `cd` command. + # @see https://github.com/pry/pry/wiki/State-navigation + class ObjectPath + SPECIAL_TERMS = ["", "::", ".", ".."] + + # @param [String] path_string The object path expressed as a string. + # @param [Array] current_stack The current state of the binding + # stack. + def initialize(path_string, current_stack) + @path_string = path_string + @current_stack = current_stack + end + + # @return [Array] a new stack resulting from applying the given + # path to the current stack. + def resolve + scanner = StringScanner.new(@path_string.strip) + stack = @current_stack.dup + + begin + next_segment = "" + + loop do + # Scan for as long as we don't see a slash + next_segment << scanner.scan(/[^\/]*/) + + if complete?(next_segment) || scanner.eos? + scanner.getch # consume the slash + break + else + next_segment << scanner.getch # append the slash + end + end + + case next_segment.chomp + when "" + stack = [stack.first] + when "::" + stack.push(TOPLEVEL_BINDING) + when "." + next + when ".." + stack.pop unless stack.size == 1 + else + stack.push(Pry.binding_for(stack.last.eval(next_segment))) + end + rescue RescuableException => e + return handle_failure(next_segment, e) + end until scanner.eos? + + stack + end + + private + + def complete?(segment) + SPECIAL_TERMS.include?(segment) || Pry::Code.complete_expression?(segment) + end + + def handle_failure(context, err) + msg = [ + "Bad object path: #{@path_string.inspect}", + "Failed trying to resolve: #{context.inspect}", + "Exception: #{err.inspect}" + ].join("\n") + + raise CommandError.new(msg).tap { |e| + e.set_backtrace err.backtrace + } + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/output.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/output.rb new file mode 100644 index 0000000..b5f6bb3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/output.rb @@ -0,0 +1,50 @@ +class Pry + class Output + attr_reader :_pry_ + + def initialize(_pry_) + @_pry_ = _pry_ + end + + def puts(*objs) + return print "\n" if objs.empty? + + objs.each do |obj| + if ary = Array.try_convert(obj) + puts(*ary) + else + print "#{obj.to_s.chomp}\n" + end + end + + nil + end + + def print(*objs) + objs.each do |obj| + _pry_.config.output.print decolorize_maybe(obj.to_s) + end + + nil + end + alias << print + alias write print + + # If _pry_.config.color is currently false, removes ansi escapes from the string. + def decolorize_maybe(str) + if _pry_.config.color + str + else + Helpers::Text.strip_color str + end + end + + def method_missing(name, *args, &block) + _pry_.config.output.send(name, *args, &block) + end + + def respond_to_missing?(*a) + _pry_.config.respond_to?(*a) + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/pager.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/pager.rb new file mode 100644 index 0000000..0c9c73d --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/pager.rb @@ -0,0 +1,235 @@ +require 'pry/terminal' + +# A pager is an `IO`-like object that accepts text and either prints it +# immediately, prints it one page at a time, or streams it to an external +# program to print one page at a time. +class Pry::Pager + class StopPaging < StandardError + end + + attr_reader :_pry_ + + def initialize(_pry_) + @_pry_ = _pry_ + end + + # Send the given text through the best available pager (if `Pry.config.pager` is + # enabled). + # If you want to send text through in chunks as you generate it, use `open` to + # get a writable object instead. + # @param [String] text A piece of text to run through a pager. + # @param [IO] output (`$stdout`) An object to send output to. + def page(text) + open do |pager| + pager << text + end + end + + # Yields a pager object (`NullPager`, `SimplePager`, or `SystemPager`). All + # pagers accept output with `#puts`, `#print`, `#write`, and `#<<`. + # @param [IO] output (`$stdout`) An object to send output to. + def open + pager = best_available + yield pager + rescue StopPaging + ensure + pager.close if pager + end + + private + + attr_reader :output + def enabled?; !!@enabled; end + + # Return an instance of the "best" available pager class -- `SystemPager` if + # possible, `SimplePager` if `SystemPager` isn't available, and `NullPager` + # if the user has disabled paging. All pagers accept output with `#puts`, + # `#print`, `#write`, and `#<<`. You must call `#close` when you're done + # writing output to a pager, and you must rescue `Pry::Pager::StopPaging`. + # These requirements can be avoided by using `.open` instead. + # @param [#<<] output ($stdout) An object to send output to. + def best_available + if !_pry_.config.pager + NullPager.new(_pry_.output) + elsif !SystemPager.available? || Pry::Helpers::BaseHelpers.jruby? + SimplePager.new(_pry_.output) + else + SystemPager.new(_pry_.output) + end + end + + # `NullPager` is a "pager" that actually just prints all output as it comes + # in. Used when `Pry.config.pager` is false. + class NullPager + def initialize(out) + @out = out + end + + def puts(str) + print "#{str.chomp}\n" + end + + def print(str) + write str + end + alias << print + + def write(str) + @out.write str + end + + def close + end + + private + + def height + @height ||= Pry::Terminal.height! + end + + def width + @width ||= Pry::Terminal.width! + end + end + + # `SimplePager` is a straightforward pure-Ruby pager. We use it on JRuby and + # when we can't find a usable external pager. + class SimplePager < NullPager + def initialize(*) + super + @tracker = PageTracker.new(height - 3, width) + end + + def write(str) + str.lines.each do |line| + @out.print line + @tracker.record line + + if @tracker.page? + @out.print "\n" + @out.print "\e[0m" + @out.print " --- Press enter to continue " \ + "( q to break ) --- \n" + raise StopPaging if Readline.readline("").chomp == "q" + @tracker.reset + end + end + end + end + + # `SystemPager` buffers output until we're pretty sure it's at least a page + # long, then invokes an external pager and starts streaming output to it. If + # `#close` is called before then, it just prints out the buffered content. + class SystemPager < NullPager + def self.default_pager + pager = ENV["PAGER"] || "" + + # Default to less, and make sure less is being passed the correct options + if pager.strip.empty? or pager =~ /^less\b/ + pager = "less -R -F -X" + end + + pager + end + + def self.available? + if @system_pager.nil? + @system_pager = begin + pager_executable = default_pager.split(' ').first + `which #{pager_executable}` + $?.success? + rescue + false + end + else + @system_pager + end + end + + def initialize(*) + super + @tracker = PageTracker.new(height, width) + @buffer = "" + end + + def write(str) + if invoked_pager? + write_to_pager str + else + @tracker.record str + @buffer << str + + if @tracker.page? + write_to_pager @buffer + end + end + rescue Errno::EPIPE + raise StopPaging + end + + def close + if invoked_pager? + pager.close + else + @out.puts @buffer + end + end + + private + + def write_to_pager(text) + pager.write @out.decolorize_maybe(text) + end + + def invoked_pager? + @pager + end + + def pager + @pager ||= IO.popen(self.class.default_pager, 'w') + end + end + + # `PageTracker` tracks output to determine whether it's likely to take up a + # whole page. This doesn't need to be super precise, but we can use it for + # `SimplePager` and to avoid invoking the system pager unnecessarily. + # + # One simplifying assumption is that we don't need `#page?` to return `true` + # on the basis of an incomplete line. Long lines should be counted as + # multiple lines, but we don't have to transition from `false` to `true` + # until we see a newline. + class PageTracker + def initialize(rows, cols) + @rows, @cols = rows, cols + reset + end + + def record(str) + str.lines.each do |line| + if line.end_with? "\n" + @row += ((@col + line_length(line) - 1) / @cols) + 1 + @col = 0 + else + @col += line_length(line) + end + end + end + + def page? + @row >= @rows + end + + def reset + @row = 0 + @col = 0 + end + + private + + # Approximation of the printable length of a given line, without the + # newline and without ANSI color codes. + def line_length(line) + line.chomp.gsub(/\e\[[\d;]*m/, '').length + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/plugins.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/plugins.rb new file mode 100644 index 0000000..0813be3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/plugins.rb @@ -0,0 +1,103 @@ +class Pry + class PluginManager + PRY_PLUGIN_PREFIX = /^pry-/ + + # Placeholder when no associated gem found, displays warning + class NoPlugin + def initialize(name) + @name = name + end + + def method_missing(*args) + warn "Warning: The plugin '#{@name}' was not found! (no gem found)" + end + end + + class Plugin + attr_accessor :name, :gem_name, :enabled, :spec, :active + + def initialize(name, gem_name, spec, enabled) + @name, @gem_name, @enabled, @spec = name, gem_name, enabled, spec + end + + # Disable a plugin. (prevents plugin from being loaded, cannot + # disable an already activated plugin) + def disable! + self.enabled = false + end + + # Enable a plugin. (does not load it immediately but puts on + # 'white list' to be loaded) + def enable! + self.enabled = true + end + + # Load the Command line options defined by this plugin (if they exist) + def load_cli_options + cli_options_file = File.join(spec.full_gem_path, "lib/#{spec.name}/cli.rb") + require cli_options_file if File.exists?(cli_options_file) + end + # Activate the plugin (require the gem - enables/loads the + # plugin immediately at point of call, even if plugin is + # disabled) + # Does not reload plugin if it's already active. + def activate! + # Create the configuration object for the plugin. + Pry.config.send("#{gem_name.gsub('-', '_')}=", Pry::Config.from_hash({})) + + begin + require gem_name if !active? + rescue LoadError => e + warn "Found plugin #{gem_name}, but could not require '#{gem_name}'" + warn e + rescue => e + warn "require '#{gem_name}' # Failed, saying: #{e}" + end + + self.active = true + self.enabled = true + end + + alias active? active + alias enabled? enabled + end + + def initialize + @plugins = [] + end + + # Find all installed Pry plugins and store them in an internal array. + def locate_plugins + Gem.refresh + (Gem::Specification.respond_to?(:each) ? Gem::Specification : Gem.source_index.find_name('')).each do |gem| + next if gem.name !~ PRY_PLUGIN_PREFIX + plugin_name = gem.name.split('-', 2).last + @plugins << Plugin.new(plugin_name, gem.name, gem, true) if !gem_located?(gem.name) + end + @plugins + end + + # @return [Hash] A hash with all plugin names (minus the 'pry-') as + # keys and Plugin objects as values. + def plugins + h = Hash.new { |_, key| NoPlugin.new(key) } + @plugins.each do |plugin| + h[plugin.name] = plugin + end + h + end + + # Require all enabled plugins, disabled plugins are skipped. + def load_plugins + @plugins.each do |plugin| + plugin.activate! if plugin.enabled? + end + end + + private + def gem_located?(gem_name) + @plugins.any? { |plugin| plugin.gem_name == gem_name } + end + end + +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/prompt.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/prompt.rb new file mode 100644 index 0000000..62f0bc1 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/prompt.rb @@ -0,0 +1,26 @@ +class Pry::Prompt + MAP = { + "default" => { + value: Pry::DEFAULT_PROMPT, + description: "The default Pry prompt. Includes information about the\n" \ + "current expression number, evaluation context, and nesting\n" \ + "level, plus a reminder that you're using Pry." + }, + + "simple" => { + value: Pry::SIMPLE_PROMPT, + description: "A simple '>>'." + }, + + "nav" => { + value: Pry::NAV_PROMPT, + description: "A prompt that displays the binding stack as a path and\n" \ + "includes information about _in_ and _out_." + }, + + "none" => { + value: Pry::NO_PROMPT, + description: "Wave goodbye to the Pry prompt." + } + } +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/pry_class.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/pry_class.rb new file mode 100644 index 0000000..e9e97b9 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/pry_class.rb @@ -0,0 +1,375 @@ +require 'pry/config' +class Pry + + HOME_RC_FILE = ENV["PRYRC"] || "~/.pryrc" + LOCAL_RC_FILE = "./.pryrc" + + class << self + extend Forwardable + attr_accessor :custom_completions + attr_accessor :current_line + attr_accessor :line_buffer + attr_accessor :eval_path + attr_accessor :cli + attr_accessor :quiet + attr_accessor :last_internal_error + attr_accessor :config + attr_writer :history + + def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins + + extend Pry::Config::Convenience + config_shortcut *Pry::Config.shortcuts + + def prompt=(value) + config.prompt = value + end + + def prompt + config.prompt + end + + def history + @history ||= History.new + end + end + + # + # @return [main] + # returns the special instance of Object, "main". + # + def self.main + @main ||= TOPLEVEL_BINDING.eval "self" + end + + # + # @return [Pry::Config] + # Returns a value store for an instance of Pry running on the current thread. + # + def self.current + Thread.current[:__pry__] ||= Pry::Config.from_hash({}, nil) + end + + # Load the given file in the context of `Pry.toplevel_binding` + # @param [String] file The unexpanded file path. + def self.load_file_at_toplevel(file) + toplevel_binding.eval(File.read(file), file) + rescue RescuableException => e + puts "Error loading #{file}: #{e}\n#{e.backtrace.first}" + end + + # Load HOME_RC_FILE and LOCAL_RC_FILE if appropriate + # This method can also be used to reload the files if they have changed. + def self.load_rc_files + rc_files_to_load.each do |file| + critical_section do + load_file_at_toplevel(file) + end + end + end + + # Load the local RC file (./.pryrc) + def self.rc_files_to_load + files = [] + files << HOME_RC_FILE if Pry.config.should_load_rc + files << LOCAL_RC_FILE if Pry.config.should_load_local_rc + files.map { |file| real_path_to(file) }.compact.uniq + end + + # Expand a file to its canonical name (following symlinks as appropriate) + def self.real_path_to(file) + expanded = Pathname.new(File.expand_path(file)).realpath.to_s + # For rbx 1.9 mode [see rubinius issue #2165] + File.exist?(expanded) ? expanded : nil + rescue Errno::ENOENT + nil + end + + # Load any Ruby files specified with the -r flag on the command line. + def self.load_requires + Pry.config.requires.each do |file| + require file + end + end + + # Trap interrupts on jruby, and make them behave like MRI so we can + # catch them. + def self.load_traps + trap('INT'){ raise Interrupt } + end + + def self.load_win32console + begin + require 'win32console' + # The mswin and mingw versions of pry require win32console, so this should + # only fail on jruby (where win32console doesn't work). + # Instead we'll recommend ansicon, which does. + rescue LoadError + warn <<-WARNING if Pry.config.windows_console_warning +For a better Pry experience on Windows, please use ansicon: + https://github.com/adoxa/ansicon +If you use an alternative to ansicon and don't want to see this warning again, +you can add "Pry.config.windows_console_warning = false" to your .pryrc. + WARNING + end + end + + # Do basic setup for initial session. + # Including: loading .pryrc, loading plugins, loading requires, and + # loading history. + def self.initial_session_setup + return unless initial_session? + @initial_session = false + + # note these have to be loaded here rather than in pry_instance as + # we only want them loaded once per entire Pry lifetime. + load_rc_files + load_plugins if Pry.config.should_load_plugins + load_requires if Pry.config.should_load_requires + load_history if Pry.config.history.should_load + load_traps if Pry.config.should_trap_interrupts + load_win32console if Pry::Helpers::BaseHelpers.windows? && !Pry::Helpers::BaseHelpers.windows_ansi? + end + + # Start a Pry REPL. + # This method also loads `~/.pryrc` and `./.pryrc` as necessary the + # first time it is invoked. + # @param [Object, Binding] target The receiver of the Pry session + # @param [Hash] options + # @option options (see Pry#initialize) + # @example + # Pry.start(Object.new, :input => MyInput.new) + def self.start(target=nil, options={}) + return if ENV['DISABLE_PRY'] + options = options.to_hash + + if in_critical_section? + output.puts "ERROR: Pry started inside Pry." + output.puts "This can happen if you have a binding.pry inside a #to_s or #inspect function." + return + end + + options[:target] = Pry.binding_for(target || toplevel_binding) + options[:hooks] = Pry::Hooks.from_hash options.delete(:hooks) if options.key?(:hooks) + initial_session_setup + + # Unless we were given a backtrace, save the current one + if options[:backtrace].nil? + options[:backtrace] = caller + + # If Pry was started via `binding.pry`, elide that from the backtrace + if options[:backtrace].first =~ /pry.*core_extensions.*pry/ + options[:backtrace].shift + end + end + + driver = options[:driver] || Pry::REPL + + # Enter the matrix + driver.start(options) + rescue Pry::TooSafeException + puts "ERROR: Pry cannot work with $SAFE > 0" + raise + end + + # Execute the file through the REPL loop, non-interactively. + # @param [String] file_name File name to load through the REPL. + def self.load_file_through_repl(file_name) + require "pry/repl_file_loader" + REPLFileLoader.new(file_name).load + end + + # + # An inspector that clips the output to `max_length` chars. + # In case of > `max_length` chars the `# notation is used. + # + # @param [Object] obj + # The object to view. + # + # @param [Hash] options + # @option options [Integer] :max_length (60) + # The maximum number of chars before clipping occurs. + # + # @option options [Boolean] :id (false) + # Boolean to indicate whether or not a hex reprsentation of the object ID + # is attached to the return value when the length of inspect is greater than + # value of `:max_length`. + # + # @return [String] + # The string representation of `obj`. + # + def self.view_clip(obj, options = {}) + max = options.fetch :max_length, 60 + id = options.fetch :id, false + if obj.kind_of?(Module) && obj.name.to_s != "" && obj.name.to_s.length <= max + obj.name.to_s + elsif Pry.main == obj + # special-case to support jruby. + # fixed as of https://github.com/jruby/jruby/commit/d365ebd309cf9df3dde28f5eb36ea97056e0c039 + # we can drop in the future. + obj.to_s + elsif Pry.config.prompt_safe_objects.any? { |v| v === obj } && obj.inspect.length <= max + obj.inspect + else + id == true ? "#<#{obj.class}:0x%x>" % (obj.object_id << 1) : "#<#{obj.class}>" + end + rescue RescuableException + "unknown" + end + + # Load Readline history if required. + def self.load_history + Pry.history.load + end + + # @return [Boolean] Whether this is the first time a Pry session has + # been started since loading the Pry class. + def self.initial_session? + @initial_session + end + + # Run a Pry command from outside a session. The commands available are + # those referenced by `Pry.config.commands` (the default command set). + # @param [String] command_string The Pry command (including arguments, + # if any). + # @param [Hash] options Optional named parameters. + # @return [Object] The return value of the Pry command. + # @option options [Object, Binding] :target The object to run the + # command under. Defaults to `TOPLEVEL_BINDING` (main). + # @option options [Boolean] :show_output Whether to show command + # output. Defaults to true. + # @example Run at top-level with no output. + # Pry.run_command "ls" + # @example Run under Pry class, returning only public methods. + # Pry.run_command "ls -m", :target => Pry + # @example Display command output. + # Pry.run_command "ls -av", :show_output => true + def self.run_command(command_string, options={}) + options = { + :target => TOPLEVEL_BINDING, + :show_output => true, + :output => Pry.config.output, + :commands => Pry.config.commands + }.merge!(options) + + # :context for compatibility with <= 0.9.11.4 + target = options[:context] || options[:target] + output = options[:show_output] ? options[:output] : StringIO.new + + pry = Pry.new(:output => output, :target => target, :commands => options[:commands]) + pry.eval command_string + end + + def self.default_editor_for_platform + return ENV['VISUAL'] if ENV['VISUAL'] and not ENV['VISUAL'].empty? + return ENV['EDITOR'] if ENV['EDITOR'] and not ENV['EDITOR'].empty? + if Helpers::BaseHelpers.windows? + 'notepad' + else + %w(editor nano vi).detect do |editor| + system("which #{editor} > /dev/null 2>&1") + end + end + end + + def self.auto_resize! + Pry.config.input # by default, load Readline + + if !defined?(Readline) || Pry.config.input != Readline + warn "Sorry, you must be using Readline for Pry.auto_resize! to work." + return + end + + if Readline::VERSION =~ /edit/i + warn <<-EOT +Readline version #{Readline::VERSION} detected - will not auto_resize! correctly. + For the fix, use GNU Readline instead: + https://github.com/guard/guard/wiki/Add-proper-Readline-support-to-Ruby-on-Mac-OS-X + EOT + return + end + + trap :WINCH do + begin + Readline.set_screen_size(*Terminal.size!) + rescue => e + warn "\nPry.auto_resize!'s Readline.set_screen_size failed: #{e}" + end + begin + Readline.refresh_line + rescue => e + warn "\nPry.auto_resize!'s Readline.refresh_line failed: #{e}" + end + end + end + + # Set all the configurable options back to their default values + def self.reset_defaults + @initial_session = true + self.config = Pry::Config.new Pry::Config::Default.new + self.cli = false + self.current_line = 1 + self.line_buffer = [""] + self.eval_path = "(pry)" + end + + # Basic initialization. + def self.init + @plugin_manager ||= PluginManager.new + reset_defaults + locate_plugins + end + + # Return a `Binding` object for `target` or return `target` if it is + # already a `Binding`. + # In the case where `target` is top-level then return `TOPLEVEL_BINDING` + # @param [Object] target The object to get a `Binding` object for. + # @return [Binding] The `Binding` object. + def self.binding_for(target) + if Binding === target + target + else + if Pry.main == target + TOPLEVEL_BINDING + else + target.__binding__ + end + end + end + + def self.toplevel_binding + unless defined?(@toplevel_binding) && @toplevel_binding + # Grab a copy of the TOPLEVEL_BINDING without any local variables. + # This binding has a default definee of Object, and new methods are + # private (just as in TOPLEVEL_BINDING). + TOPLEVEL_BINDING.eval <<-RUBY + def self.__pry__ + binding + end + Pry.toplevel_binding = __pry__ + class << self; undef __pry__; end + RUBY + end + @toplevel_binding.eval('private') + @toplevel_binding + end + + def self.toplevel_binding=(binding) + @toplevel_binding = binding + end + + def self.in_critical_section? + Thread.current[:pry_critical_section] ||= 0 + Thread.current[:pry_critical_section] > 0 + end + + def self.critical_section(&block) + Thread.current[:pry_critical_section] ||= 0 + Thread.current[:pry_critical_section] += 1 + yield + ensure + Thread.current[:pry_critical_section] -= 1 + end +end + +Pry.init diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/pry_instance.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/pry_instance.rb new file mode 100644 index 0000000..7122b59 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/pry_instance.rb @@ -0,0 +1,654 @@ +# -*- coding: utf-8 -*- +## +# Pry is a powerful alternative to the standard IRB shell for Ruby. It +# features syntax highlighting, a flexible plugin architecture, runtime +# invocation and source and documentation browsing. +# +# Pry can be started similar to other command line utilities by simply running +# the following command: +# +# pry +# +# Once inside Pry you can invoke the help message: +# +# help +# +# This will show a list of available commands and their usage. For more +# information about Pry you can refer to the following resources: +# +# * http://pry.github.com/ +# * https://github.com/pry/pry +# * the IRC channel, which is #pry on the Freenode network +# + +class Pry + attr_accessor :binding_stack + attr_accessor :custom_completions + attr_accessor :eval_string + attr_accessor :backtrace + attr_accessor :suppress_output + attr_accessor :last_result + attr_accessor :last_file + attr_accessor :last_dir + + attr_reader :last_exception + attr_reader :command_state + attr_reader :exit_value + attr_reader :input_array + attr_reader :output_array + attr_reader :config + + extend Pry::Config::Convenience + config_shortcut *Pry::Config.shortcuts + EMPTY_COMPLETIONS = [].freeze + + # Create a new {Pry} instance. + # @param [Hash] options + # @option options [#readline] :input + # The object to use for input. + # @option options [#puts] :output + # The object to use for output. + # @option options [Pry::CommandBase] :commands + # The object to use for commands. + # @option options [Hash] :hooks + # The defined hook Procs. + # @option options [Array] :prompt + # The array of Procs to use for prompts. + # @option options [Proc] :print + # The Proc to use for printing return values. + # @option options [Boolean] :quiet + # Omit the `whereami` banner when starting. + # @option options [Array] :backtrace + # The backtrace of the session's `binding.pry` line, if applicable. + # @option options [Object] :target + # The initial context for this session. + def initialize(options={}) + @binding_stack = [] + @indent = Pry::Indent.new + @command_state = {} + @eval_string = "" + @backtrace = options.delete(:backtrace) || caller + target = options.delete(:target) + @config = Pry::Config.new + config.merge!(options) + push_prompt(config.prompt) + @input_array = Pry::HistoryArray.new config.memory_size + @output_array = Pry::HistoryArray.new config.memory_size + @custom_completions = config.command_completions + set_last_result nil + @input_array << nil + push_initial_binding(target) + exec_hook(:when_started, target, options, self) + end + + # The current prompt. + # This is the prompt at the top of the prompt stack. + # + # @example + # self.prompt = Pry::SIMPLE_PROMPT + # self.prompt # => Pry::SIMPLE_PROMPT + # + # @return [Array] Current prompt. + def prompt + prompt_stack.last + end + + def prompt=(new_prompt) + if prompt_stack.empty? + push_prompt new_prompt + else + prompt_stack[-1] = new_prompt + end + end + + # Initialize this instance by pushing its initial context into the binding + # stack. If no target is given, start at the top level. + def push_initial_binding(target=nil) + push_binding(target || Pry.toplevel_binding) + end + + # The currently active `Binding`. + # @return [Binding] The currently active `Binding` for the session. + def current_binding + binding_stack.last + end + alias current_context current_binding # support previous API + + # Push a binding for the given object onto the stack. If this instance is + # currently stopped, mark it as usable again. + def push_binding(object) + @stopped = false + binding_stack << Pry.binding_for(object) + end + + # + # Generate completions. + # + # @param [String] input + # What the user has typed so far + # + # @return [Array] + # Possible completions + # + def complete(str) + return EMPTY_COMPLETIONS unless config.completer + Pry.critical_section do + completer = config.completer.new(config.input, self) + completer.call str, target: current_binding, custom_completions: custom_completions.call.push(*sticky_locals.keys) + end + end + + # + # Injects a local variable into the provided binding. + # + # @param [String] name + # The name of the local to inject. + # + # @param [Object] value + # The value to set the local to. + # + # @param [Binding] b + # The binding to set the local on. + # + # @return [Object] + # The value the local was set to. + # + def inject_local(name, value, b) + value = Proc === value ? value.call : value + if b.respond_to?(:local_variable_set) + b.local_variable_set name, value + else # < 2.1 + begin + Pry.current[:pry_local] = value + b.eval "#{name} = ::Pry.current[:pry_local]" + ensure + Pry.current[:pry_local] = nil + end + end + end + + # @return [Integer] The maximum amount of objects remembered by the inp and + # out arrays. Defaults to 100. + def memory_size + @output_array.max_size + end + + def memory_size=(size) + @input_array = Pry::HistoryArray.new(size) + @output_array = Pry::HistoryArray.new(size) + end + + # Inject all the sticky locals into the current binding. + def inject_sticky_locals! + sticky_locals.each_pair do |name, value| + inject_local(name, value, current_binding) + end + end + + # Add a sticky local to this Pry instance. + # A sticky local is a local that persists between all bindings in a session. + # @param [Symbol] name The name of the sticky local. + # @yield The block that defines the content of the local. The local + # will be refreshed at each tick of the repl loop. + def add_sticky_local(name, &block) + config.extra_sticky_locals[name] = block + end + + def sticky_locals + { _in_: input_array, + _out_: output_array, + _pry_: self, + _ex_: last_exception && last_exception.wrapped_exception, + _file_: last_file, + _dir_: last_dir, + _: proc { last_result }, + __: proc { output_array[-2] } + }.merge(config.extra_sticky_locals) + end + + # Reset the current eval string. If the user has entered part of a multiline + # expression, this discards that input. + def reset_eval_string + @eval_string = "" + end + + # Pass a line of input to Pry. + # + # This is the equivalent of `Binding#eval` but with extra Pry! + # + # In particular: + # 1. Pry commands will be executed immediately if the line matches. + # 2. Partial lines of input will be queued up until a complete expression has + # been accepted. + # 3. Output is written to `#output` in pretty colours, not returned. + # + # Once this method has raised an exception or returned false, this instance + # is no longer usable. {#exit_value} will return the session's breakout + # value if applicable. + # + # @param [String?] line The line of input; `nil` if the user types `` + # @option options [Boolean] :generated Whether this line was generated automatically. + # Generated lines are not stored in history. + # @return [Boolean] Is Pry ready to accept more input? + # @raise [Exception] If the user uses the `raise-up` command, this method + # will raise that exception. + def eval(line, options={}) + return false if @stopped + + exit_value = nil + exception = catch(:raise_up) do + exit_value = catch(:breakout) do + handle_line(line, options) + # We use 'return !@stopped' here instead of 'return true' so that if + # handle_line has stopped this pry instance (e.g. by opening _pry_.repl and + # then popping all the bindings) we still exit immediately. + return !@stopped + end + exception = false + end + + @stopped = true + @exit_value = exit_value + + # TODO: make this configurable? + raise exception if exception + return false + end + + def handle_line(line, options) + if line.nil? + config.control_d_handler.call(@eval_string, self) + return + end + + ensure_correct_encoding!(line) + Pry.history << line unless options[:generated] + + @suppress_output = false + inject_sticky_locals! + begin + if !process_command_safely(line.lstrip) + @eval_string << "#{line.chomp}\n" if !line.empty? || !@eval_string.empty? + end + rescue RescuableException => e + self.last_exception = e + result = e + + Pry.critical_section do + show_result(result) + end + return + end + + # This hook is supposed to be executed after each line of ruby code + # has been read (regardless of whether eval_string is yet a complete expression) + exec_hook :after_read, eval_string, self + + begin + complete_expr = Pry::Code.complete_expression?(@eval_string) + rescue SyntaxError => e + output.puts "SyntaxError: #{e.message.sub(/.*syntax error, */m, '')}" + reset_eval_string + end + + if complete_expr + if @eval_string =~ /;\Z/ || @eval_string.empty? || @eval_string =~ /\A *#.*\n\z/ + @suppress_output = true + end + + # A bug in jruby makes java.lang.Exception not rescued by + # `rescue Pry::RescuableException` clause. + # + # * https://github.com/pry/pry/issues/854 + # * https://jira.codehaus.org/browse/JRUBY-7100 + # + # Until that gets fixed upstream, treat java.lang.Exception + # as an additional exception to be rescued explicitly. + # + # This workaround has a side effect: java exceptions specified + # in `Pry.config.exception_whitelist` are ignored. + jruby_exceptions = [] + if Pry::Helpers::BaseHelpers.jruby? + jruby_exceptions << Java::JavaLang::Exception + end + + begin + # Reset eval string, in case we're evaluating Ruby that does something + # like open a nested REPL on this instance. + eval_string = @eval_string + reset_eval_string + + result = evaluate_ruby(eval_string) + rescue RescuableException, *jruby_exceptions => e + # Eliminate following warning: + # warning: singleton on non-persistent Java type X + # (http://wiki.jruby.org/Persistence) + if Pry::Helpers::BaseHelpers.jruby? && e.class.respond_to?('__persistent__') + e.class.__persistent__ = true + end + self.last_exception = e + result = e + end + + Pry.critical_section do + show_result(result) + end + end + + throw(:breakout) if current_binding.nil? + end + private :handle_line + + # Potentially deprecated — Use `Pry::REPL.new(pry, :target => target).start` + # (If nested sessions are going to exist, this method is fine, but a goal is + # to come up with an alternative to nested sessions altogether.) + def repl(target = nil) + Pry::REPL.new(self, :target => target).start + end + + def evaluate_ruby(code) + inject_sticky_locals! + exec_hook :before_eval, code, self + + result = current_binding.eval(code, Pry.eval_path, Pry.current_line) + set_last_result(result, code) + ensure + update_input_history(code) + exec_hook :after_eval, result, self + end + + # Output the result or pass to an exception handler (if result is an exception). + def show_result(result) + if last_result_is_exception? + exception_handler.call(output, result, self) + elsif should_print? + print.call(output, result, self) + else + # nothin' + end + rescue RescuableException => e + # Being uber-paranoid here, given that this exception arose because we couldn't + # serialize something in the user's program, let's not assume we can serialize + # the exception either. + begin + output.puts "(pry) output error: #{e.inspect}" + rescue RescuableException => e + if last_result_is_exception? + output.puts "(pry) output error: failed to show exception" + else + output.puts "(pry) output error: failed to show result" + end + end + ensure + output.flush if output.respond_to?(:flush) + end + + # Force `eval_string` into the encoding of `val`. [Issue #284] + def ensure_correct_encoding!(val) + if @eval_string.empty? && + val.respond_to?(:encoding) && + val.encoding != @eval_string.encoding + @eval_string.force_encoding(val.encoding) + end + end + private :ensure_correct_encoding! + + # If the given line is a valid command, process it in the context of the + # current `eval_string` and binding. + # @param [String] val The line to process. + # @return [Boolean] `true` if `val` is a command, `false` otherwise + def process_command(val) + val = val.chomp + result = commands.process_line(val, + :target => current_binding, + :output => output, + :eval_string => @eval_string, + :pry_instance => self + ) + + # set a temporary (just so we can inject the value we want into eval_string) + Pry.current[:pry_cmd_result] = result + + # note that `result` wraps the result of command processing; if a + # command was matched and invoked then `result.command?` returns true, + # otherwise it returns false. + if result.command? + if !result.void_command? + # the command that was invoked was non-void (had a return value) and so we make + # the value of the current expression equal to the return value + # of the command. + @eval_string.replace "::Pry.current[:pry_cmd_result].retval\n" + end + true + else + false + end + end + + # Same as process_command, but outputs exceptions to `#output` instead of + # raising. + # @param [String] val The line to process. + # @return [Boolean] `true` if `val` is a command, `false` otherwise + def process_command_safely(val) + process_command(val) + rescue CommandError, Slop::InvalidOptionError, MethodSource::SourceNotFoundError => e + Pry.last_internal_error = e + output.puts "Error: #{e.message}" + true + end + + # Run the specified command. + # @param [String] val The command (and its params) to execute. + # @return [Pry::Command::VOID_VALUE] + # @example + # pry_instance.run_command("ls -m") + def run_command(val) + commands.process_line(val, + :eval_string => @eval_string, + :target => current_binding, + :pry_instance => self, + :output => output + ) + Pry::Command::VOID_VALUE + end + + # Execute the specified hook. + # @param [Symbol] name The hook name to execute + # @param [*Object] args The arguments to pass to the hook + # @return [Object, Exception] The return value of the hook or the exception raised + # + # If executing a hook raises an exception, we log that and then continue sucessfully. + # To debug such errors, use the global variable $pry_hook_error, which is set as a + # result. + def exec_hook(name, *args, &block) + e_before = hooks.errors.size + hooks.exec_hook(name, *args, &block).tap do + hooks.errors[e_before..-1].each do |e| + output.puts "#{name} hook failed: #{e.class}: #{e.message}" + output.puts "#{e.backtrace.first}" + output.puts "(see _pry_.hooks.errors to debug)" + end + end + end + + # Set the last result of an eval. + # This method should not need to be invoked directly. + # @param [Object] result The result. + # @param [String] code The code that was run. + def set_last_result(result, code="") + @last_result_is_exception = false + @output_array << result + + self.last_result = result unless code =~ /\A\s*\z/ + end + + # + # Set the last exception for a session. + # + # @param [Exception] e + # the last exception. + # + def last_exception=(e) + last_exception = Pry::LastException.new(e) + @last_result_is_exception = true + @output_array << last_exception + @last_exception = last_exception + end + + # Update Pry's internal state after evalling code. + # This method should not need to be invoked directly. + # @param [String] code The code we just eval'd + def update_input_history(code) + # Always push to the @input_array as the @output_array is always pushed to. + @input_array << code + if code + Pry.line_buffer.push(*code.each_line) + Pry.current_line += code.each_line.count + end + end + + # @return [Boolean] True if the last result is an exception that was raised, + # as opposed to simply an instance of Exception (like the result of + # Exception.new) + def last_result_is_exception? + @last_result_is_exception + end + + # Whether the print proc should be invoked. + # Currently only invoked if the output is not suppressed. + # @return [Boolean] Whether the print proc should be invoked. + def should_print? + !@suppress_output + end + + # Returns the appropriate prompt to use. + # @return [String] The prompt. + def select_prompt + object = current_binding.eval('self') + + open_token = @indent.open_delimiters.any? ? @indent.open_delimiters.last : + @indent.stack.last + + c = Pry::Config.from_hash({ + :object => object, + :nesting_level => binding_stack.size - 1, + :open_token => open_token, + :session_line => Pry.history.session_line_count + 1, + :history_line => Pry.history.history_line_count + 1, + :expr_number => input_array.count, + :_pry_ => self, + :binding_stack => binding_stack, + :input_array => input_array, + :eval_string => @eval_string, + :cont => !@eval_string.empty?}) + + Pry.critical_section do + # If input buffer is empty then use normal prompt + if eval_string.empty? + generate_prompt(Array(prompt).first, c) + + # Otherwise use the wait prompt (indicating multi-line expression) + else + generate_prompt(Array(prompt).last, c) + end + end + end + + def generate_prompt(prompt_proc, conf) + if prompt_proc.arity == 1 + prompt_proc.call(conf) + else + prompt_proc.call(conf.object, conf.nesting_level, conf._pry_) + end + end + private :generate_prompt + + # the array that the prompt stack is stored in + def prompt_stack + @prompt_stack ||= Array.new + end + private :prompt_stack + + # Pushes the current prompt onto a stack that it can be restored from later. + # Use this if you wish to temporarily change the prompt. + # @param [Array] new_prompt + # @return [Array] new_prompt + # @example + # new_prompt = [ proc { '>' }, proc { '>>' } ] + # push_prompt(new_prompt) # => new_prompt + def push_prompt(new_prompt) + prompt_stack.push new_prompt + end + + # Pops the current prompt off of the prompt stack. + # If the prompt you are popping is the last prompt, it will not be popped. + # Use this to restore the previous prompt. + # @return [Array] Prompt being popped. + # @example + # prompt1 = [ proc { '>' }, proc { '>>' } ] + # prompt2 = [ proc { '$' }, proc { '>' } ] + # pry = Pry.new :prompt => prompt1 + # pry.push_prompt(prompt2) + # pry.pop_prompt # => prompt2 + # pry.pop_prompt # => prompt1 + # pry.pop_prompt # => prompt1 + def pop_prompt + prompt_stack.size > 1 ? prompt_stack.pop : prompt + end + + # Returns the currently configured pager + # @example + # _pry_.pager.page text + def pager + Pry::Pager.new(self) + end + + # Returns an output device + # @example + # _pry_.output.puts "ohai!" + def output + Pry::Output.new(self) + end + + # Raise an exception out of Pry. + # + # See Kernel#raise for documentation of parameters. + # See rb_make_exception for the inbuilt implementation. + # + # This is necessary so that the raise-up command can tell the + # difference between an exception the user has decided to raise, + # and a mistake in specifying that exception. + # + # (i.e. raise-up RunThymeError.new should not be the same as + # raise-up NameError, "unititialized constant RunThymeError") + # + def raise_up_common(force, *args) + exception = if args == [] + last_exception || RuntimeError.new + elsif args.length == 1 && args.first.is_a?(String) + RuntimeError.new(args.first) + elsif args.length > 3 + raise ArgumentError, "wrong number of arguments" + elsif !args.first.respond_to?(:exception) + raise TypeError, "exception class/object expected" + elsif args.length === 1 + args.first.exception + else + args.first.exception(args[1]) + end + + raise TypeError, "exception object expected" unless exception.is_a? Exception + + exception.set_backtrace(args.length === 3 ? args[2] : caller(1)) + + if force || binding_stack.one? + binding_stack.clear + throw :raise_up, exception + else + binding_stack.pop + raise exception + end + end + def raise_up(*args); raise_up_common(false, *args); end + def raise_up!(*args); raise_up_common(true, *args); end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/rbx_path.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/rbx_path.rb new file mode 100644 index 0000000..bd969c6 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/rbx_path.rb @@ -0,0 +1,22 @@ +class Pry + module RbxPath + module_function + def is_core_path?(path) + Pry::Helpers::BaseHelpers.rbx? && (path.start_with?("kernel") || path.start_with?("lib")) && File.exist?(convert_path_to_full(path)) + end + + def convert_path_to_full(path) + if path.start_with?("kernel") + File.join File.dirname(Rubinius::KERNEL_PATH), path + elsif path.start_with?("lib") + File.join File.dirname(Rubinius::LIB_PATH), path + else + path + end + end + + def rvm_ruby?(path) + !!(path =~ /\.rvm/) + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/repl.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/repl.rb new file mode 100644 index 0000000..4748785 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/repl.rb @@ -0,0 +1,202 @@ +require 'forwardable' + +class Pry + class REPL + extend Forwardable + def_delegators :@pry, :input, :output + + # @return [Pry] The instance of {Pry} that the user is controlling. + attr_accessor :pry + + # Instantiate a new {Pry} instance with the given options, then start a + # {REPL} instance wrapping it. + # @option options See {Pry#initialize} + def self.start(options) + new(Pry.new(options)).start + end + + # Create an instance of {REPL} wrapping the given {Pry}. + # @param [Pry] pry The instance of {Pry} that this {REPL} will control. + # @param [Hash] options Options for this {REPL} instance. + # @option options [Object] :target The initial target of the session. + def initialize(pry, options = {}) + @pry = pry + @indent = Pry::Indent.new + + if options[:target] + @pry.push_binding options[:target] + end + end + + # Start the read-eval-print loop. + # @return [Object?] If the session throws `:breakout`, return the value + # thrown with it. + # @raise [Exception] If the session throws `:raise_up`, raise the exception + # thrown with it. + def start + prologue + Pry::InputLock.for(:all).with_ownership { repl } + ensure + epilogue + end + + private + + # Set up the repl session. + # @return [void] + def prologue + pry.exec_hook :before_session, pry.output, pry.current_binding, pry + + # Clear the line before starting Pry. This fixes issue #566. + if pry.config.correct_indent + Kernel.print Pry::Helpers::BaseHelpers.windows_ansi? ? "\e[0F" : "\e[0G" + end + end + + # The actual read-eval-print loop. + # + # The {REPL} instance is responsible for reading and looping, whereas the + # {Pry} instance is responsible for evaluating user input and printing + # return values and command output. + # + # @return [Object?] If the session throws `:breakout`, return the value + # thrown with it. + # @raise [Exception] If the session throws `:raise_up`, raise the exception + # thrown with it. + def repl + loop do + case val = read + when :control_c + output.puts "" + pry.reset_eval_string + when :no_more_input + output.puts "" if output.tty? + break + else + output.puts "" if val.nil? && output.tty? + return pry.exit_value unless pry.eval(val) + end + end + end + + # Clean up after the repl session. + # @return [void] + def epilogue + pry.exec_hook :after_session, pry.output, pry.current_binding, pry + end + + # Read a line of input from the user. + # @return [String] The line entered by the user. + # @return [nil] On ``. + # @return [:control_c] On ``. + # @return [:no_more_input] On EOF. + def read + @indent.reset if pry.eval_string.empty? + current_prompt = pry.select_prompt + indentation = pry.config.auto_indent ? @indent.current_prefix : '' + + val = read_line("#{current_prompt}#{indentation}") + + # Return nil for EOF, :no_more_input for error, or :control_c for + return val unless String === val + + if pry.config.auto_indent + original_val = "#{indentation}#{val}" + indented_val = @indent.indent(val) + + if output.tty? && pry.config.correct_indent && Pry::Helpers::BaseHelpers.use_ansi_codes? + output.print @indent.correct_indentation( + current_prompt, indented_val, + original_val.length - indented_val.length + ) + output.flush + end + else + indented_val = val + end + + indented_val + end + + # Manage switching of input objects on encountering `EOFError`s. + # @return [Object] Whatever the given block returns. + # @return [:no_more_input] Indicates that no more input can be read. + def handle_read_errors + should_retry = true + exception_count = 0 + + begin + yield + rescue EOFError + pry.config.input = Pry.config.input + if !should_retry + output.puts "Error: Pry ran out of things to read from! " \ + "Attempting to break out of REPL." + return :no_more_input + end + should_retry = false + retry + + # Handle like Bash: empty the current input buffer, but don't + # quit. This is only for MRI 1.9; other versions of Ruby don't let you + # send Interrupt from within Readline. + rescue Interrupt + return :control_c + + # If we get a random error when trying to read a line we don't want to + # automatically retry, as the user will see a lot of error messages + # scroll past and be unable to do anything about it. + rescue RescuableException => e + puts "Error: #{e.message}" + output.puts e.backtrace + exception_count += 1 + if exception_count < 5 + retry + end + puts "FATAL: Pry failed to get user input using `#{input}`." + puts "To fix this you may be able to pass input and output file " \ + "descriptors to pry directly. e.g." + puts " Pry.config.input = STDIN" + puts " Pry.config.output = STDOUT" + puts " binding.pry" + return :no_more_input + end + end + + # Returns the next line of input to be sent to the {Pry} instance. + # @param [String] current_prompt The prompt to use for input. + # @return [String?] The next line of input, or `nil` on . + def read_line(current_prompt) + handle_read_errors do + if defined? Coolline and input.is_a? Coolline + input.completion_proc = proc do |cool| + completions = @pry.complete cool.completed_word + completions.compact + end + elsif input.respond_to? :completion_proc= + input.completion_proc = proc do |input| + @pry.complete input + end + end + + if defined?(Readline) and input == Readline + input_readline(current_prompt, false) # false since we'll add it manually + elsif defined? Coolline and input.is_a? Coolline + input_readline(current_prompt) + else + if input.method(:readline).arity == 1 + input_readline(current_prompt) + else + input_readline + end + end + end + end + + def input_readline(*args) + Pry::InputLock.for(:all).interruptible_region do + input.readline(*args) + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/repl_file_loader.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/repl_file_loader.rb new file mode 100644 index 0000000..cd8de9a --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/repl_file_loader.rb @@ -0,0 +1,74 @@ +class Pry + + # A class to manage the loading of files through the REPL loop. + # This is an interesting trick as it processes your file as if it + # was user input in an interactive session. As a result, all Pry + # commands are available, and they are executed non-interactively. Furthermore + # the session becomes interactive when the repl loop processes a + # 'make-interactive' command in the file. The session also becomes + # interactive when an exception is encountered, enabling you to fix + # the error before returning to non-interactive processing with the + # 'make-non-interactive' command. + + class REPLFileLoader + def initialize(file_name) + full_name = File.expand_path(file_name) + raise RuntimeError, "No such file: #{full_name}" if !File.exists?(full_name) + + define_additional_commands + @content = File.read(full_name) + end + + # Switch to interactive mode, i.e take input from the user + # and use the regular print and exception handlers. + # @param [Pry] _pry_ the Pry instance to make interactive. + def interactive_mode(_pry_) + _pry_.config.input = Pry.config.input + _pry_.config.print = Pry.config.print + _pry_.config.exception_handler = Pry.config.exception_handler + Pry::REPL.new(_pry_).start + end + + # Switch to non-interactive mode. Essentially + # this means there is no result output + # and that the session becomes interactive when an exception is encountered. + # @param [Pry] _pry_ the Pry instance to make non-interactive. + def non_interactive_mode(_pry_, content) + _pry_.print = proc {} + _pry_.exception_handler = proc do |o, e, _p_| + _p_.run_command "cat --ex" + o.puts "...exception encountered, going interactive!" + interactive_mode(_pry_) + end + + content.lines.each do |line| + break unless _pry_.eval line, :generated => true + end + + unless _pry_.eval_string.empty? + _pry_.output.puts "#{_pry_.eval_string}...exception encountered, going interactive!" + interactive_mode(_pry_) + end + end + + # Define a few extra commands useful for flipping back & forth + # between interactive/non-interactive modes + def define_additional_commands + s = self + + Pry::Commands.command "make-interactive", "Make the session interactive" do + s.interactive_mode(_pry_) + end + + Pry::Commands.command "load-file", "Load another file through the repl" do |file_name| + s.non_interactive_mode(_pry_, File.read(File.expand_path(file_name))) + end + end + + # Actually load the file through the REPL by setting file content + # as the REPL input stream. + def load + non_interactive_mode(Pry.new, @content) + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/rubygem.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/rubygem.rb new file mode 100644 index 0000000..36f788d --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/rubygem.rb @@ -0,0 +1,82 @@ +require 'rubygems' + +class Pry + module Rubygem + + class << self + def installed?(name) + if Gem::Specification.respond_to?(:find_all_by_name) + Gem::Specification.find_all_by_name(name).any? + else + Gem.source_index.find_name(name).first + end + end + + # Get the gem spec object for the given gem name. + # + # @param [String] name + # @return [Gem::Specification] + def spec(name) + specs = if Gem::Specification.respond_to?(:each) + Gem::Specification.find_all_by_name(name) + else + Gem.source_index.find_name(name) + end + + first_spec = specs.sort_by{ |spec| Gem::Version.new(spec.version) }.last + + first_spec or raise CommandError, "Gem `#{name}` not found" + end + + # List gems matching a pattern. + # + # @param [Regexp] pattern + # @return [Array] + def list(pattern = /.*/) + if Gem::Specification.respond_to?(:each) + Gem::Specification.select{|spec| spec.name =~ pattern } + else + Gem.source_index.gems.values.select{|spec| spec.name =~ pattern } + end + end + + # Completion function for gem-cd and gem-open. + # + # @param [String] so_far what the user's typed so far + # @return [Array] completions + def complete(so_far) + if so_far =~ / ([^ ]*)\z/ + self.list(%r{\A#{$2}}).map(&:name) + else + self.list.map(&:name) + end + end + + # Installs a gem with all its dependencies. + # + # @param [String] name + # @return [void] + def install(name) + gemrc_opts = Gem.configuration['gem'].split(' ') + destination = if gemrc_opts.include?('--user-install') + Gem.user_dir + elsif File.writable?(Gem.dir) + Gem.dir + else + Gem.user_dir + end + installer = Gem::DependencyInstaller.new(:install_dir => destination) + installer.install(name) + rescue Errno::EACCES + raise CommandError, + "Insufficient permissions to install #{ Pry::Helpers::Text.green(name) }." + rescue Gem::GemNotFoundException + raise CommandError, + "Gem #{ Pry::Helpers::Text.green(name) } not found. Aborting installation." + else + Gem.refresh + end + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/terminal.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/terminal.rb new file mode 100644 index 0000000..67f2979 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/terminal.rb @@ -0,0 +1,79 @@ +class Pry::Terminal + class << self + # Return a pair of [rows, columns] which gives the size of the window. + # + # If the window size cannot be determined, return nil. + def screen_size + rows, cols = actual_screen_size + if rows && cols + [rows.to_i, cols.to_i] + else + nil + end + end + + # Return a screen size or a default if that fails. + def size! default = [27, 80] + screen_size || default + end + + # Return a screen width or the default if that fails. + def width! + size![1] + end + + # Return a screen height or the default if that fails. + def height! + size![0] + end + + def actual_screen_size + # The best way, if possible (requires non-jruby ≥1.9 or io-console gem) + screen_size_according_to_io_console or + # Fall back to the old standby, though it might be stale: + screen_size_according_to_env or + # Fall further back, though this one is also out of date without something + # calling Readline.set_screen_size + screen_size_according_to_readline or + # Windows users can otherwise run ansicon and get a decent answer: + screen_size_according_to_ansicon_env + end + + def screen_size_according_to_io_console + return if Pry::Helpers::BaseHelpers.jruby? + require 'io/console' + $stdout.winsize if $stdout.tty? and $stdout.respond_to?(:winsize) + rescue LoadError + # They probably don't have the io/console stdlib or the io-console gem. + # We'll keep trying. + end + + def screen_size_according_to_env + size = [ENV['LINES'] || ENV['ROWS'], ENV['COLUMNS']] + size if nonzero_column?(size) + end + + def screen_size_according_to_readline + if defined?(Readline) && Readline.respond_to?(:get_screen_size) + size = Readline.get_screen_size + size if nonzero_column?(size) + end + rescue Java::JavaLang::NullPointerException + # This rescue won't happen on jrubies later than: + # https://github.com/jruby/jruby/pull/436 + nil + end + + def screen_size_according_to_ansicon_env + return unless ENV['ANSICON'] =~ /\((.*)x(.*)\)/ + size = [$2, $1] + size if nonzero_column?(size) + end + + private + + def nonzero_column?(size) + size[1].to_i > 0 + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/test/helper.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/test/helper.rb new file mode 100644 index 0000000..8ddf144 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/test/helper.rb @@ -0,0 +1,170 @@ +require 'pry' + +# in case the tests call reset_defaults, ensure we reset them to +# amended (test friendly) values +class << Pry + alias_method :orig_reset_defaults, :reset_defaults + def reset_defaults + orig_reset_defaults + + Pry.config.color = false + Pry.config.pager = false + Pry.config.should_load_rc = false + Pry.config.should_load_local_rc= false + Pry.config.should_load_plugins = false + Pry.config.history.should_load = false + Pry.config.history.should_save = false + Pry.config.correct_indent = false + Pry.config.hooks = Pry::Hooks.new + Pry.config.collision_warning = false + end +end +Pry.reset_defaults + +# A global space for storing temporary state during tests. + +module PryTestHelpers + + module_function + + # inject a variable into a binding + def inject_var(name, value, b) + Pry.current[:pry_local] = value + b.eval("#{name} = ::Pry.current[:pry_local]") + ensure + Pry.current[:pry_local] = nil + end + + def constant_scope(*names) + names.each do |name| + Object.remove_const name if Object.const_defined?(name) + end + + yield + ensure + names.each do |name| + Object.remove_const name if Object.const_defined?(name) + end + end + + # Open a temp file and yield it to the block, closing it after + # @return [String] The path of the temp file + def temp_file(ext='.rb') + file = Tempfile.new(['pry', ext]) + yield file + ensure + file.close(true) if file + File.unlink("#{file.path}c") if File.exists?("#{file.path}c") # rbx + end + + def unindent(*args) + Pry::Helpers::CommandHelpers.unindent(*args) + end + + def mock_command(cmd, args=[], opts={}) + output = StringIO.new + pry = Pry.new(output: output) + ret = cmd.new(opts.merge(pry_instance: pry, :output => output)).call_safely(*args) + Struct.new(:output, :return).new(output.string, ret) + end + + def mock_exception(*mock_backtrace) + StandardError.new.tap do |e| + e.define_singleton_method(:backtrace) { mock_backtrace } + end + end +end + +def pry_tester(*args, &block) + if args.length == 0 || args[0].is_a?(Hash) + args.unshift(Pry.toplevel_binding) + end + + PryTester.new(*args).tap do |t| + (class << t; self; end).class_eval(&block) if block + end +end + +def pry_eval(*eval_strs) + if eval_strs.first.is_a? String + binding = Pry.toplevel_binding + else + binding = Pry.binding_for(eval_strs.shift) + end + + pry_tester(binding).eval(*eval_strs) +end + +class PryTester + extend Forwardable + + attr_reader :pry, :out + + def_delegators :@pry, :eval_string, :eval_string= + + def initialize(target = TOPLEVEL_BINDING, options = {}) + @pry = Pry.new(options.merge(:target => target)) + @history = options[:history] + + @pry.inject_sticky_locals! + reset_output + end + + def eval(*strs) + reset_output + result = nil + + strs.flatten.each do |str| + str = "#{str.strip}\n" + @history.push str if @history + + if @pry.process_command(str) + result = last_command_result_or_output + else + result = @pry.evaluate_ruby(str) + end + end + + result + end + + def push(*lines) + Array(lines).flatten.each do |line| + @pry.eval(line) + end + end + + def push_binding(context) + @pry.push_binding context + end + + def last_output + @out.string if @out + end + + def process_command(command_str) + @pry.process_command(command_str) or raise "Not a valid command" + last_command_result_or_output + end + + def last_command_result + result = Pry.current[:pry_cmd_result] + result.retval if result + end + + protected + + def last_command_result_or_output + result = last_command_result + if result != Pry::Command::VOID_VALUE + result + else + last_output + end + end + + def reset_output + @out = StringIO.new + @pry.output = @out + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/version.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/version.rb new file mode 100644 index 0000000..9930e64 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/version.rb @@ -0,0 +1,3 @@ +class Pry + VERSION = "0.10.0" +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/wrapped_module.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/wrapped_module.rb new file mode 100644 index 0000000..6022c5d --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/wrapped_module.rb @@ -0,0 +1,373 @@ +require 'pry/module_candidate' + +class Pry + class << self + # If the given object is a `Pry::WrappedModule`, return it unaltered. If it's + # anything else, return it wrapped in a `Pry::WrappedModule` instance. + def WrappedModule(obj) + if obj.is_a? Pry::WrappedModule + obj + else + Pry::WrappedModule.new(obj) + end + end + end + + class WrappedModule + include Helpers::BaseHelpers + include CodeObject::Helpers + + attr_reader :wrapped + + # Convert a string to a module. + # + # @param [String] mod_name + # @param [Binding] target The binding where the lookup takes place. + # @return [Module, nil] The module or `nil` (if conversion failed). + # @example + # Pry::WrappedModule.from_str("Pry::Code") + def self.from_str(mod_name, target=TOPLEVEL_BINDING) + if safe_to_evaluate?(mod_name, target) + Pry::WrappedModule.new(target.eval(mod_name)) + else + nil + end + rescue RescuableException + nil + end + + class << self + private + + # We use this method to decide whether code is safe to eval. Method's are + # generally not, but everything else is. + # TODO: is just checking != "method" enough?? + # TODO: see duplication of this method in Pry::CodeObject + # @param [String] str The string to lookup. + # @param [Binding] target Where the lookup takes place. + # @return [Boolean] + def safe_to_evaluate?(str, target) + return true if str.strip == "self" + kind = target.eval("defined?(#{str})") + kind =~ /variable|constant/ + end + end + + # @raise [ArgumentError] if the argument is not a `Module` + # @param [Module] mod + def initialize(mod) + raise ArgumentError, "Tried to initialize a WrappedModule with a non-module #{mod.inspect}" unless ::Module === mod + @wrapped = mod + @memoized_candidates = [] + @host_file_lines = nil + @source = nil + @source_location = nil + @doc = nil + end + + # Returns an array of the names of the constants accessible in the wrapped + # module. This avoids the problem of accidentally calling the singleton + # method `Module.constants`. + # @param [Boolean] inherit Include the names of constants from included + # modules? + def constants(inherit = true) + Module.instance_method(:constants).bind(@wrapped).call(inherit) + end + + # The prefix that would appear before methods defined on this class. + # + # i.e. the "String." or "String#" in String.new and String#initialize. + # + # @return String + def method_prefix + if singleton_class? + if Module === singleton_instance + "#{WrappedModule.new(singleton_instance).nonblank_name}." + else + "self." + end + else + "#{nonblank_name}#" + end + end + + # The name of the Module if it has one, otherwise #. + # + # @return [String] + def nonblank_name + if name.to_s == "" + wrapped.inspect + else + name + end + end + + # Is this a singleton class? + # @return [Boolean] + def singleton_class? + if Pry::Method.safe_send(wrapped, :respond_to?, :singleton_class?) + Pry::Method.safe_send(wrapped, :singleton_class?) + else + wrapped != Pry::Method.safe_send(wrapped, :ancestors).first + end + end + + # Is this strictly a module? (does not match classes) + # @return [Boolean] + def module? + wrapped.instance_of?(Module) + end + + # Is this strictly a class? + # @return [Boolean] + def class? + wrapped.instance_of?(Class) + end + + # Get the instance associated with this singleton class. + # + # @raise ArgumentError: tried to get instance of non singleton class + # + # @return [Object] + def singleton_instance + raise ArgumentError, "tried to get instance of non singleton class" unless singleton_class? + + if Helpers::BaseHelpers.jruby? + wrapped.to_java.attached + else + @singleton_instance ||= ObjectSpace.each_object(wrapped).detect{ |x| (class << x; self; end) == wrapped } + end + end + + # Forward method invocations to the wrapped module + def method_missing(method_name, *args, &block) + wrapped.send(method_name, *args, &block) + end + + def respond_to?(method_name) + super || wrapped.respond_to?(method_name) + end + + # Retrieve the source location of a module. Return value is in same + # format as Method#source_location. If the source location + # cannot be found this method returns `nil`. + # + # @param [Module] mod The module (or class). + # @return [Array, nil] The source location of the + # module (or class), or `nil` if no source location found. + def source_location + @source_location ||= primary_candidate.source_location + rescue Pry::RescuableException + nil + end + + # @return [String, nil] The associated file for the module (i.e + # the primary candidate: highest ranked monkeypatch). + def file + Array(source_location).first + end + alias_method :source_file, :file + + # @return [Fixnum, nil] The associated line for the module (i.e + # the primary candidate: highest ranked monkeypatch). + def line + Array(source_location).last + end + alias_method :source_line, :line + + # Returns documentation for the module. + # This documentation is for the primary candidate, if + # you would like documentation for other candidates use + # `WrappedModule#candidate` to select the candidate you're + # interested in. + # @raise [Pry::CommandError] If documentation cannot be found. + # @return [String] The documentation for the module. + def doc + @doc ||= primary_candidate.doc + end + + # Returns the source for the module. + # This source is for the primary candidate, if + # you would like source for other candidates use + # `WrappedModule#candidate` to select the candidate you're + # interested in. + # @raise [Pry::CommandError] If source cannot be found. + # @return [String] The source for the module. + def source + @source ||= primary_candidate.source + end + + # @return [String] Return the associated file for the + # module from YARD, if one exists. + def yard_file + YARD::Registry.at(name).file if yard_docs? + end + + # @return [Fixnum] Return the associated line for the + # module from YARD, if one exists. + def yard_line + YARD::Registry.at(name).line if yard_docs? + end + + # @return [String] Return the YARD docs for this module. + def yard_doc + YARD::Registry.at(name).docstring.to_s if yard_docs? + end + + # Return a candidate for this module of specified rank. A `rank` + # of 0 is equivalent to the 'primary candidate', which is the + # module definition with the highest number of methods. A `rank` + # of 1 is the module definition with the second highest number of + # methods, and so on. Module candidates are necessary as modules + # can be reopened multiple times and in multiple places in Ruby, + # the candidate API gives you access to the module definition + # representing each of those reopenings. + # @raise [Pry::CommandError] If the `rank` is out of range. That + # is greater than `number_of_candidates - 1`. + # @param [Fixnum] rank + # @return [Pry::WrappedModule::Candidate] + def candidate(rank) + @memoized_candidates[rank] ||= Candidate.new(self, rank) + end + + # @return [Fixnum] The number of candidate definitions for the + # current module. + def number_of_candidates + method_candidates.count + end + + # @note On JRuby 1.9 and higher, in certain conditions, this method chucks + # away its ability to be quick (when there are lots of monkey patches, + # like in Rails). However, it should be efficient enough on other rubies. + # @see https://github.com/jruby/jruby/issues/525 + # @return [Enumerator, Array] on JRuby 1.9 and higher returns Array, on + # other rubies returns Enumerator + def candidates + enum = Enumerator.new do |y| + (0...number_of_candidates).each do |num| + y.yield candidate(num) + end + end + Pry::Helpers::BaseHelpers.jruby_19? ? enum.to_a : enum + end + + # @return [Boolean] Whether YARD docs are available for this module. + def yard_docs? + !!(defined?(YARD) && YARD::Registry.at(name)) + end + + # @param [Fixnum] times How far to travel up the ancestor chain. + # @return [Pry::WrappedModule, nil] The wrapped module that is the + # superclass. + # When `self` is a `Module` then return the + # nth ancestor, otherwise (in the case of classes) return the + # nth ancestor that is a class. + def super(times=1) + return self if times.zero? + + if wrapped.is_a?(Class) + sup = ancestors.select { |v| v.is_a?(Class) }[times] + else + sup = ancestors[times] + end + + Pry::WrappedModule(sup) if sup + end + + private + + # @return [Pry::WrappedModule::Candidate] The candidate with the + # highest rank, that is the 'monkey patch' of this module with the + # highest number of methods, which contains a source code line that + # defines the module. It is considered the 'canonical' definition + # for the module. In the absense of a suitable candidate, the + # candidate of rank 0 will be returned, or a CommandError raised if + # there are no candidates at all. + def primary_candidate + @primary_candidate ||= candidates.find { |c| c.file } || + # This will raise an exception if there is no candidate at all. + candidate(0) + end + + # @return [Array>] The array of `Pry::Method` objects, + # there are two associated with each candidate. The first is the 'base + # method' for a candidate and it serves as the start point for + # the search in uncovering the module definition. The second is + # the last method defined for that candidate and it is used to + # speed up source code extraction. + def method_candidates + @method_candidates ||= all_source_locations_by_popularity.map do |group| + methods_sorted_by_source_line = group.last.sort_by(&:source_line) + [methods_sorted_by_source_line.first, methods_sorted_by_source_line.last] + end + end + + # A helper method. + def all_source_locations_by_popularity + return @all_source_locations_by_popularity if @all_source_locations_by_popularity + + ims = all_relevant_methods_for(wrapped) + @all_source_locations_by_popularity = ims.group_by { |v| Array(v.source_location).first }. + sort_by do |path, methods| + expanded = File.expand_path(path) + load_order = $LOADED_FEATURES.index{ |file| expanded.end_with?(file) } + + [-methods.size, load_order || (1.0 / 0.0)] + end + end + + # We only want methods that have a non-nil `source_location`. We also + # skip some spooky internal methods. + # (i.e we skip `__class_init__` because it's an odd rbx specific thing that causes tests to fail.) + # @return [Array] + def all_relevant_methods_for(mod) + methods = all_methods_for(mod).select(&:source_location). + reject{ |x| x.name == '__class_init__' || method_defined_by_forwardable_module?(x) } + + return methods unless methods.empty? + + safe_send(mod, :constants).map do |const_name| + if const = nested_module?(mod, const_name) + all_relevant_methods_for(const) + else + [] + end + end.flatten + end + + # Return all methods (instance methods and class methods) for a + # given module. + # @return [Array] + def all_methods_for(mod) + Pry::Method.all_from_obj(mod, false) + Pry::Method.all_from_class(mod, false) + end + + def nested_module?(parent, name) + return if safe_send(parent, :autoload?, name) + child = safe_send(parent, :const_get, name) + return unless Module === child + return unless safe_send(child, :name) == "#{safe_send(parent, :name)}::#{name}" + child + end + + # Detect methods that are defined with `def_delegator` from the Forwardable + # module. We want to reject these methods as they screw up module + # extraction since the `source_location` for such methods points at forwardable.rb + # TODO: make this more robust as valid user-defined files called + # forwardable.rb are also skipped. + def method_defined_by_forwardable_module?(method) + method.source_location.first =~ /forwardable\.rb/ + end + + # memoized lines for file + def lines_for_file(file) + @lines_for_file ||= {} + + if file == Pry.eval_path + @lines_for_file[file] ||= Pry.line_buffer.drop(1) + else + @lines_for_file[file] ||= File.readlines(file) + end + end + end +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/.gitignore b/vendor/bundle/gems/pry-byebug-1.3.3/.gitignore new file mode 100644 index 0000000..9033d2d --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/.gitignore @@ -0,0 +1,18 @@ +tmp +pkg +doc + +.bundle +.config +.yardoc +.gdb_history +.rvmrc +.ruby-gemset +.ruby-version + +Gemfile.lock +InstalledFiles +_yardoc +coverage +lib/bundler/man +rdoc diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/.travis.yml b/vendor/bundle/gems/pry-byebug-1.3.3/.travis.yml new file mode 100644 index 0000000..2e83117 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/.travis.yml @@ -0,0 +1,7 @@ +rvm: +- 2.0.0 +- 2.1 +- ruby-head +matrix: + allow_failures: + - rvm: ruby-head diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/CHANGELOG.md b/vendor/bundle/gems/pry-byebug-1.3.3/CHANGELOG.md new file mode 100644 index 0000000..404b864 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/CHANGELOG.md @@ -0,0 +1,83 @@ +## 1.3.3 (2014-25-06) + +* Relaxes pry dependency to support pry 0.10 series and further minor version +level releases. + + +## 1.3.2 (2014-24-02) + +* Bumps byebug dependency to get rid of bug in byebug. + + +## 1.3.1 (2014-08-02) + +* Fix #22 (thanks @andreychernih) + + +## 1.3.0 (2014-05-02) + +* Add breakpoints on method names (thanks @andreychernih & @palkan) +* Fix "undefined method `interface`" error (huge thanks to @andreychernih) + + +## 1.2.1 (2013-30-12) + +* Fix for "uncaught throw :breakout_nav" (thanks @lukebergen) + + +## 1.2.0 (2013-24-09) + +* Compatibility with byebug's 2.x series + + +## 1.1.2 (2013-11-07) + +* Allow pry-byebug to use backwards compatible versions of byebug + + +## 1.1.1 (2013-02-07) + +* Adds some initial tests to the test suite +* Fixes bug when doing "step n" or "next n" where n > 1 right after binding.pry + + +## 1.1.0 (2013-06-06) + +* Adds a test suite (thanks @teeparham!) +* Uses byebug ~> 1.4.0 +* Uses s, n, f and c aliases by default (thanks @jgakos!) + + +## 1.0.0, 1.0.1 (2013-05-07) + +* Forked from [pry-debugger](https://github.com/nixme/pry-debugger) to support + byebug +* Dropped pry-remote support + + +## 0.2.2 (2013-03-07) + +* Relaxed [byebug][byebug] dependency. + + +## 0.2.1 (2012-12-26) + +* Support breakpoints on methods defined in the pry console. (@banister) +* Fix support for specifying breakpoints by *file:line_number*. (@nviennot) +* Validate breakpoint conditionals are real Ruby expressions. +* Support for debugger ~> 1.2.0. (@jshou) +* Safer `alias_method_chain`-style patching of `Pry.start` and + `PryRemote::Server#teardown`. (@benizi) + + +## 0.2.0 (2012-06-11) + +* Breakpoints +* **finish** command +* Internal cleanup and bug fixes + + +## 0.1.0 (2012-06-07) + +* First release. **step**, **next**, and **continue** commands. + [pry-remote 0.1.4][pry-remote] support. diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/Gemfile b/vendor/bundle/gems/pry-byebug-1.3.3/Gemfile new file mode 100644 index 0000000..1fa34e1 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/Gemfile @@ -0,0 +1,9 @@ +source 'https://rubygems.org' + +gemspec + +gem 'rake', '~> 10.2' + +group :development, :test do + gem 'mocha', '~> 1.0' +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/LICENSE b/vendor/bundle/gems/pry-byebug-1.3.3/LICENSE new file mode 100644 index 0000000..bc6dfb7 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/LICENSE @@ -0,0 +1,20 @@ +MIT/Expat License + +Copyright (c) David Rodríguez + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/README.md b/vendor/bundle/gems/pry-byebug-1.3.3/README.md new file mode 100644 index 0000000..3bfaab3 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/README.md @@ -0,0 +1,115 @@ +pry-byebug [![Gem Version][1]][2] [![Build Status][3]][4] +============ + +_Fast execution control in Pry_ + +Adds **step**, **next**, **finish** and **continue** commands and +**breakpoints** to [Pry][pry] using [byebug][byebug]. + +To use, invoke pry normally. No need to start your script or app differently. + +```ruby +def some_method + binding.pry # Execution will stop here. + puts 'Hello World' # Run 'step' or 'next' in the console to move here. +end +``` + +For a complete debugging environment, add +[pry-stack_explorer][pry-stack_explorer] for call-stack frame navigation. + + +## Installation + +Drop + +```ruby +gem 'pry-byebug' +``` + +in your Gemfile and run + + bundle install + +_Make sure you include the gem globally or inside the `:test` group if you plan +to use it to debug your tests!_ + + +## Execution Commands + +**step:** Step execution into the next line or method. Takes an optional numeric +argument to step multiple times. Aliased to `s` + +**next:** Step over to the next line within the same frame. Also takes an +optional numeric argument to step multiple lines. Aliased to `n` + +**finish:** Execute until current stack frame returns. Aliased to `f` + +**continue:** Continue program execution and end the Pry session. Aliased to `c` + + +## Breakpoints + +You can set and adjust breakpoints directly from a Pry session using the +following commands: + +**break:** Set a new breakpoint from a line number in the current file, a file +and line number, or a method. Pass an optional expression to create a +conditional breakpoint. Edit existing breakpoints via various flags. + +Examples: + +``` +break SomeClass#run Break at the start of `SomeClass#run`. +break Foo#bar if baz? Break at `Foo#bar` only if `baz?`. +break app/models/user.rb:15 Break at line 15 in user.rb. +break 14 Break at line 14 in the current file. + +break --condition 4 x > 2 Change condition on breakpoint #4 to 'x > 2'. +break --condition 3 Remove the condition on breakpoint #3. + +break --delete 5 Delete breakpoint #5. +break --disable-all Disable all breakpoints. + +break List all breakpoints. (Same as `breakpoints`) +break --show 2 Show details about breakpoint #2. +``` + +Type `break --help` from a Pry session to see all available options. + + +**breakpoints**: List all defined breakpoints. Pass `-v` or `--verbose` to see +the source code around each breakpoint. + + +## Caveats + +Only supports MRI 2.0.0 or newer. For MRI 1.9.3 or older, use +[pry-debugger][pry-debugger] + + +## Contributors + +* Tee Parham (@teeparham) +* Gopal Patel (@nixme) +* John Mair (@banister) +* Nicolas Viennot (@nviennot) +* Benjamin R. Haskell (@benizi) +* Joshua Hou (@jshou) +* ...and others who helped with [pry-nav][pry-nav] + +Patches and bug reports are welcome. Just send a [pull request][pullrequests] or +file an [issue][issues]. [Project changelog][changelog]. + +[pry]: http://pry.github.com +[byebug]: https://github.com/deivid-rodriguez/byebug +[pry-debugger]: https://github.com/nixme/pry-debugger +[pry-stack_explorer]: https://github.com/pry/pry-stack_explorer +[pullrequests]: https://github.com/deivid-rodriguez/pry-byebug/pulls +[issues]: https://github.com/deivid-rodriguez/pry-byebug/issues +[changelog]: https://github.com/deivid-rodriguez/pry-byebug/blob/master/CHANGELOG.md +[pry-nav]: https://github.com/nixme/pry-nav +[1]: https://badge.fury.io/rb/pry-byebug.png +[2]: http://badge.fury.io/rb/pry-byebug +[3]: https://secure.travis-ci.org/deivid-rodriguez/pry-byebug.png +[4]: http://travis-ci.org/deivid-rodriguez/pry-byebug diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/Rakefile b/vendor/bundle/gems/pry-byebug-1.3.3/Rakefile new file mode 100644 index 0000000..cdc3988 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/Rakefile @@ -0,0 +1,10 @@ +require 'bundler/gem_tasks' +require 'rake/testtask' + +desc 'Run tests' +Rake::TestTask.new(:test) do |t| + t.libs << 'test' + t.pattern = 'test/**/*_test.rb' +end + +task default: :test diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug.rb new file mode 100644 index 0000000..b405b2a --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug.rb @@ -0,0 +1,3 @@ +require 'pry-byebug/base' +require 'pry-byebug/pry_ext' +require 'pry-byebug/commands' diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/base.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/base.rb new file mode 100644 index 0000000..ca37298 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/base.rb @@ -0,0 +1,13 @@ +module PryByebug + extend self + + # Checks that a binding is in a local file context. Extracted from + # https://github.com/pry/pry/blob/master/lib/pry/default_commands/context.rb + def check_file_context(target) + file = target.eval('__FILE__') + file == Pry.eval_path || (file !~ /(\(.*\))|<.*>/ && file != '' && file != '-e') + end + + # Reference to currently running pry-remote server. Used by the processor. + attr_accessor :current_remote_server +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/breakpoints.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/breakpoints.rb new file mode 100644 index 0000000..e717055 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/breakpoints.rb @@ -0,0 +1,140 @@ +module PryByebug + + # Wrapper for Byebug.breakpoints that respects our Processor and has better + # failure behavior. Acts as an Enumerable. + # + module Breakpoints + extend Enumerable + extend self + + class FileBreakpoint < SimpleDelegator + def source_code + Pry::Code.from_file(source).around(pos, 3).with_marker(pos) + end + + def to_s + "#{source} @ #{pos}" + end + end + + class MethodBreakpoint < SimpleDelegator + def initialize(byebug_bp, method) + __setobj__ byebug_bp + @method = method + end + + def source_code + Pry::Code.from_method(Pry::Method.from_str(@method)) + end + + def to_s + @method + end + end + + def breakpoints + @breakpoints ||= [] + end + + # Add method breakpoint. + def add_method(method, expression = nil) + validate_expression expression + Pry.processor.debugging = true + owner, name = method.split(/[\.#]/) + byebug_bp = Byebug.add_breakpoint(owner, name.to_sym, expression) + bp = MethodBreakpoint.new byebug_bp, method + breakpoints << bp + bp + end + + # Add file breakpoint. + def add_file(file, line, expression = nil) + real_file = (file != Pry.eval_path) + raise ArgumentError, 'Invalid file!' if real_file && !File.exist?(file) + validate_expression expression + + Pry.processor.debugging = true + + path = (real_file ? File.expand_path(file) : file) + bp = FileBreakpoint.new Byebug.add_breakpoint(path, line, expression) + breakpoints << bp + bp + end + + # Change the conditional expression for a breakpoint. + def change(id, expression = nil) + validate_expression expression + + breakpoint = find_by_id(id) + breakpoint.expr = expression + breakpoint + end + + # Delete an existing breakpoint with the given ID. + def delete(id) + deleted = Byebug.started? && + Byebug.remove_breakpoint(id) && + breakpoints.delete(find_by_id(id)) + raise ArgumentError, "No breakpoint ##{id}" if not deleted + Pry.processor.debugging = false if to_a.empty? + end + + # Delete all breakpoints. + def clear + @breakpoints = [] + Byebug.breakpoints.clear if Byebug.started? + Pry.processor.debugging = false + end + + # Enable a disabled breakpoint with the given ID. + def enable(id) + change_status id, true + end + + # Disable a breakpoint with the given ID. + def disable(id) + change_status id, false + end + + # Disable all breakpoints. + def disable_all + each do |breakpoint| + breakpoint.enabled = false + end + end + + def to_a + breakpoints + end + + def size + to_a.size + end + + def each(&block) + to_a.each(&block) + end + + def find_by_id(id) + breakpoint = find { |b| b.id == id } + raise ArgumentError, "No breakpoint ##{id}!" unless breakpoint + breakpoint + end + + + private + + def change_status(id, enabled = true) + breakpoint = find_by_id(id) + breakpoint.enabled = enabled + breakpoint + end + + def validate_expression(expression) + if expression && # `nil` implies no expression given, so pass + (expression.empty? || !Pry::Code.complete_expression?(expression)) + raise "Invalid breakpoint conditional: #{expression}" + end + end + end +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/cli.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/cli.rb new file mode 100644 index 0000000..d153748 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/cli.rb @@ -0,0 +1 @@ +require 'pry-byebug' \ No newline at end of file diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/commands.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/commands.rb new file mode 100644 index 0000000..9274377 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/commands.rb @@ -0,0 +1,260 @@ +require 'pry' +require 'pry-byebug/breakpoints' + +module PryByebug + Commands = Pry::CommandSet.new do + create_command 'step' do + description 'Step execution into the next line or method.' + + banner <<-BANNER + Usage: step [TIMES] + Aliases: s + + Step execution forward. By default, moves a single step. + + Examples: + + step Move a single step forward. + step 5 Execute the next 5 steps. + BANNER + + def process + check_file_context + breakout_navigation :step, args.first + end + end + alias_command 's', 'step' + + create_command 'next' do + description 'Execute the next line within the current stack frame.' + + banner <<-BANNER + Usage: next [LINES] + Aliases: n + + Step over within the same frame. By default, moves forward a single + line. + + Examples: + + next Move a single line forward. + next 4 Execute the next 4 lines. + BANNER + + def process + check_file_context + breakout_navigation :next, args.first + end + end + alias_command 'n', 'next' + + create_command 'finish' do + description 'Execute until current stack frame returns.' + + banner <<-BANNER + Usage: finish + Aliases: f + BANNER + + def process + check_file_context + breakout_navigation :finish + end + end + alias_command 'f', 'finish' + + create_command 'continue' do + description 'Continue program execution and end the Pry session.' + + banner <<-BANNER + Usage: continue + Aliases: c + BANNER + + def process + check_file_context + run 'exit-all' + end + end + alias_command 'c', 'continue' + + create_command 'break' do + description 'Set or edit a breakpoint.' + + banner <<-BANNER + Usage: break [if CONDITION] + break --condition N [CONDITION] + break [--show | --delete | --enable | --disable] N + break [--delete-all | --disable-all] + Aliases: breakpoint + + Set a breakpoint. Accepts a line number in the current file, a file and + line number, or a method, and an optional condition. + + Pass appropriate flags to manipulate existing breakpoints. + + Examples: + + break SomeClass#run Break at the start of `SomeClass#run`. + break Foo#bar if baz? Break at `Foo#bar` only if `baz?`. + break app/models/user.rb:15 Break at line 15 in user.rb. + break 14 Break at line 14 in the current file. + + break --condition 4 x > 2 Add/change condition on breakpoint #4. + break --condition 3 Remove the condition on breakpoint #3. + + break --delete 5 Delete breakpoint #5. + break --disable-all Disable all breakpoints. + + break List all breakpoints. (Same as `breakpoints`) + break --show 2 Show details about breakpoint #2. + BANNER + + def options(opt) + opt.on :c, :condition, 'Change the condition of a breakpoint.', :argument => true, :as => Integer + opt.on :s, :show, 'Show breakpoint details and source.', :argument => true, :as => Integer + opt.on :D, :delete, 'Delete a breakpoint.', :argument => true, :as => Integer + opt.on :d, :disable, 'Disable a breakpoint.', :argument => true, :as => Integer + opt.on :e, :enable, 'Enable a disabled breakpoint.', :argument => true, :as => Integer + opt.on :'disable-all', 'Disable all breakpoints.' + opt.on :'delete-all', 'Delete all breakpoints.' + method_options(opt) + end + + def process + Pry.processor.pry = _pry_ + + { :delete => :delete, + :disable => :disable, + :enable => :enable, + :'disable-all' => :disable_all, + :'delete-all' => :clear + }.each do |action, method| + if opts.present?(action) + Breakpoints.__send__ method, *(method == action ? [opts[action]] : []) + return run 'breakpoints' + end + end + + if opts.present?(:condition) + Breakpoints.change(opts[:condition], args.empty? ? nil : args.join(' ')) + run 'breakpoints' + elsif opts.present?(:show) + print_full_breakpoint Breakpoints.find_by_id(opts[:show]) + elsif args.empty? + run 'breakpoints' + else + new_breakpoint + end + end + + def new_breakpoint + place = args.shift + condition = args.join(' ') if 'if' == args.shift + + bp = + case place + when /^(\d+)$/ # Line number only + line = $1 + unless PryByebug.check_file_context(target) + raise ArgumentError, 'Line number declaration valid only in a file context.' + end + Breakpoints.add_file(target.eval('__FILE__'), line.to_i, condition) + when /^(.+):(\d+)$/ # File and line number + Breakpoints.add_file($1, $2.to_i, condition) + when /^(.*)[.#].+$/ # Method or class name + if $1.strip.empty? + unless PryByebug.check_file_context(target) + raise ArgumentError, 'Method name declaration valid only in a file context.' + end + place = target.eval('self.class.to_s') + place + end + Breakpoints.add_method(place,condition) + else + raise ArgumentError, 'Cannot identify arguments as breakpoint' + end + + print_full_breakpoint bp + end + end + alias_command 'breakpoint', 'break' + + + create_command 'breakpoints' do + description 'List defined breakpoints.' + + banner <<-BANNER + Usage: breakpoints [OPTIONS] + Aliases: breaks + + List registered breakpoints and their current status. + BANNER + + def options(opt) + opt.on :v, :verbose, 'Print source around each breakpoint.' + end + + def process + if Breakpoints.count > 0 + if opts.verbose? # Long-form with source output + Breakpoints.each { |b| print_full_breakpoint(b) } + else # Simple table output + max_width = [Math.log10(Breakpoints.count).ceil, 1].max + header = "#{' ' * (max_width - 1)}# Enabled At " + + output.puts + output.puts text.bold(header) + output.puts text.bold('-' * header.size) + Breakpoints.each do |breakpoint| + output.printf "%#{max_width}d ", breakpoint.id + output.print breakpoint.enabled? ? 'Yes ' : 'No ' + output.print breakpoint.to_s + output.print " (if #{breakpoint.expr})" if breakpoint.expr + output.puts + end + output.puts + end + else + output.puts text.bold('No breakpoints defined.') + end + end + end + alias_command 'breaks', 'breakpoints' + + helpers do + def breakout_navigation(action, times = nil) + _pry_.binding_stack.clear # Clear the binding stack. + throw :breakout_nav, { # Break out of the REPL loop and signal tracer + :action => action, + :times => times, + :pry => _pry_ + } + end + + # Ensures that a command is executed in a local file context. + def check_file_context + unless PryByebug.check_file_context(target) + raise Pry::CommandError, 'Cannot find local context. Did you use `binding.pry`?' + end + end + + # Print out full information about a breakpoint including surrounding code + # at that point. + def print_full_breakpoint(breakpoint) + line = breakpoint.pos + output.print text.bold("Breakpoint #{breakpoint.id}: ") + output.print "#{breakpoint.to_s} " + output.print breakpoint.enabled? ? '(Enabled)' : '(Disabled)' + output.puts ' :' + if (expr = breakpoint.expr) + output.puts "#{text.bold('Condition:')} #{expr}" + end + output.puts + output.puts breakpoint.source_code.with_line_numbers.to_s + output.puts + end + end + end +end + +Pry.commands.import PryByebug::Commands diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/processor.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/processor.rb new file mode 100644 index 0000000..31524dd --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/processor.rb @@ -0,0 +1,127 @@ +require 'pry' +require 'byebug' + +module PryByebug + class Processor < Byebug::Processor + attr_accessor :pry + + def initialize(interface = Byebug::LocalInterface.new) + super(interface) + + Byebug.handler = self + @always_enabled = true + @delayed = Hash.new(0) + end + + # Wrap a Pry REPL to catch navigational commands and act on them. + def run(initial = true, &block) + return_value = nil + + command = catch(:breakout_nav) do # Throws from PryByebug::Commands + return_value = yield + {} # Nothing thrown == no navigational command + end + + times = (command[:times] || 1).to_i # Command argument + times = 1 if times <= 0 + + if [:step, :next, :finish].include? command[:action] + @pry = command[:pry] # Pry instance to resume after stepping + Byebug.start unless Byebug.started? + + if initial + # Movement when on the initial binding.pry line will have a frame + # inside Byebug. If we step normally, it'll stop inside this + # Processor. So jump out and stop at the above frame, then step/next + # from our callback. + @delayed[command[:action]] = times + Byebug.current_context.step_out(2) + elsif :next == command[:action] + Byebug.current_context.step_over(times, 0) + + elsif :step == command[:action] + Byebug.current_context.step_into(times) + + elsif :finish == command[:action] + Byebug.current_context.step_out(0) + end + else + stop + end + + return_value + end + + # Adjust debugging. When set to false, the Processor will manage enabling + # and disabling the debugger itself. When set to true, byebug is always + # enabled. + def debugging=(enabled) + if enabled + @always_enabled = true + Byebug.start unless Byebug.started? + else + @always_enabled = false + # Byebug will get stopped if necessary in `stop` once the repl ends. + end + end + + # --- Callbacks from byebug C extension --- + def at_line(context, file, line) + # If any delayed nexts/steps, do 'em. + if @delayed[:next] > 1 + context.step_over(@delayed[:next] - 1, 0) + + elsif @delayed[:step] > 1 + context.step_into(@delayed[:step] - 1) + + elsif @delayed[:finish] > 1 + context.step_out(@delayed[:finish] - 1) + + # Otherwise, resume the pry session at the stopped line. + else + resume_pry context + end + + @delayed = Hash.new(0) + end + + # Called when a breakpoint is triggered. Note: `at_line`` is called + # immediately after with the context's `stop_reason == :breakpoint`. + def at_breakpoint(context, breakpoint) + @pry.output.print Pry::Helpers::Text.bold("\nBreakpoint #{breakpoint.id}. ") + @pry.output.puts (breakpoint.hit_count == 1 ? + 'First hit.' : + "Hit #{breakpoint.hit_count} times." ) + if (expr = breakpoint.expr) + @pry.output.print Pry::Helpers::Text.bold("Condition: ") + @pry.output.puts expr + end + end + + def at_catchpoint(context, exception) + # TODO + end + + private + + # + # Resume an existing Pry REPL at the paused point. + # + def resume_pry(context) + new_binding = context.frame_binding(0) + Byebug.stop unless @always_enabled + + run(false) do + @pry.repl new_binding + end + end + + # Cleanup when debugging is stopped and execution continues. + def stop + Byebug.stop if !@always_enabled && Byebug.started? + if PryByebug.current_remote_server # Cleanup DRb remote if running + PryByebug.current_remote_server.teardown + end + end + end +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_ext.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_ext.rb new file mode 100644 index 0000000..f017d44 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_ext.rb @@ -0,0 +1,23 @@ +require 'pry' +require 'pry-byebug/processor' + +class << Pry + alias_method :start_without_pry_byebug, :start + attr_reader :processor + + def start_with_pry_byebug(target = TOPLEVEL_BINDING, options = {}) + @processor ||= PryByebug::Processor.new + + if target.is_a?(Binding) && PryByebug.check_file_context(target) + # Wrap the processor around the usual Pry.start to catch navigation + # commands. + @processor.run(true) do + start_without_pry_byebug(target, options) + end + else + # No need for the tracer unless we have a file context to step through + start_without_pry_byebug(target, options) + end + end + alias_method :start, :start_with_pry_byebug +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_remote_ext.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_remote_ext.rb new file mode 100644 index 0000000..9d830ad --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_remote_ext.rb @@ -0,0 +1,41 @@ +require 'pry-remote' + +module PryRemote + class Server + # Override the call to Pry.start to save off current Server, and not + # teardown the server right after Pry.start finishes. + def run + if PryByebug.current_remote_server + raise 'Already running a pry-remote session!' + else + PryByebug.current_remote_server = self + end + + setup + Pry.start @object, { + :input => client.input_proxy, + :output => client.output + } + end + + # Override to reset our saved global current server session. + alias_method :teardown_without_pry_byebug, :teardown + def teardown_with_pry_byebug + return if @torn + + teardown_without_pry_byebug + PryByebug.current_remote_server = nil + @torn = true + end + alias_method :teardown, :teardown_with_pry_byebug + end +end + +# Ensure cleanup when a program finishes without another break. For example, +# 'next' on the last line of a program won't hit PryByebug::Processor#run, +# which normally handles cleanup. +at_exit do + if PryByebug.current_remote_server + PryByebug.current_remote_server.teardown + end +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/version.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/version.rb new file mode 100644 index 0000000..ca37adf --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/version.rb @@ -0,0 +1,3 @@ +module PryByebug + VERSION = '1.3.3' +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/pry-byebug.gemspec b/vendor/bundle/gems/pry-byebug-1.3.3/pry-byebug.gemspec new file mode 100644 index 0000000..5f031fc --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/pry-byebug.gemspec @@ -0,0 +1,23 @@ +require File.dirname(__FILE__) + '/lib/pry-byebug/version' + +Gem::Specification.new do |gem| + gem.name = 'pry-byebug' + gem.version = PryByebug::VERSION + gem.authors = ['David Rodríguez', 'Gopal Patel'] + gem.email = 'deivid.rodriguez@gmail.com' + gem.license = 'MIT' + gem.homepage = 'https://github.com/deivid-rodriguez/pry-byebug' + gem.summary = 'Fast debugging with Pry.' + gem.description = %q{Combine 'pry' with 'byebug'. Adds 'step', 'next', and + 'continue' commands to control execution.} + + gem.files = `git ls-files`.split("\n") + gem.test_files = `git ls-files -- test/*`.split("\n") + gem.require_paths = ['lib'] + + # Dependencies + gem.required_ruby_version = '>= 2.0.0' + + gem.add_runtime_dependency 'pry', '~> 0.10' + gem.add_runtime_dependency 'byebug', '~> 2.7' +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/base_test.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/base_test.rb new file mode 100644 index 0000000..7d838b6 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/base_test.rb @@ -0,0 +1,14 @@ +require 'test_helper' + +class BaseTest < MiniTest::Spec + def test_main_file_context + Pry.stubs eval_path: "
" + assert PryByebug.check_file_context(TOPLEVEL_BINDING) + end + + def test_other_file_context + Pry.stubs eval_path: "something" + refute PryByebug.check_file_context(TOPLEVEL_BINDING) + end +end + diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/breakpoints_test.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/breakpoints_test.rb new file mode 100644 index 0000000..3e61a7c --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/breakpoints_test.rb @@ -0,0 +1,34 @@ +require 'test_helper' + +class BreakpointsTest < MiniTest::Spec + def test_add_file_raises_argument_error + Pry.stubs eval_path: "something" + File.stubs :exist? + assert_raises(ArgumentError) do + PryByebug::Breakpoints.add_file("file", 1) + end + end + + class Tester + def self.class_method; end + def instance_method; end + end + + def test_add_method_adds_instance_method_breakpoint + Pry.stub :processor, PryByebug::Processor.new do + PryByebug::Breakpoints.add_method 'BreakpointsTest::Tester#instance_method' + bp = Byebug.breakpoints.last + assert_equal 'BreakpointsTest::Tester', bp.source + assert_equal 'instance_method', bp.pos + end + end + + def test_add_method_adds_class_method_breakpoint + Pry.stub :processor, PryByebug::Processor.new do + PryByebug::Breakpoints.add_method 'BreakpointsTest::Tester.class_method' + bp = Byebug.breakpoints.last + assert_equal 'BreakpointsTest::Tester', bp.source + assert_equal 'class_method', bp.pos + end + end +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/commands_test.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/commands_test.rb new file mode 100644 index 0000000..5f4109e --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/commands_test.rb @@ -0,0 +1,178 @@ +require 'test_helper' + +class CommandsTest < MiniTest::Spec + let(:step_file) do + (Pathname.new(__FILE__) + "../examples/stepping.rb").cleanpath.to_s + end + + let(:break_first_file) do + (Pathname.new(__FILE__) + "../examples/break1.rb").cleanpath.to_s + end + + let(:break_second_file) do + (Pathname.new(__FILE__) + "../examples/break2.rb").cleanpath.to_s + end + + before do + Pry.color = false + Pry.pager = false + Pry.hooks = Pry::DEFAULT_HOOKS + @output = StringIO.new + end + + describe 'Step Command' do + describe 'single step' do + before do + @input = InputTester.new 'step' + redirect_pry_io(@input, @output) do + load step_file + end + end + + it 'shows current line' do + @output.string.must_match /\=> 3:/ + end + end + + describe 'multiple step' do + before do + @input = InputTester.new 'step 2' + redirect_pry_io(@input, @output) do + load step_file + end + end + + it 'shows current line' do + @output.string.must_match /\=> 4:/ + end + end + end + + describe 'Next Command' do + describe 'single step' do + before do + @input = InputTester.new 'next' + redirect_pry_io(@input, @output) do + load step_file + end + end + + it 'shows current line' do + @output.string.must_match /\=> 3:/ + end + end + + describe 'multiple step' do + before do + @input = InputTester.new 'next 2' + redirect_pry_io(@input, @output) do + load step_file + end + end + + it 'shows current line' do + @output.string.must_match /\=> 20:/ + end + end + end + + describe 'Set Breakpoints' do + before do + @input = InputTester.new 'break --delete-all' + redirect_pry_io(@input, @output) do + load break_first_file + end + @output = StringIO.new + end + + describe 'set by line number' do + before do + @input = InputTester.new 'break 3' + redirect_pry_io(@input, @output) do + load break_first_file + end + end + + it 'shows breakpoint enabled' do + @output.string.must_match /^Breakpoint [\d]+: #{break_first_file} @ 3 \(Enabled\)/ + end + + it 'shows breakpoint hit' do + @output.string =~ /^Breakpoint ([\d]+): #{break_first_file} @ 3 \(Enabled\)/ + @output.string.must_match Regexp.new("^Breakpoint #{$1}\. First hit") + end + + it 'shows breakpoint line' do + @output.string.must_match /\=> 3:/ + end + end + + describe 'set by method_id' do + before do + @input = InputTester.new 'break BreakExample#a' + redirect_pry_io(@input, @output) do + load break_first_file + end + end + + it 'shows breakpoint enabled' do + @output.string.must_match /^Breakpoint [\d]+: BreakExample#a \(Enabled\)/ + end + + it 'shows breakpoint hit' do + @output.string =~ /^Breakpoint ([\d]+): BreakExample#a \(Enabled\)/ + @output.string.must_match Regexp.new("^Breakpoint #{$1}\. First hit") + end + + it 'shows breakpoint line' do + @output.string.must_match /\=> 4:/ + end + + describe 'when its a bang method' do + before do + @input = InputTester.new 'break BreakExample#c!' + redirect_pry_io(@input, @output) do + load break_first_file + end + end + + it 'shows breakpoint enabled' do + @output.string.must_match /^Breakpoint [\d]+: BreakExample#c! \(Enabled\)/ + end + + it 'shows breakpoint hit' do + @output.string =~ /^Breakpoint ([\d]+): BreakExample#c! \(Enabled\)/ + @output.string.must_match Regexp.new("^Breakpoint #{$1}\. First hit") + end + + it 'shows breakpoint line' do + @output.string.must_match /\=> 14:/ + end + end + end + + describe 'set by method_id within context' do + before do + @input = InputTester.new 'break #b' + redirect_pry_io(@input, @output) do + load break_second_file + end + end + + it 'shows breakpoint enabled' do + @output.string.must_match /^Breakpoint [\d]+: BreakExample#b \(Enabled\)/ + end + + it 'shows breakpoint hit' do + @output.string =~ /^Breakpoint ([\d]+): BreakExample#b \(Enabled\)/ + @output.string.must_match Regexp.new("^Breakpoint #{$1}\. First hit") + end + + it 'shows breakpoint line' do + @output.string.must_match /\=> 8:/ + end + end + + end +end + diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break1.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break1.rb new file mode 100644 index 0000000..bce68fe --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break1.rb @@ -0,0 +1,20 @@ +binding.pry + +class BreakExample + def a + z = 2 + b + end + + def b + v2 = 5 if 1 == 2 ; [1,2,3].map { |a| a.to_f } + c! + end + + def c! + z = 4 + 5 + end +end + +BreakExample.new.a diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break2.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break2.rb new file mode 100644 index 0000000..d10c399 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break2.rb @@ -0,0 +1,18 @@ +class BreakExample + def a + binding.pry + z = 2 + b + end + + def b + c + end + + def c + z = 4 + 5 + end +end + +BreakExample.new.a diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/stepping.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/stepping.rb new file mode 100644 index 0000000..a062622 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/stepping.rb @@ -0,0 +1,25 @@ +binding.pry + +class SteppingExample + def a + z = 2 + b + end + + def b + v2 = 5 if 1 == 2 ; [1,2,3].map { |a| a.to_f } + c + end + + def c + z = 4 + 5 + end +end + +ex = SteppingExample.new.a +2.times do + ex += 1 +end + +ex diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/processor_test.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/processor_test.rb new file mode 100644 index 0000000..f943e4d --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/processor_test.rb @@ -0,0 +1,6 @@ +require 'test_helper' + +class ProcessorTest < MiniTest::Spec + +end + diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/pry_ext_test.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/pry_ext_test.rb new file mode 100644 index 0000000..3b5e43c --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/pry_ext_test.rb @@ -0,0 +1,6 @@ +require 'test_helper' + +class PryExtTest < MiniTest::Spec + +end + diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/pry_remote_ext_test.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/pry_remote_ext_test.rb new file mode 100644 index 0000000..67e8c7c --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/pry_remote_ext_test.rb @@ -0,0 +1,6 @@ +require 'test_helper' + +class PryRemoteExtTest < MiniTest::Spec + +end + diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/test_helper.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/test_helper.rb new file mode 100644 index 0000000..99070dc --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/test_helper.rb @@ -0,0 +1,34 @@ +require 'pry/test/helper' +require 'minitest/autorun' +require 'pry-byebug' +require 'mocha/setup' + +# Set I/O streams. Out defaults to an anonymous StringIO. +def redirect_pry_io(new_in, new_out = StringIO.new) + old_in = Pry.input + old_out = Pry.output + + Pry.input = new_in + Pry.output = new_out + begin + yield + ensure + Pry.input = old_in + Pry.output = old_out + end +end + +class InputTester + def initialize(*actions) + @orig_actions = actions.dup + @actions = actions + end + + def readline(*) + @actions.shift + end + + def rewind + @actions = @orig_actions.dup + end +end diff --git a/vendor/bundle/gems/slop-3.6.0/.gitignore b/vendor/bundle/gems/slop-3.6.0/.gitignore new file mode 100644 index 0000000..e20dac6 --- /dev/null +++ b/vendor/bundle/gems/slop-3.6.0/.gitignore @@ -0,0 +1,7 @@ +.rvmrc +.yardoc +doc +*.swp +*.gem +*.rbc +Gemfile.lock diff --git a/vendor/bundle/gems/slop-3.6.0/.travis.yml b/vendor/bundle/gems/slop-3.6.0/.travis.yml new file mode 100644 index 0000000..6fba0ce --- /dev/null +++ b/vendor/bundle/gems/slop-3.6.0/.travis.yml @@ -0,0 +1,9 @@ +rvm: + - 1.9.3 + - 2.1 + - ruby-head + - jruby-19mode +notifications: + email: + on_success: change + on_failure: always diff --git a/vendor/bundle/gems/slop-3.6.0/CHANGES.md b/vendor/bundle/gems/slop-3.6.0/CHANGES.md new file mode 100644 index 0000000..c500beb --- /dev/null +++ b/vendor/bundle/gems/slop-3.6.0/CHANGES.md @@ -0,0 +1,309 @@ +3.6.0 (2014-06-18) +------------------ + +* Add example of rest arguments usage in the readme file #139 +* Default values on options are printed in the help message #134 + +3.5.0 (2014-03-12) +------------------ + +* Add support for `as: Regexp` #132 + +3.4.7 (2013-11-14) +------------------ + +* Ensure trash is cleared on every parse so you can parse multiple + times with the same instance (#130) + +3.4.5 (2013-05-14) +------------------ + +* Allow specifying long options starting with numbers (#110, Peter Zotov) +* Ensure short-options still consume trailing arguments, ie `-abc foo` + should assign `foo` to the option `c` if it expects an argument (#114). + +3.4.4 (2013-03-12) +------------------ + +* Disable the run callback when the help option is used and `-h` + or `--help` is passed. #106 +* Ensure default `--help` option exits by default (#107, Autumn Perrault). + +3.4.3 (2013-01-14) +------------------ + +* Ensure `parse!` removes commands and their options. + +3.4.2 (2013-01-14) +------------------ + +* Expose the Hash commands as public API. +* Deprecated `Slop.optspec`. +* Ensure help output prints to stdout, not stderr. + +3.4.1 (2013-01-13) +------------------ + +* Ensure options replace any existing duplicates +* Command config options now inherit config options from top level Slop. +* Command help output now adds command in usage string. + +3.4.0 (2013-01-12) +------------------ + +* Implement new command system (#95) +* Deprecate Slop::Commands +* Ensure 'no-foo' options are not inverted when parsing '--no-foo' (#86) +* Code refactoring and simplification (Kenichi Kamiya, #84, #85) + +3.3.3 (2012-08-29) +------------------ + +* Ensure autocreate arguments are not created as options (#77) +* Ensure options are not swallowed when using short options with argument + included (#74) + +3.3.2 (2012-06-26) +------------------ + +* Ensure multiple options are not executed unless they exist (#70) + +3.3.1 (2012-05-31) +------------------ + +* Stop multiple switches from trashing arguments (Conrad Irwin, #66) + +3.3.0 (2012-05-30) +------------------ + +* Fix `:as => :count` when using multiple switches. +* Ensure range typecast allows negative range values. +* Ignore nil objects send to #parse instead of choking. + +3.2.0 (2012-05-15) +------------------ + +* Ensure boolean options appear correctly in `to_hash` output. (#59) + +3.1.1 (2012-04-24) +------------------ + +* Ensure separators before any options are still being processed (#62) + +3.1.0 (2012-04-23) +------------------ + +* Allow options to be fetched via underscores instead of dashes + (as a fallback) (Eric Anderson, #51) +* Added `Slop#strict?` method. +* Added strict checks for Integer/Float type casting. (Amon Sha) +* Ensure separators are not replacing existing separators (#61) + +3.0.4 (2012-01-31) +------------------ + +* Ensure `option=argument` syntax does not consume following arguments (#55). + +3.0.3 (2012-01-30) +------------------ + +* Ensure options passed after option terminator do not raise an exception + (#54, Amon Sha) + +3.0.2 (2012-01-27) +------------------ + +* Ensure `--option=value` is being evaluated before multiple switches (#52) + +3.0.1 (2012-01-27) +------------------ + +* Ensure tests run green on 1.8.7 +* Ensure `:argument => :optional` works with `:option=` format. +* Ruby 1.8.7 compat fix (dont chain Enumerable methods!) (Eric Anderson) + +3.0.0 (2012-01-24) +------------------ + +* value_to_range returns an x..x range if the value looks like an integer. +* Lots of code refactoring +* Use TomDoc documentation +* Added `Slop::Commands` and removed existing command system +* Configuration options altered: + * `:optional` has been renamed to `:optional_argument` + * Added `:required` for mandatory options + * `:argument` now accepts an `:optional` symbol as well as boolean value +* Removed Slop instance methods: + * description=, description + * summary=, summary + * command + * on_empty + * on_noopts + * execute + * to_struct +* Added Slop instance methods: + * separator + * fetch_option + * add_callback + +2.4.3 (2012-01-16) +------------------ + +* Allow the `:as` option to accept an object responding to :call for + custom type conversions (#45) +* Ensure negative integers are not parsed as possible options (#46) + +2.4.2 (2011-12-18) +------------------ + +* Fix checking of required options (Dominik Honnef) + +2.4.1 (2011-12-08) +------------------ + +* Ensure optional arguments are returned correctly + +2.4.0 (2011-11-26) +------------------ + +* Avoid `define_method` for checking an options presence (and caching it) #37 +* Ensure the short option allows an appended `=` for accepting arguments +* Implement `respond_to?` + +2.3.1 (2011-11-11) +------------------ + +* Return `nil` for any options using casting which don't expect arguments (#33) +* Fix parenthesis warning on 1.8.7 (@shevegen) +* Ensure long argument is a string before attempting to use `#[]` method on it + +2.3.0 (2011-11-04) +------------------ + +* Allow flags to have suffixed `=` char for options which accept an argument + +2.2.0 (2011-11-02) +------------------ + +* Support `bup.options` style optspec parsing + * http://apenwarr.ca/log/?m=201111 + +* Allow `:as` to accept a `count` value (Conrad Irwin): + + `on :v, :verbose, :as => :count # -vv; opts[:verbose] #=> 2` + +2.1.0 (2011-08-03) +------------------ + +* Added `Slop#missing` for returning a list of missing options parsed +* Allow `Slop#present?` to accept multiple arguments +* Added `:all_accept_arguments` to Slop configuration options, this saves + having to specify that every option takes an argument +* Added `Slop#to_struct` for building new classes from options + +2.0.0 (2011-07-07) +------------------ + +* Deprecations: + * Removed `Slop::Options#to_hash` continue using `Slop#to_hash` directly. + This method also now returns symbols by default instead of strings. If + you want strings use `opts.to_hash(false)` + * `:multiple_switches` is now enabled by default, to parse `fbar` as the + option `f` with value `bar` you must disable `:multiple_switches` + * Removed `Slop::Options#to_help` and merged its contents into `Slop#help` + * Removed `lib/slop/options.rb` and merged `Slop::Options` into slop.rb + * Removed `lib/slop/option.rb` and merged `Slop::Option` into slop.rb + * These changes make Slop much easier to vendor in libraries +* `Slop::Option` now inherits from `Struct.new` +* Added Slop::Error subclassing from StandardError which all exception + classes should inherit from +* Added Slop::MissingOptionError and `:required` option to Slop::Option. + This exception is raised when a mandatory option is not used + +1.9.1 (2011-06-16) +------------------ + +* Ensure optional items with no arguments still return true when searching + for presence + +1.9.0 (2011-06-15) +------------------ + +* Add command completion and support for an error message when ambiguous + commands are used +* Add command aliases +* Fix: Ensure parsed elements are removed from original arguments when using + `:multiple_switches` +* Ensure anything after `--` is parsed as an argument and not option even + if prefixed with `/--?/` +* Performance improvements when making many calls to `Slop#option?` for + checking an options presence (Rob Gleeson) +* Ensure `execute` passes command arguments to the block +* Support for summary and description (Denis Defreyne) + +1.8.0 (2011-06-12) +------------------ + +* Added `execute` method to Slop for commands. This block will be invoked + when a specific command is used. The Slop object will be yielded to the + block +* Allow passing a class name to `on` to be used as an `:as` option. ie: + `on :people, 'Some people', Array` +* Get smart with parsing options optparse style: `on '--name NAME'` and + `on 'password [OPTIONAL]'` +* Feature: `:arguments` setting to enable argument passing for all options + +1.7.0 (2011-06-06) +------------------ + +* Feature: Autocreate (auto create options at parse time, making assumptions) +* Feature: When parsing options as arrays, push multiple arguments into a + single array + +1.6.1 (2011-06-01) +------------------ + +* Fix tests and using a temporary Array for ARGV, fixes RubyGems Test issues +* General cleanup of code + +1.6.0 (2011-05-18) +------------------ + +* Add `:ignore_case` to Slop options for case insensitive option matching +* Add `:on_noopts` for triggering an event when the arguments contain no + options +* Add `:unless` to Slop::Option for omitting execution of the Options block + when this object exists in the Array of items passed to Slop.new +* Bugfix: Do not parse negative integers as options. A valid option must + start with an alphabet character +* Bugfix: Allow a Range to accept a negative Integer at either end + +1.5.5 (2011-05-03) +------------------ + +* Bugfix: only attempt to extract options prefixed with `-` + +1.5.4 (2011-05-01) +------------------ + +* Bugfix: `parse!` should not remove items with the same value as items used + in option arguments. Fixes #22 (Utkarsh Kukreti) + +1.5.3 (2011-04-22) +------------------ + +* Bugfix: Use integers when fetching array indexes, not strings + +1.5.2 (2011-04-17) +------------------ + +* Bugfix: Ensure `ARGV` is empty when using the `on_empty` event + +1.5.0 (2011-04-15) +------------------ + +* Add `Slop#get` as alias to `Slop#[]` +* Add `Slop#present?` as alias for `Slop#