diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/journey')
11 files changed, 72 insertions, 64 deletions
diff --git a/actionpack/lib/action_dispatch/journey/formatter.rb b/actionpack/lib/action_dispatch/journey/formatter.rb index 7764763791..57f0963731 100644 --- a/actionpack/lib/action_dispatch/journey/formatter.rb +++ b/actionpack/lib/action_dispatch/journey/formatter.rb @@ -33,8 +33,8 @@ module ActionDispatch return [route.format(parameterized_parts), params] end - message = "No route matches #{constraints.inspect}" - message << " missing required keys: #{missing_keys.inspect}" if name + message = "No route matches #{Hash[constraints.sort].inspect}" + message << " missing required keys: #{missing_keys.sort.inspect}" if name raise ActionController::UrlGenerationError, message end @@ -121,9 +121,9 @@ module ActionDispatch def possibles(cache, options, depth = 0) cache.fetch(:___routes) { [] } + options.find_all { |pair| cache.key?(pair) - }.map { |pair| + }.flat_map { |pair| possibles(cache[pair], options, depth + 1) - }.flatten(1) + } end # Returns +true+ if no missing keys are present, otherwise +false+. diff --git a/actionpack/lib/action_dispatch/journey/gtg/builder.rb b/actionpack/lib/action_dispatch/journey/gtg/builder.rb index 7d2791714b..450588cda6 100644 --- a/actionpack/lib/action_dispatch/journey/gtg/builder.rb +++ b/actionpack/lib/action_dispatch/journey/gtg/builder.rb @@ -27,7 +27,7 @@ module ActionDispatch marked[s] = true # mark s s.group_by { |state| symbol(state) }.each do |sym, ps| - u = ps.map { |l| followpos(l) }.flatten + u = ps.flat_map { |l| followpos(l) } next if u.empty? if u.uniq == [DUMMY] @@ -90,7 +90,7 @@ module ActionDispatch firstpos(node.left) end when Nodes::Or - node.children.map { |c| firstpos(c) }.flatten.uniq + node.children.flat_map { |c| firstpos(c) }.uniq when Nodes::Unary firstpos(node.left) when Nodes::Terminal @@ -105,7 +105,7 @@ module ActionDispatch when Nodes::Star firstpos(node.left) when Nodes::Or - node.children.map { |c| lastpos(c) }.flatten.uniq + node.children.flat_map { |c| lastpos(c) }.uniq when Nodes::Cat if nullable?(node.right) lastpos(node.left) | lastpos(node.right) diff --git a/actionpack/lib/action_dispatch/journey/gtg/simulator.rb b/actionpack/lib/action_dispatch/journey/gtg/simulator.rb index 58ad803841..94b0a24344 100644 --- a/actionpack/lib/action_dispatch/journey/gtg/simulator.rb +++ b/actionpack/lib/action_dispatch/journey/gtg/simulator.rb @@ -19,6 +19,14 @@ module ActionDispatch end def simulate(string) + ms = memos(string) { return } + MatchData.new(ms) + end + + alias :=~ :simulate + alias :match :simulate + + def memos(string) input = StringScanner.new(string) state = [0] while sym = input.scan(%r([/.?]|[^/.?]+)) @@ -29,15 +37,10 @@ module ActionDispatch tt.accepting? s } - return if acceptance_states.empty? + return yield if acceptance_states.empty? - memos = acceptance_states.map { |x| tt.memo(x) }.flatten.compact - - MatchData.new(memos) + acceptance_states.flat_map { |x| tt.memo(x) }.compact end - - alias :=~ :simulate - alias :match :simulate end end end diff --git a/actionpack/lib/action_dispatch/journey/gtg/transition_table.rb b/actionpack/lib/action_dispatch/journey/gtg/transition_table.rb index 5a79059ed6..990d2127ee 100644 --- a/actionpack/lib/action_dispatch/journey/gtg/transition_table.rb +++ b/actionpack/lib/action_dispatch/journey/gtg/transition_table.rb @@ -40,7 +40,19 @@ module ActionDispatch end def move(t, a) - move_string(t, a).concat(move_regexp(t, a)) + return [] if t.empty? + + regexps = [] + + t.map { |s| + if states = @regexp_states[s] + regexps.concat states.map { |re, v| re === a ? v : nil } + end + + if states = @string_states[s] + states[a] + end + }.compact.concat regexps end def as_json(options = nil) @@ -114,17 +126,17 @@ module ActionDispatch end def states - ss = @string_states.keys + @string_states.values.map(&:values).flatten - rs = @regexp_states.keys + @regexp_states.values.map(&:values).flatten + ss = @string_states.keys + @string_states.values.flat_map(&:values) + rs = @regexp_states.keys + @regexp_states.values.flat_map(&:values) (ss + rs).uniq end def transitions - @string_states.map { |from, hash| + @string_states.flat_map { |from, hash| hash.map { |s, to| [from, s, to] } - }.flatten(1) + @regexp_states.map { |from, hash| + } + @regexp_states.flat_map { |from, hash| hash.map { |s, to| [from, s, to] } - }.flatten(1) + } end private @@ -139,26 +151,6 @@ module ActionDispatch raise ArgumentError, 'unknown symbol: %s' % sym.class end end - - def move_regexp(t, a) - return [] if t.empty? - - t.map { |s| - if states = @regexp_states[s] - states.map { |re, v| re === a ? v : nil } - end - }.flatten.compact.uniq - end - - def move_string(t, a) - return [] if t.empty? - - t.map do |s| - if states = @string_states[s] - states[a] - end - end.compact - end end end end diff --git a/actionpack/lib/action_dispatch/journey/nfa/dot.rb b/actionpack/lib/action_dispatch/journey/nfa/dot.rb index 5c33a872e5..47bf76bdbf 100644 --- a/actionpack/lib/action_dispatch/journey/nfa/dot.rb +++ b/actionpack/lib/action_dispatch/journey/nfa/dot.rb @@ -16,9 +16,9 @@ module ActionDispatch # end # " #{n.object_id} [label=\"#{label}\", shape=box];" #} - #memo_edges = memos.map { |k, memos| + #memo_edges = memos.flat_map { |k, memos| # (memos || []).map { |v| " #{k} -> #{v.object_id};" } - #}.flatten.uniq + #}.uniq <<-eodot digraph nfa { diff --git a/actionpack/lib/action_dispatch/journey/nfa/simulator.rb b/actionpack/lib/action_dispatch/journey/nfa/simulator.rb index 5b40da6569..b23270db3c 100644 --- a/actionpack/lib/action_dispatch/journey/nfa/simulator.rb +++ b/actionpack/lib/action_dispatch/journey/nfa/simulator.rb @@ -34,7 +34,7 @@ module ActionDispatch return if acceptance_states.empty? - memos = acceptance_states.map { |x| tt.memo(x) }.flatten.compact + memos = acceptance_states.flat_map { |x| tt.memo(x) }.compact MatchData.new(memos) end diff --git a/actionpack/lib/action_dispatch/journey/nfa/transition_table.rb b/actionpack/lib/action_dispatch/journey/nfa/transition_table.rb index a3017aeea1..66e414213a 100644 --- a/actionpack/lib/action_dispatch/journey/nfa/transition_table.rb +++ b/actionpack/lib/action_dispatch/journey/nfa/transition_table.rb @@ -42,7 +42,7 @@ module ActionDispatch end def states - (@table.keys + @table.values.map(&:keys).flatten).uniq + (@table.keys + @table.values.flat_map(&:keys)).uniq end # Returns a generalized transition graph with reduced states. The states @@ -93,7 +93,7 @@ module ActionDispatch # Returns set of NFA states to which there is a transition on ast symbol # +a+ from some state +s+ in +t+. def following_states(t, a) - Array(t).map { |s| inverted[s][a] }.flatten.uniq + Array(t).flat_map { |s| inverted[s][a] }.uniq end # Returns set of NFA states to which there is a transition on ast symbol @@ -107,7 +107,7 @@ module ActionDispatch end def alphabet - inverted.values.map(&:keys).flatten.compact.uniq.sort_by { |x| x.to_s } + inverted.values.flat_map(&:keys).compact.uniq.sort_by { |x| x.to_s } end # Returns a set of NFA states reachable from some NFA state +s+ in set @@ -131,9 +131,9 @@ module ActionDispatch end def transitions - @table.map { |to, hash| + @table.flat_map { |to, hash| hash.map { |from, sym| [from, sym, to] } - }.flatten(1) + } end private diff --git a/actionpack/lib/action_dispatch/journey/parser.rb b/actionpack/lib/action_dispatch/journey/parser.rb index bb4cbb00e2..430812fafe 100644 --- a/actionpack/lib/action_dispatch/journey/parser.rb +++ b/actionpack/lib/action_dispatch/journey/parser.rb @@ -1,7 +1,7 @@ # # DO NOT MODIFY!!!! # This file is automatically generated by Racc 1.4.9 -# from Racc grammer file "". +# from Racc grammar file "". # require 'racc/parser.rb' diff --git a/actionpack/lib/action_dispatch/journey/path/pattern.rb b/actionpack/lib/action_dispatch/journey/path/pattern.rb index d37aa1fbe5..fb155e516f 100644 --- a/actionpack/lib/action_dispatch/journey/path/pattern.rb +++ b/actionpack/lib/action_dispatch/journey/path/pattern.rb @@ -53,9 +53,9 @@ module ActionDispatch end def optional_names - @optional_names ||= spec.grep(Nodes::Group).map { |group| + @optional_names ||= spec.grep(Nodes::Group).flat_map { |group| group.grep(Nodes::Symbol) - }.flatten.map { |n| n.name }.uniq + }.map { |n| n.name }.uniq end class RegexpOffsets < Journey::Visitors::Visitor # :nodoc: diff --git a/actionpack/lib/action_dispatch/journey/router.rb b/actionpack/lib/action_dispatch/journey/router.rb index da32f1bfe7..36561c71a1 100644 --- a/actionpack/lib/action_dispatch/journey/router.rb +++ b/actionpack/lib/action_dispatch/journey/router.rb @@ -54,7 +54,7 @@ module ActionDispatch end def call(env) - env['PATH_INFO'] = normalize_path(env['PATH_INFO']) + env['PATH_INFO'] = Utils.normalize_path(env['PATH_INFO']) find_routes(env).each do |match, parameters, route| script_name, path_info, set_params = env.values_at('SCRIPT_NAME', @@ -103,12 +103,6 @@ module ActionDispatch private - def normalize_path(path) - path = "/#{path}" - path.squeeze!('/') - path - end - def partitioned_routes routes.partitioned_routes end @@ -127,8 +121,7 @@ module ActionDispatch def filter_routes(path) return [] unless ast - data = simulator.match(path) - data ? data.memos : [] + simulator.memos(path) { [] } end def find_routes env diff --git a/actionpack/lib/action_dispatch/journey/visitors.rb b/actionpack/lib/action_dispatch/journey/visitors.rb index 9e66cab052..daade5bb74 100644 --- a/actionpack/lib/action_dispatch/journey/visitors.rb +++ b/actionpack/lib/action_dispatch/journey/visitors.rb @@ -77,12 +77,32 @@ module ActionDispatch end end - class OptimizedPath < String # :nodoc: + class OptimizedPath < Visitor # :nodoc: + def accept(node) + Array(visit(node)) + end + private - def visit_GROUP(node) - "" - end + def visit_CAT(node) + [visit(node.left), visit(node.right)].flatten + end + + def visit_SYMBOL(node) + node.left[1..-1].to_sym + end + + def visit_STAR(node) + visit(node.left) + end + + def visit_GROUP(node) + [] + end + + %w{ LITERAL SLASH DOT }.each do |t| + class_eval %{ def visit_#{t}(n); n.left; end }, __FILE__, __LINE__ + end end # Used for formatting urls (url_for) |