actionpack 7.1.5.1 → 8.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +308 -523
  3. data/README.rdoc +1 -1
  4. data/lib/abstract_controller/asset_paths.rb +6 -2
  5. data/lib/abstract_controller/base.rb +104 -105
  6. data/lib/abstract_controller/caching/fragments.rb +50 -53
  7. data/lib/abstract_controller/caching.rb +8 -3
  8. data/lib/abstract_controller/callbacks.rb +70 -62
  9. data/lib/abstract_controller/collector.rb +7 -7
  10. data/lib/abstract_controller/deprecator.rb +2 -0
  11. data/lib/abstract_controller/error.rb +2 -0
  12. data/lib/abstract_controller/helpers.rb +71 -84
  13. data/lib/abstract_controller/logger.rb +4 -1
  14. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  15. data/lib/abstract_controller/rendering.rb +13 -13
  16. data/lib/abstract_controller/translation.rb +12 -13
  17. data/lib/abstract_controller/url_for.rb +8 -6
  18. data/lib/abstract_controller.rb +2 -0
  19. data/lib/action_controller/api/api_rendering.rb +2 -0
  20. data/lib/action_controller/api.rb +76 -72
  21. data/lib/action_controller/base.rb +199 -126
  22. data/lib/action_controller/caching.rb +16 -14
  23. data/lib/action_controller/deprecator.rb +2 -0
  24. data/lib/action_controller/form_builder.rb +21 -18
  25. data/lib/action_controller/log_subscriber.rb +23 -2
  26. data/lib/action_controller/metal/allow_browser.rb +133 -0
  27. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  28. data/lib/action_controller/metal/conditional_get.rb +217 -175
  29. data/lib/action_controller/metal/content_security_policy.rb +25 -24
  30. data/lib/action_controller/metal/cookies.rb +4 -2
  31. data/lib/action_controller/metal/data_streaming.rb +72 -63
  32. data/lib/action_controller/metal/default_headers.rb +5 -3
  33. data/lib/action_controller/metal/etag_with_flash.rb +3 -1
  34. data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
  35. data/lib/action_controller/metal/exceptions.rb +16 -9
  36. data/lib/action_controller/metal/flash.rb +13 -14
  37. data/lib/action_controller/metal/head.rb +15 -11
  38. data/lib/action_controller/metal/helpers.rb +63 -55
  39. data/lib/action_controller/metal/http_authentication.rb +209 -201
  40. data/lib/action_controller/metal/implicit_render.rb +17 -15
  41. data/lib/action_controller/metal/instrumentation.rb +16 -14
  42. data/lib/action_controller/metal/live.rb +177 -128
  43. data/lib/action_controller/metal/logging.rb +6 -4
  44. data/lib/action_controller/metal/mime_responds.rb +151 -142
  45. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  46. data/lib/action_controller/metal/params_wrapper.rb +57 -59
  47. data/lib/action_controller/metal/permissions_policy.rb +22 -12
  48. data/lib/action_controller/metal/rate_limiting.rb +92 -0
  49. data/lib/action_controller/metal/redirecting.rb +213 -94
  50. data/lib/action_controller/metal/renderers.rb +78 -57
  51. data/lib/action_controller/metal/rendering.rb +111 -77
  52. data/lib/action_controller/metal/request_forgery_protection.rb +182 -143
  53. data/lib/action_controller/metal/rescue.rb +20 -9
  54. data/lib/action_controller/metal/streaming.rb +118 -195
  55. data/lib/action_controller/metal/strong_parameters.rb +720 -530
  56. data/lib/action_controller/metal/testing.rb +2 -0
  57. data/lib/action_controller/metal/url_for.rb +17 -15
  58. data/lib/action_controller/metal.rb +86 -60
  59. data/lib/action_controller/railtie.rb +36 -15
  60. data/lib/action_controller/railties/helpers.rb +2 -0
  61. data/lib/action_controller/renderer.rb +41 -36
  62. data/lib/action_controller/structured_event_subscriber.rb +116 -0
  63. data/lib/action_controller/template_assertions.rb +4 -2
  64. data/lib/action_controller/test_case.rb +160 -131
  65. data/lib/action_controller.rb +5 -1
  66. data/lib/action_dispatch/constants.rb +8 -0
  67. data/lib/action_dispatch/deprecator.rb +2 -0
  68. data/lib/action_dispatch/http/cache.rb +163 -35
  69. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +54 -39
  71. data/lib/action_dispatch/http/filter_parameters.rb +14 -8
  72. data/lib/action_dispatch/http/filter_redirect.rb +22 -1
  73. data/lib/action_dispatch/http/headers.rb +22 -22
  74. data/lib/action_dispatch/http/mime_negotiation.rb +89 -41
  75. data/lib/action_dispatch/http/mime_type.rb +25 -21
  76. data/lib/action_dispatch/http/mime_types.rb +3 -0
  77. data/lib/action_dispatch/http/param_builder.rb +187 -0
  78. data/lib/action_dispatch/http/param_error.rb +26 -0
  79. data/lib/action_dispatch/http/parameters.rb +14 -12
  80. data/lib/action_dispatch/http/permissions_policy.rb +25 -36
  81. data/lib/action_dispatch/http/query_parser.rb +55 -0
  82. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  83. data/lib/action_dispatch/http/request.rb +141 -92
  84. data/lib/action_dispatch/http/response.rb +137 -77
  85. data/lib/action_dispatch/http/upload.rb +18 -16
  86. data/lib/action_dispatch/http/url.rb +187 -89
  87. data/lib/action_dispatch/journey/formatter.rb +21 -9
  88. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  89. data/lib/action_dispatch/journey/gtg/simulator.rb +34 -11
  90. data/lib/action_dispatch/journey/gtg/transition_table.rb +47 -53
  91. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  92. data/lib/action_dispatch/journey/nodes/node.rb +8 -6
  93. data/lib/action_dispatch/journey/parser.rb +99 -195
  94. data/lib/action_dispatch/journey/path/pattern.rb +4 -1
  95. data/lib/action_dispatch/journey/route.rb +54 -38
  96. data/lib/action_dispatch/journey/router/utils.rb +22 -27
  97. data/lib/action_dispatch/journey/router.rb +63 -83
  98. data/lib/action_dispatch/journey/routes.rb +11 -2
  99. data/lib/action_dispatch/journey/scanner.rb +46 -42
  100. data/lib/action_dispatch/journey/visitors.rb +57 -23
  101. data/lib/action_dispatch/journey/visualizer/fsm.js +4 -6
  102. data/lib/action_dispatch/journey.rb +2 -0
  103. data/lib/action_dispatch/log_subscriber.rb +7 -1
  104. data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
  105. data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
  106. data/lib/action_dispatch/middleware/callbacks.rb +3 -1
  107. data/lib/action_dispatch/middleware/cookies.rb +125 -106
  108. data/lib/action_dispatch/middleware/debug_exceptions.rb +37 -8
  109. data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
  110. data/lib/action_dispatch/middleware/debug_view.rb +13 -5
  111. data/lib/action_dispatch/middleware/exception_wrapper.rb +18 -23
  112. data/lib/action_dispatch/middleware/executor.rb +19 -4
  113. data/lib/action_dispatch/middleware/flash.rb +63 -51
  114. data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
  115. data/lib/action_dispatch/middleware/public_exceptions.rb +14 -12
  116. data/lib/action_dispatch/middleware/reloader.rb +5 -3
  117. data/lib/action_dispatch/middleware/remote_ip.rb +87 -77
  118. data/lib/action_dispatch/middleware/request_id.rb +16 -10
  119. data/lib/action_dispatch/middleware/server_timing.rb +4 -2
  120. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
  121. data/lib/action_dispatch/middleware/session/cache_store.rb +30 -8
  122. data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
  123. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
  124. data/lib/action_dispatch/middleware/show_exceptions.rb +16 -16
  125. data/lib/action_dispatch/middleware/ssl.rb +53 -40
  126. data/lib/action_dispatch/middleware/stack.rb +11 -10
  127. data/lib/action_dispatch/middleware/static.rb +33 -31
  128. data/lib/action_dispatch/middleware/templates/rescues/_copy_button.html.erb +1 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +3 -5
  130. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +9 -5
  131. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +1 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +1 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +4 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +3 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +50 -0
  136. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -0
  137. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -0
  138. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -0
  139. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -0
  140. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -0
  141. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
  142. data/lib/action_dispatch/railtie.rb +23 -3
  143. data/lib/action_dispatch/request/session.rb +24 -21
  144. data/lib/action_dispatch/request/utils.rb +11 -3
  145. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  146. data/lib/action_dispatch/routing/inspector.rb +85 -60
  147. data/lib/action_dispatch/routing/mapper.rb +1031 -851
  148. data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
  149. data/lib/action_dispatch/routing/redirection.rb +47 -39
  150. data/lib/action_dispatch/routing/route_set.rb +79 -56
  151. data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
  152. data/lib/action_dispatch/routing/url_for.rb +130 -125
  153. data/lib/action_dispatch/routing.rb +150 -148
  154. data/lib/action_dispatch/structured_event_subscriber.rb +20 -0
  155. data/lib/action_dispatch/system_test_case.rb +91 -81
  156. data/lib/action_dispatch/system_testing/browser.rb +16 -23
  157. data/lib/action_dispatch/system_testing/driver.rb +2 -0
  158. data/lib/action_dispatch/system_testing/server.rb +2 -0
  159. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +34 -23
  160. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  161. data/lib/action_dispatch/testing/assertion_response.rb +9 -7
  162. data/lib/action_dispatch/testing/assertions/response.rb +52 -25
  163. data/lib/action_dispatch/testing/assertions/routing.rb +168 -87
  164. data/lib/action_dispatch/testing/assertions.rb +2 -0
  165. data/lib/action_dispatch/testing/integration.rb +233 -223
  166. data/lib/action_dispatch/testing/request_encoder.rb +11 -9
  167. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  168. data/lib/action_dispatch/testing/test_process.rb +11 -8
  169. data/lib/action_dispatch/testing/test_request.rb +3 -1
  170. data/lib/action_dispatch/testing/test_response.rb +27 -26
  171. data/lib/action_dispatch.rb +36 -32
  172. data/lib/action_pack/gem_version.rb +6 -4
  173. data/lib/action_pack/version.rb +3 -1
  174. data/lib/action_pack.rb +17 -16
  175. metadata +36 -32
  176. data/lib/action_dispatch/journey/parser.y +0 -50
  177. data/lib/action_dispatch/journey/parser_extras.rb +0 -31
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "action_dispatch/journey/nfa/dot"
4
6
 
