diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/journey/scanner.rb')
-rw-r--r-- | actionpack/lib/action_dispatch/journey/scanner.rb | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/actionpack/lib/action_dispatch/journey/scanner.rb b/actionpack/lib/action_dispatch/journey/scanner.rb index 19e0bc03d6..2a075862e9 100644 --- a/actionpack/lib/action_dispatch/journey/scanner.rb +++ b/actionpack/lib/action_dispatch/journey/scanner.rb @@ -1,4 +1,6 @@ -require 'strscan' +# frozen_string_literal: true + +require "strscan" module ActionDispatch module Journey # :nodoc: @@ -32,27 +34,35 @@ module ActionDispatch private + # takes advantage of String @- deduping capabilities in Ruby 2.5 upwards + # see: https://bugs.ruby-lang.org/issues/13077 + def dedup_scan(regex) + r = @ss.scan(regex) + r ? -r : nil + end + def scan case # / - when text = @ss.scan(/\//) - [:SLASH, text] - when text = @ss.scan(/\*\w+/) - [:STAR, text] - when text = @ss.scan(/(?<!\\)\(/) - [:LPAREN, text] - when text = @ss.scan(/(?<!\\)\)/) - [:RPAREN, text] - when text = @ss.scan(/\|/) - [:OR, text] - when text = @ss.scan(/\./) - [:DOT, text] - when text = @ss.scan(/(?<!\\):\w+/) + when @ss.skip(/\//) + [:SLASH, "/"] + when @ss.skip(/\(/) + [:LPAREN, "("] + when @ss.skip(/\)/) + [:RPAREN, ")"] + when @ss.skip(/\|/) + [:OR, "|"] + when @ss.skip(/\./) + [:DOT, "."] + when text = dedup_scan(/:\w+/) [:SYMBOL, text] - when text = @ss.scan(/(?:[\w%\-~!$&'*+,;=@]|\\:|\\\(|\\\))+/) - [:LITERAL, text.tr('\\', '')] + when text = dedup_scan(/\*\w+/) + [:STAR, text] + when text = @ss.scan(/(?:[\w%\-~!$&'*+,;=@]|\\[:()])+/) + text.tr! "\\", "" + [:LITERAL, -text] # any char - when text = @ss.scan(/./) + when text = dedup_scan(/./) [:LITERAL, text] end end |