From 88727e6165bfe5b44d5d3d0793de660410dd729e Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Fri, 26 Jun 2009 08:53:10 +0200 Subject: [PATCH] cleanup stack/ruby_builder --- lib/core_ext/hash/delete_at.rb | 5 ++ lib/ripper/ruby_builder.rb | 72 +++++++------------------ lib/ripper/ruby_builder/events/array.rb | 4 +- lib/ripper/ruby_builder/stack.rb | 32 +++-------- lib/ripper/ruby_builder/token.rb | 6 +-- 5 files changed, 35 insertions(+), 84 deletions(-) create mode 100644 lib/core_ext/hash/delete_at.rb diff --git a/lib/core_ext/hash/delete_at.rb b/lib/core_ext/hash/delete_at.rb new file mode 100644 index 0000000..55b33ae --- /dev/null +++ b/lib/core_ext/hash/delete_at.rb @@ -0,0 +1,5 @@ +class Hash + def delete_at(*keys) + keys.map { |key| delete(key) } + end +end \ No newline at end of file diff --git a/lib/ripper/ruby_builder.rb b/lib/ripper/ruby_builder.rb index 2582520..6757dc0 100644 --- a/lib/ripper/ruby_builder.rb +++ b/lib/ripper/ruby_builder.rb @@ -19,23 +19,23 @@ def build(src, filename = nil) NEWLINE = [:@nl, :@ignored_nl] WHITESPACE = [:@sp, :@comment] + NEWLINE - OPENERS = [:@lparen, :@lbracket, :@lbrace, :@class, :@module, :@def, :@begin, :@while, :@until, + OPENERS = [:@lparen, :@lbracket, :@lbrace, :@class, :@module, :@def, :@begin, :@while, :@until, :@for, :@if, :@elsif, :@else, :@unless, :@case, :@when, :@embexpr_beg, :@do, :@rescue, :'@=', :'@::'] - KEYWORDS = [:@alias, :@and, :@BEGIN, :@begin, :@break, :@case, :@class, :@def, :@defined, - :@do, :@else, :@elsif, :@END, :@end, :@ensure, :@false, :@for, :@if, :@in, - :@module, :@next, :@nil, :@not, :@or, :@redo, :@rescue, :@retry, :@return, - :@self, :@super, :@then, :@true, :@undef, :@unless, :@until, :@when, :@while, + KEYWORDS = [:@alias, :@and, :@BEGIN, :@begin, :@break, :@case, :@class, :@def, :@defined, + :@do, :@else, :@elsif, :@END, :@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] - + SEPARATORS = [:@semicolon, :@comma] - + UNARY_OPERATORS = [:'@+', :'@-', :'@!', :'@~', :@not] - BINARY_OPERATORS = [:'@**', :'@*', :'@/', :'@%', :'@+', :'@-', :'@<<', :'@>>', :'@&', :'@|', :'@^', - :'@>', :'@>=', :'@<', :'@<=', :'@<=>', :'@==', :'@===', :'@!=', :'@=~', :'@!~', + BINARY_OPERATORS = [:'@**', :'@*', :'@/', :'@%', :'@+', :'@-', :'@<<', :'@>>', :'@&', :'@|', :'@^', + :'@>', :'@>=', :'@<', :'@<=', :'@<=>', :'@==', :'@===', :'@!=', :'@=~', :'@!~', :'@&&', :'@||', :@and, :@or] TERNARY_OPERATORS = [:'@?', :'@:'] - ASSIGN_OPERATORS = [:'@=', :'@+=', :'@-=', :'@*=', :'@**=', :'@%=', :'@/=', :'@|=', :'@&=', :'@^=', + ASSIGN_OPERATORS = [:'@=', :'@+=', :'@-=', :'@*=', :'@**=', :'@%=', :'@/=', :'@|=', :'@&=', :'@^=', :'@[]=', :'@||=', :'@&&=', :'@<<=', :'@>>='] ACCESS_OPERATORS = [:'@[]'] @@ -62,65 +62,37 @@ def initialize(src, filename = nil, lineno = nil) protected def position - Ruby::Node::Position.new(lineno - 1, column) + Ruby::Node::Position.new(lineno.to_i - 1, column) end def push(sexp = nil) - token = Token.new(*sexp) if sexp + token = Token.new(sexp[0], sexp[1], position) if sexp stack.push(token) unless extra_heredoc_chars(token) token end def pop(*args) - options = args.last.is_a?(::Hash) ? args.pop : {} - if types = options[:ignore] - stack_ignore(types) { stack.pop(*args << options) } - else - stack.pop(*args << options) - end - end - - def shift(*args) - stack.reverse! - result = pop(*args) - stack.reverse! - result - end - - def pop_one(*types) - options = types.last.is_a?(::Hash) ? types.pop : {} - options[:max] = 1 - pop(*types << options).first + stack.pop(*args) end - + def pop_token(*types) options = types.last.is_a?(::Hash) ? types.pop : {} options[:max] = 1 pop_tokens(*types << options).first end - - def shift_token(*types) - options = types.last.is_a?(::Hash) ? types.pop : {} - options[:max] = 1 - shift_tokens(*types << options).first - end def pop_tokens(*types) pop(*types).map { |token| build_token(token) }.flatten.compact end - def shift_tokens(*types) - shift(*types).map { |token| build_token(token) }.flatten.compact - end - def pop_identifier(type, options = {}) pop_token(type, options).to_identifier end - + def pop_operator(options = {}) pop_token(*OPERATORS, options) end - + def pop_unary_operator(options = {}) pop_token(*UNARY_OPERATORS, options) end @@ -129,10 +101,6 @@ def pop_binary_operator(options = {}) pop_token(*BINARY_OPERATORS, options) end - def pop_ternary_operators(options = {}) - pop_tokens(*TERNARY_OPERATORS, options) - end - def pop_ternary_operator(options = {}) pop_token(*TERNARY_OPERATORS, options) end @@ -145,18 +113,14 @@ def pop_context stack.context.get end - def stack_ignore(*types, &block) - stack.ignore_types(*types, &block) - end - def build_token(token) Ruby::Token.new(token.token, token.position, token.context) if token end - + def build_keyword(token) klass = Ruby.const_get(token.token[0].upcase + token.token[1..-1]) klass.new(token, token.position, token.context) - rescue NameError + rescue NameError Ruby::Keyword.new(token, token.position, token.context) end diff --git a/lib/ripper/ruby_builder/events/array.rb b/lib/ripper/ruby_builder/events/array.rb index 612f2a7..f3a45d9 100644 --- a/lib/ripper/ruby_builder/events/array.rb +++ b/lib/ripper/ruby_builder/events/array.rb @@ -44,14 +44,14 @@ def on_words_end(rdelim = nil) def on_aref(target, args) args ||= Ruby::ArgsList.new args.ldelim ||= pop_token(:@lbracket, :left => target) - args.rdelim ||= shift_token(:@rbracket, :pass => true, :left => args.ldelim) + args.rdelim ||= pop_token(:@rbracket, :reverse => true, :pass => true, :left => args.ldelim) Ruby::Call.new(target, nil, nil, args) end def on_aref_field(target, args) args ||= Ruby::ArgsList.new args.ldelim ||= pop_token(:@lbracket, :left => target) - args.rdelim ||= shift_token(:@rbracket, :pass => true, :left => args.ldelim) + args.rdelim ||= pop_token(:@rbracket, :reverse => true, :pass => true, :left => args.ldelim) Ruby::Call.new(target, nil, nil, args) end diff --git a/lib/ripper/ruby_builder/stack.rb b/lib/ripper/ruby_builder/stack.rb index f4da0a3..4723b70 100644 --- a/lib/ripper/ruby_builder/stack.rb +++ b/lib/ripper/ruby_builder/stack.rb @@ -1,3 +1,4 @@ +require 'core_ext/hash/delete_at' require 'ripper/ruby_builder/queue' require 'ripper/ruby_builder/context' @@ -22,45 +23,26 @@ def push(token) alias :_pop :pop def pop(*types) options = types.last.is_a?(::Hash) ? types.pop : {} - max, pass = options.delete(:max), options.delete(:pass) - @ignored, tokens = [], [] + max, pass, revert = options.delete_at(:max, :pass, :reverse) + ignored, tokens = [], [] + reverse! if revert while !empty? && !(max && tokens.length >= max) if types.include?(last.type) && matches?(options) tokens << _pop() - elsif ignore?(last.type) - ignore! elsif last.opener? && !pass break else - ignore! + ignored.unshift(_pop()) end end - replace(self + @ignored) + replace(self + ignored) + reverse! if revert tokens end - def ignore?(type) - ignore_stack.flatten.include?(type) - end - - def ignore! - @ignored.unshift(_pop()) - end - - def ignore_types(*types) - ignore_stack.push(types) - result = yield - ignore_stack.pop - result - end - protected - - def ignore_stack - @ignore_stack ||= [] - end def matches?(conditions) conditions.inject(true) do |result, (type, value)| diff --git a/lib/ripper/ruby_builder/token.rb b/lib/ripper/ruby_builder/token.rb index 3a5cc18..2cb3a1e 100644 --- a/lib/ripper/ruby_builder/token.rb +++ b/lib/ripper/ruby_builder/token.rb @@ -8,9 +8,9 @@ class Token attr_accessor :type, :token, :position, :context def initialize(type = nil, token = nil, position = nil) - @type = normalize_type(type, token) + @type = token_type(type, token) @token = token - @position = Ruby::Node::Position.new(position[0] - 1, position[1]) if position + @position = position if position end def newline? @@ -63,7 +63,7 @@ def <=>(other) protected - def normalize_type(type, token) + def token_type(type, token) case type when :@kw :"@#{token.gsub(/\W/, '')}"