5
7
  module ActionDispatch
@@ -11,7 +13,6 @@ module ActionDispatch
11
13
  attr_reader :memos
12
14
 
13
15
  DEFAULT_EXP = /[^.\/?]+/
14
- DEFAULT_EXP_ANCHORED = /\A#{DEFAULT_EXP}\Z/
15
16
 
16
17
  def initialize
17
18
  @stdparam_states = {}
@@ -45,32 +46,34 @@ module ActionDispatch
45
46
  Array(t)
46
47
  end
47
48
 
48
- def move(t, full_string, start_index, end_index)
49
+ def move(t, full_string, token, start_index, token_matches_default)
49
50
  return [] if t.empty?
50
51
 
51
52
  next_states = []
52
53
 
53
- tok = full_string.slice(start_index, end_index - start_index)
54
- token_matches_default_component = DEFAULT_EXP_ANCHORED.match?(tok)
55
-
56
- t.each { |s, previous_start|
54
+ transitions_count = t.size
55
+ i = 0
56
+ while i < transitions_count
57
+ s = t[i]
58
+ previous_start = t[i + 1]
57
59
  if previous_start.nil?
58
- # In the simple case of a "default" param regex do this fast-path
59
- # and add all next states.
60
- if token_matches_default_component && states = @stdparam_states[s]
61
- states.each { |re, v| next_states << [v, nil].freeze if !v.nil? }
60
+ # In the simple case of a "default" param regex do this fast-path and add all
61
+ # next states.
62
+ if token_matches_default && std_state = @stdparam_states[s]
63
+ next_states << std_state << nil
62
64
  end
63
65
 
64
66
  # When we have a literal string, we can just pull the next state
65
67
  if states = @string_states[s]
66
- next_states << [states[tok], nil].freeze unless states[tok].nil?
68
+ state = states[token]
69
+ next_states << state << nil unless state.nil?
67
70
  end
68
71
  end
69
72
 
70
- # For regexes that aren't the "default" style, they may potentially
71
- # not be terminated by the first "token" [./?], so we need to continue
72
- # to attempt to match this regexp as well as any successful paths that
73
- # continue out of it. both paths could be valid.
73
+ # For regexes that aren't the "default" style, they may potentially not be
74
+ # terminated by the first "token" [./?], so we need to continue to attempt to
75
+ # match this regexp as well as any successful paths that continue out of it.
76
+ # both paths could be valid.
74
77
  if states = @regexp_states[s]
75
78
  slice_start = if previous_start.nil?
76
79
  start_index
@@ -78,19 +81,21 @@ module ActionDispatch
78
81
  previous_start
79
82
  end
80
83
 
81
- slice_length = end_index - slice_start
84
+ slice_length = start_index + token.length - slice_start
82
85
  curr_slice = full_string.slice(slice_start, slice_length)
83
86
 
84
87
  states.each { |re, v|
85
88
  # if we match, we can try moving past this
86
- next_states << [v, nil].freeze if !v.nil? && re.match?(curr_slice)
89
+ next_states << v << nil if !v.nil? && re.match?(curr_slice)
87
90
  }
88
91
 
89
- # and regardless, we must continue accepting tokens and retrying this regexp.
90
- # we need to remember where we started as well so we can take bigger slices.
91
- next_states << [s, slice_start].freeze
92
+ # and regardless, we must continue accepting tokens and retrying this regexp. we
93
+ # need to remember where we started as well so we can take bigger slices.
94
+ next_states << s << slice_start
92
95
  end
93
- }
96
+
97
+ i += 2
98
+ end
94
99
 
95
100
  next_states
96
101
  end
@@ -105,10 +110,10 @@ module ActionDispatch
105
110
  end
106
111
 
107
112
  {
108
- regexp_states: simple_regexp,
109
- string_states: @string_states,
110
- stdparam_states: @stdparam_states,
111
- accepting: @accepting
113
+ regexp_states: simple_regexp.stringify_keys,
114
+ string_states: @string_states.stringify_keys,
115
+ stdparam_states: @stdparam_states.stringify_keys,
116
+ accepting: @accepting.stringify_keys
112
117
  }
113
118
  end
114
119
 
@@ -161,54 +166,43 @@ module ActionDispatch
161
166
  end
162
167
 
163
168
  def []=(from, to, sym)
164
- to_mappings = states_hash_for(sym)[from] ||= {}
165
169
  case sym
170
+ when String, Symbol
171
+ to_mapping = @string_states[from] ||= {}
172
+ # account for symbols in the constraints the same as strings
173
+ to_mapping[sym.to_s] = to
166
174
  when Regexp
167
- # we must match the whole string to a token boundary
168
175
  if sym == DEFAULT_EXP
169
- sym = DEFAULT_EXP_ANCHORED
176
+ @stdparam_states[from] = to
170
177
  else
171
- sym = /\A#{sym}\Z/
178
+ to_mapping = @regexp_states[from] ||= {}
179
+ # we must match the whole string to a token boundary
180
+ to_mapping[/\A#{sym}\Z/] = to
172
181
  end
173
- when Symbol
174
- # account for symbols in the constraints the same as strings
175
- sym = sym.to_s
182
+ else
183
+ raise ArgumentError, "unknown symbol: %s" % sym.class
176
184
  end
177
- to_mappings[sym] = to
178
185
  end
179
186
 
180
187
  def states
181
188
  ss = @string_states.keys + @string_states.values.flat_map(&:values)
182
- ps = @stdparam_states.keys + @stdparam_states.values.flat_map(&:values)
189
+ ps = @stdparam_states.keys + @stdparam_states.values
183
190
  rs = @regexp_states.keys + @regexp_states.values.flat_map(&:values)
184
191
  (ss + ps + rs).uniq
185
192
  end
186
193
 
187
194
  def transitions
195
+ # double escaped because dot evaluates escapes
196
+ default_exp_anchored = "\\\\A#{DEFAULT_EXP.source}\\\\Z"
197
+
188
198
  @string_states.flat_map { |from, hash|
189
199
  hash.map { |s, to| [from, s, to] }
190
- } + @stdparam_states.flat_map { |from, hash|
191
- hash.map { |s, to| [from, s, to] }
200
+ } + @stdparam_states.map { |from, to|
201
+ [from, default_exp_anchored, to]
192
202
  } + @regexp_states.flat_map { |from, hash|
193
- hash.map { |s, to| [from, s, to] }
203
+ hash.map { |r, to| [from, r.source.gsub("\\") { "\\\\" }, to] }
194
204
  }
195
205
  end
196
-
197
- private
198
- def states_hash_for(sym)
199
- case sym
200
- when String, Symbol
201
- @string_states
202
- when Regexp
203
- if sym == DEFAULT_EXP
204
- @stdparam_states
205
- else
206
- @regexp_states
207
- end
208
- else
209
- raise ArgumentError, "unknown symbol: %s" % sym.class
210
- end
211
- end
212
206
  end
213
207
  end
214
208
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionDispatch
4
6
  module Journey # :nodoc:
5
7
  module NFA # :nodoc:
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "action_dispatch/journey/visitors"
4
6
 
5
7
  module ActionDispatch
@@ -21,9 +23,8 @@ module ActionDispatch
21
23
  end
22
24
 
23
25
  def requirements=(requirements)
24
- # inject any regexp requirements for `star` nodes so they can be
25
- # determined nullable, which requires knowing if the regex accepts an
26
- # empty string.
26
+ # inject any regexp requirements for `star` nodes so they can be determined
27
+ # nullable, which requires knowing if the regex accepts an empty string.
27
28
  (symbols + stars).each do |node|
28
29
  re = requirements[node.to_sym]
29
30
  node.regexp = re if re
@@ -51,8 +52,8 @@ module ActionDispatch
51
52
  stars << node
52
53
 
53
54
  if formatted != false
54
- # Add a constraint for wildcard route to make it non-greedy and
55
- # match the optional format part of the route by default.
55
+ # Add a constraint for wildcard route to make it non-greedy and match the
56
+ # optional format part of the route by default.
56
57
  wildcard_options[node.name.to_sym] ||= /.+?/m
57
58
  end
58
59
  end
@@ -73,6 +74,7 @@ module ActionDispatch
73
74
  def initialize(left)
74
75
  @left = left
75
76
  @memo = nil
77
+ @to_s = nil
76
78
  end
77
79
 
78
80
  def each(&block)
@@ -80,7 +82,7 @@ module ActionDispatch
80
82
  end
81
83
 
82
84
  def to_s
83
- Visitors::String::INSTANCE.accept(self, "")
85
+ @to_s ||= Visitors::String::INSTANCE.accept(self, "".dup).freeze
84
86
  end
85
87
 
86
88
  def to_dot
@@ -1,199 +1,103 @@
1
- #
2
- # DO NOT MODIFY!!!!
3
- # This file is automatically generated by Racc 1.4.16
4
- # from Racc grammar file "".
5
- #
1
+ # frozen_string_literal: true
6
2
 
7
- require 'racc/parser.rb'
3
+ require "action_dispatch/journey/scanner"
4
+ require "action_dispatch/journey/nodes/node"
8
5
 
9
- # :stopdoc:
10
-
11
- require "action_dispatch/journey/parser_extras"
12
6
  module ActionDispatch
13
- module Journey
14
- class Parser < Racc::Parser
15
- ##### State transition tables begin ###
16
-
17
- racc_action_table = [
18
- 13, 15, 14, 7, 19, 16, 8, 19, 13, 15,
19
- 14, 7, 17, 16, 8, 13, 15, 14, 7, 21,
20
- 16, 8, 13, 15, 14, 7, 24, 16, 8 ]
21
-
22
- racc_action_check = [
23
- 2, 2, 2, 2, 22, 2, 2, 2, 19, 19,
24
- 19, 19, 1, 19, 19, 7, 7, 7, 7, 17,
25
- 7, 7, 0, 0, 0, 0, 20, 0, 0 ]
26
-
27
- racc_action_pointer = [
28
- 20, 12, -2, nil, nil, nil, nil, 13, nil, nil,
29
- nil, nil, nil, nil, nil, nil, nil, 19, nil, 6,
30
- 20, nil, -5, nil, nil ]
31
-
32
- racc_action_default = [
33
- -19, -19, -2, -3, -4, -5, -6, -19, -10, -11,
34
- -12, -13, -14, -15, -16, -17, -18, -19, -1, -19,
35
- -19, 25, -8, -9, -7 ]
36
-
37
- racc_goto_table = [
38
- 1, 22, 18, 23, nil, nil, nil, 20 ]
39
-
40
- racc_goto_check = [
41
- 1, 2, 1, 3, nil, nil, nil, 1 ]
42
-
43
- racc_goto_pointer = [
44
- nil, 0, -18, -16, nil, nil, nil, nil, nil, nil,
45
- nil ]
46
-
47
- racc_goto_default = [
48
- nil, nil, 2, 3, 4, 5, 6, 9, 10, 11,
49
- 12 ]
50
-
51
- racc_reduce_table = [
52
- 0, 0, :racc_error,
53
- 2, 11, :_reduce_1,
54
- 1, 11, :_reduce_2,
55
- 1, 11, :_reduce_none,
56
- 1, 12, :_reduce_none,
57
- 1, 12, :_reduce_none,
58
- 1, 12, :_reduce_none,
59
- 3, 15, :_reduce_7,
60
- 3, 13, :_reduce_8,
61
- 3, 13, :_reduce_9,
62
- 1, 16, :_reduce_10,
63
- 1, 14, :_reduce_none,
64
- 1, 14, :_reduce_none,
65
- 1, 14, :_reduce_none,
66
- 1, 14, :_reduce_none,
67
- 1, 19, :_reduce_15,
68
- 1, 17, :_reduce_16,
69
- 1, 18, :_reduce_17,
70
- 1, 20, :_reduce_18 ]
71
-
72
- racc_reduce_n = 19
73
-
74
- racc_shift_n = 25
75
-
76
- racc_token_table = {
77
- false => 0,
78
- :error => 1,
79
- :SLASH => 2,
80
- :LITERAL => 3,
81
- :SYMBOL => 4,
82
- :LPAREN => 5,
83
- :RPAREN => 6,
84
- :DOT => 7,
85
- :STAR => 8,
86
- :OR => 9 }
87
-
88
- racc_nt_base = 10
89
-
90
- racc_use_result_var = false
91
-
92
- Racc_arg = [
93
- racc_action_table,
94
- racc_action_check,
95
- racc_action_default,
96
- racc_action_pointer,
97
- racc_goto_table,
98
- racc_goto_check,
99
- racc_goto_default,
100
- racc_goto_pointer,
101
- racc_nt_base,
102
- racc_reduce_table,
103
- racc_token_table,
104
- racc_shift_n,
105
- racc_reduce_n,
106
- racc_use_result_var ]
107
-
108
- Racc_token_to_s_table = [
109
- "$end",
110
- "error",
111
- "SLASH",
112
- "LITERAL",
113
- "SYMBOL",
114
- "LPAREN",
115
- "RPAREN",
116
- "DOT",
117
- "STAR",
118
- "OR",
119
- "$start",
120
- "expressions",
121
- "expression",
122
- "or",
123
- "terminal",
124
- "group",
125
- "star",
126
- "symbol",
127
- "literal",
128
- "slash",
129
- "dot" ]
130
-
131
- Racc_debug_parser = false
132
-
133
- ##### State transition tables end #####
134
-
135
- # reduce 0 omitted
136
-
137
- def _reduce_1(val, _values)
138
- Cat.new(val.first, val.last)
139
- end
140
-
141
- def _reduce_2(val, _values)
142
- val.first
143
- end
144
-
145
- # reduce 3 omitted
146
-
147
- # reduce 4 omitted
148
-
149
- # reduce 5 omitted
150
-
151
- # reduce 6 omitted
152
-
153
- def _reduce_7(val, _values)
154
- Group.new(val[1])
155
- end
156
-
157
- def _reduce_8(val, _values)
158
- Or.new([val.first, val.last])
159
- end
160
-
161
- def _reduce_9(val, _values)
162
- Or.new([val.first, val.last])
163
- end
164
-
165
- def _reduce_10(val, _values)
166
- Star.new(Symbol.new(val.last, Symbol::GREEDY_EXP))
7
+ module Journey # :nodoc:
8
+ class Parser # :nodoc:
9
+ include Journey::Nodes
10
+
11
+ def self.parse(string)
12
+ new.parse string
13
+ end
14
+
15
+ def initialize
16
+ @scanner = Scanner.new
17
+ @next_token = nil
18
+ end
19
+
20
+ def parse(string)
21
+ @scanner.scan_setup(string)
22
+ advance_token
23
+ do_parse
24
+ end
25
+
26
+ private
27
+ def advance_token
28
+ @next_token = @scanner.next_token
29
+ end
30
+
31
+ def do_parse
32
+ parse_expressions
33
+ end
34
+
35
+ def parse_expressions
36
+ node = parse_expression
37
+
38
+ while @next_token
39
+ case @next_token
40
+ when :RPAREN
41
+ break
42
+ when :OR
43
+ node = parse_or(node)
44
+ else
45
+ node = Cat.new(node, parse_expressions)
46
+ end
47
+ end
48
+
49
+ node
50
+ end
51
+
52
+ def parse_or(lhs)
53
+ advance_token
54
+ node = parse_expression
55
+ Or.new([lhs, node])
56
+ end
57
+
58
+ def parse_expression
59
+ if @next_token == :STAR
60
+ parse_star
61
+ elsif @next_token == :LPAREN
62
+ parse_group
63
+ else
64
+ parse_terminal
65
+ end
66
+ end
67
+
68
+ def parse_star
69
+ node = Star.new(Symbol.new(@scanner.last_string, Symbol::GREEDY_EXP))
70
+ advance_token
71
+ node
72
+ end
73
+
74
+ def parse_group
75
+ advance_token
76
+ node = parse_expressions
77
+ if @next_token == :RPAREN
78
+ node = Group.new(node)
79
+ advance_token
80
+ node
81
+ else
82
+ raise ArgumentError, "missing right parenthesis."
83
+ end
84
+ end
85
+
86
+ def parse_terminal
87
+ node = case @next_token
88
+ when :SYMBOL
89
+ Symbol.new(@scanner.last_string)
90
+ when :LITERAL
91
+ Literal.new(@scanner.last_literal)
92
+ when :SLASH
93
+ Slash.new("/")
94
+ when :DOT
95
+ Dot.new(".")
96
+ end
97
+
98
+ advance_token
99
+ node
100
+ end
101
+ end
102
+ end
167
103
  end
168
-
169
- # reduce 11 omitted
170
-
171
- # reduce 12 omitted
172
-
173
- # reduce 13 omitted
174
-
175
- # reduce 14 omitted
176
-
177
- def _reduce_15(val, _values)
178
- Slash.new(val.first)
179
- end
180
-
181
- def _reduce_16(val, _values)
182
- Symbol.new(val.first)
183
- end
184
-
185
- def _reduce_17(val, _values)
186
- Literal.new(val.first)
187
- end
188
-
189
- def _reduce_18(val, _values)
190
- Dot.new(val.first)
191
- end
192
-
193
- def _reduce_none(val, _values)
194
- val[0]
195
- end
196
-
197
- end # class Parser
198
- end # module Journey
199
- end # module ActionDispatch
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionDispatch
4
6
  module Journey # :nodoc:
5
7
  module Path # :nodoc:
@@ -32,7 +34,8 @@ module ActionDispatch
32
34
  end
33
35
 
34
36
  def requirements_anchored?
35
- # each required param must not be surrounded by a literal, otherwise it isn't simple to chunk-match the url piecemeal
37
+ # each required param must not be surrounded by a literal, otherwise it isn't
38
+ # simple to chunk-match the url piecemeal
36
39
  terminals = ast.terminals
37
40
 
38
41
  terminals.each_with_index { |s, index|