liquid 5.1.0 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +35 -0
  3. data/README.md +4 -4
  4. data/lib/liquid/block_body.rb +6 -6
  5. data/lib/liquid/condition.rb +7 -1
  6. data/lib/liquid/context.rb +6 -2
  7. data/lib/liquid/expression.rb +11 -10
  8. data/lib/liquid/forloop_drop.rb +44 -1
  9. data/lib/liquid/locales/en.yml +6 -5
  10. data/lib/liquid/partial_cache.rb +3 -3
  11. data/lib/liquid/registers.rb +51 -0
  12. data/lib/liquid/standardfilters.rb +463 -75
  13. data/lib/liquid/strainer_factory.rb +15 -10
  14. data/lib/liquid/strainer_template.rb +9 -0
  15. data/lib/liquid/tablerowloop_drop.rb +58 -1
  16. data/lib/liquid/tags/assign.rb +12 -8
  17. data/lib/liquid/tags/break.rb +8 -0
  18. data/lib/liquid/tags/capture.rb +13 -10
  19. data/lib/liquid/tags/case.rb +21 -0
  20. data/lib/liquid/tags/comment.rb +13 -0
  21. data/lib/liquid/tags/continue.rb +8 -9
  22. data/lib/liquid/tags/cycle.rb +12 -11
  23. data/lib/liquid/tags/decrement.rb +16 -17
  24. data/lib/liquid/tags/echo.rb +16 -9
  25. data/lib/liquid/tags/for.rb +22 -43
  26. data/lib/liquid/tags/if.rb +11 -9
  27. data/lib/liquid/tags/include.rb +15 -13
  28. data/lib/liquid/tags/increment.rb +16 -14
  29. data/lib/liquid/tags/inline_comment.rb +43 -0
  30. data/lib/liquid/tags/raw.rb +11 -0
  31. data/lib/liquid/tags/render.rb +29 -4
  32. data/lib/liquid/tags/table_row.rb +22 -0
  33. data/lib/liquid/tags/unless.rb +15 -4
  34. data/lib/liquid/template.rb +2 -3
  35. data/lib/liquid/variable.rb +4 -4
  36. data/lib/liquid/variable_lookup.rb +10 -7
  37. data/lib/liquid/version.rb +1 -1
  38. data/lib/liquid.rb +4 -4
  39. metadata +7 -121
  40. data/lib/liquid/register.rb +0 -6
  41. data/lib/liquid/static_registers.rb +0 -44
  42. data/test/fixtures/en_locale.yml +0 -9
  43. data/test/integration/assign_test.rb +0 -117
  44. data/test/integration/blank_test.rb +0 -109
  45. data/test/integration/block_test.rb +0 -58
  46. data/test/integration/capture_test.rb +0 -58
  47. data/test/integration/context_test.rb +0 -636
  48. data/test/integration/document_test.rb +0 -21
  49. data/test/integration/drop_test.rb +0 -257
  50. data/test/integration/error_handling_test.rb +0 -272
  51. data/test/integration/expression_test.rb +0 -46
  52. data/test/integration/filter_test.rb +0 -189
  53. data/test/integration/hash_ordering_test.rb +0 -25
  54. data/test/integration/output_test.rb +0 -125
  55. data/test/integration/parsing_quirks_test.rb +0 -134
  56. data/test/integration/profiler_test.rb +0 -213
  57. data/test/integration/security_test.rb +0 -89
  58. data/test/integration/standard_filter_test.rb +0 -880
  59. data/test/integration/tag/disableable_test.rb +0 -59
  60. data/test/integration/tag_test.rb +0 -45
  61. data/test/integration/tags/break_tag_test.rb +0 -17
  62. data/test/integration/tags/continue_tag_test.rb +0 -17
  63. data/test/integration/tags/echo_test.rb +0 -13
  64. data/test/integration/tags/for_tag_test.rb +0 -466
  65. data/test/integration/tags/if_else_tag_test.rb +0 -190
  66. data/test/integration/tags/include_tag_test.rb +0 -269
  67. data/test/integration/tags/increment_tag_test.rb +0 -25
  68. data/test/integration/tags/liquid_tag_test.rb +0 -116
  69. data/test/integration/tags/raw_tag_test.rb +0 -34
  70. data/test/integration/tags/render_tag_test.rb +0 -213
  71. data/test/integration/tags/standard_tag_test.rb +0 -303
  72. data/test/integration/tags/statements_test.rb +0 -113
  73. data/test/integration/tags/table_row_test.rb +0 -66
  74. data/test/integration/tags/unless_else_tag_test.rb +0 -28
  75. data/test/integration/template_test.rb +0 -340
  76. data/test/integration/trim_mode_test.rb +0 -563
  77. data/test/integration/variable_test.rb +0 -138
  78. data/test/test_helper.rb +0 -207
  79. data/test/unit/block_unit_test.rb +0 -53
  80. data/test/unit/condition_unit_test.rb +0 -168
  81. data/test/unit/file_system_unit_test.rb +0 -37
  82. data/test/unit/i18n_unit_test.rb +0 -39
  83. data/test/unit/lexer_unit_test.rb +0 -53
  84. data/test/unit/parse_tree_visitor_test.rb +0 -261
  85. data/test/unit/parser_unit_test.rb +0 -84
  86. data/test/unit/partial_cache_unit_test.rb +0 -128
  87. data/test/unit/regexp_unit_test.rb +0 -46
  88. data/test/unit/static_registers_unit_test.rb +0 -156
  89. data/test/unit/strainer_factory_unit_test.rb +0 -100
  90. data/test/unit/strainer_template_unit_test.rb +0 -82
  91. data/test/unit/tag_unit_test.rb +0 -23
  92. data/test/unit/tags/case_tag_unit_test.rb +0 -12
  93. data/test/unit/tags/for_tag_unit_test.rb +0 -15
  94. data/test/unit/tags/if_tag_unit_test.rb +0 -10
  95. data/test/unit/template_factory_unit_test.rb +0 -12
  96. data/test/unit/template_unit_test.rb +0 -87
  97. data/test/unit/tokenizer_unit_test.rb +0 -62
  98. data/test/unit/variable_unit_test.rb +0 -164
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d033978c659ebc86ff6ae3a36adaa1a90b8f69580e0cd033eb9c2c669ff6d66d
4
- data.tar.gz: 5c440b450df6ac2c673b0a23091d97e497ccb8207a443b0b6011f2b1a9b6529b
3
+ metadata.gz: c8408df245a1cc22ee1154fe5387e3e41eb3c740f7277e7d3736c1863d387e47
4
+ data.tar.gz: 64549a58828fd7e9e0eb7310cb4371e75e64a7c3249fe9ebd021039e3334bba1
5
5
  SHA512:
6
- metadata.gz: 114697a0375800b4f67d7c216f9c56f823bb4468203632d45bda92bc597e0677acd0c4151c60f92fc121c2cd1b8d0d1c18d2482f1265acb62dbf190f12773d5c
7
- data.tar.gz: 3c013aef59a531829e202b73c4ce33d63ad5f58d763b7f2c610a3ff96fdab13fe2fdcf7e9401b63e09bb136fb1518ad69300b41114ebc1f076565c7d2953de78
6
+ metadata.gz: 29aaff16e3bc464712cdcac3aa205df943132198ef9568d46f4a123d327849f7ead7bd669a095eae0425581eb59ea08874ac38664bf9d8df00b0aa99917c7768
7
+ data.tar.gz: 9f6070c39733b7f4064f70676b1f886fc61070f3ba8921360b9c5fcdb09c217b3e58c3d59d8293b24b6c18e55899ed17552a2f867ea8eb95e7dee9a7deb29ae5
data/History.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # Liquid Change Log
2
2
 
3
+ ## 5.4.0 2022-07-29
4
+
5
+ ### Breaking Changes
6
+ * Drop support for end-of-life Ruby versions (2.5 and 2.6) (#1578) [Andy Waite]
7
+
8
+ ### Features
9
+ * Allow `#` to be used as an inline comment tag (#1498) [CP Clermont]
10
+
11
+ ### Fixes
12
+ * `PartialCache` now shares snippet cache with subcontexts by default (#1553) [Chris AtLee]
13
+ * Hash registers no longer leak into subcontexts as static registers (#1564) [Chris AtLee]
14
+ * Fix `ParseTreeVisitor` for `with` variable expressions in `Render` tag (#1596) [CP Clermont]
15
+
16
+ ### Changed
17
+ * Liquid::Context#registers now always returns a Liquid::Registers object, though supports the most used Hash functions for compatibility (#1553)
18
+
19
+ ## 5.3.0 2022-03-22
20
+
21
+ ### Fixes
22
+ * StandardFilter: Fix missing @context on iterations (#1525) [Thierry Joyal]
23
+ * Fix warning about block and default value in `static_registers.rb` (#1531) [Peter Zhu]
24
+
25
+ ### Deprecation
26
+ * Condition#evaluate to require mandatory context argument in Liquid 6.0.0 (#1527) [Thierry Joyal]
27
+
28
+ ## 5.2.0 2022-03-01
29
+
30
+ ### Features
31
+ * Add `remove_last`, and `replace_last` filters (#1422) [Anders Hagbard]
32
+ * Eagerly cache global filters (#1524) [Jean Boussier]
33
+
34
+ ### Fixes
35
+ * Fix some internal errors in filters from invalid input (#1476) [Dylan Thacker-Smith]
36
+ * Allow dash in filter kwarg name for consistency with Liquid::C (#1518) [CP Clermont]
37
+
3
38
  ## 5.1.0 / 2021-09-09
4
39
 
5
40
  ### Features
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  * [Contributing guidelines](CONTRIBUTING.md)
7
7
  * [Version history](History.md)
8
- * [Liquid documentation from Shopify](http://docs.shopify.com/themes/liquid-basics)
8
+ * [Liquid documentation from Shopify](https://shopify.dev/api/liquid)
9
9
  * [Liquid Wiki at GitHub](https://github.com/Shopify/liquid/wiki)
10
10
  * [Website](http://liquidmarkup.org/)
11
11
 
@@ -56,20 +56,20 @@ For standard use you can just pass it the content of a file and call render with
56
56
 
57
57
  Setting the error mode of Liquid lets you specify how strictly you want your templates to be interpreted.
58
58
  Normally the parser is very lax and will accept almost anything without error. Unfortunately this can make
59
- it very hard to debug and can lead to unexpected behaviour.
59
+ it very hard to debug and can lead to unexpected behaviour.
60
60
 
61
61
  Liquid also comes with a stricter parser that can be used when editing templates to give better error messages
62
62
  when templates are invalid. You can enable this new parser like this:
63
63
 
64
64
  ```ruby
65
65
  Liquid::Template.error_mode = :strict # Raises a SyntaxError when invalid syntax is used
66
- Liquid::Template.error_mode = :warn # Adds errors to template.errors but continues as normal
66
+ Liquid::Template.error_mode = :warn # Adds strict errors to template.errors but continues as normal
67
67
  Liquid::Template.error_mode = :lax # The default mode, accepts almost anything.
68
68
  ```
69
69
 
70
70
  If you want to set the error mode only on specific templates you can pass `:error_mode` as an option to `parse`:
71
71
  ```ruby
72
- Liquid::Template.parse(source, :error_mode => :strict)
72
+ Liquid::Template.parse(source, error_mode: :strict)
73
73
  ```
74
74
  This is useful for doing things like enabling strict mode only in the theme editor.
75
75
 
@@ -4,8 +4,8 @@ require 'English'
4
4
 
5
5
  module Liquid
6
6
  class BlockBody
7
- LiquidTagToken = /\A\s*(\w+)\s*(.*?)\z/o
8
- FullToken = /\A#{TagStart}#{WhitespaceControl}?(\s*)(\w+)(\s*)(.*?)#{WhitespaceControl}?#{TagEnd}\z/om
7
+ LiquidTagToken = /\A\s*(#{TagName})\s*(.*?)\z/o
8
+ FullToken = /\A#{TagStart}#{WhitespaceControl}?(\s*)(#{TagName})(\s*)(.*?)#{WhitespaceControl}?#{TagEnd}\z/om
9
9
  ContentOfVariable = /\A#{VariableStart}#{WhitespaceControl}?(.*?)#{WhitespaceControl}?#{VariableEnd}\z/om
10
10
  WhitespaceOrNothing = /\A\s*\z/
11
11
  TAGSTART = "{%"
@@ -37,7 +37,7 @@ module Liquid
37
37
 
38
38
  private def parse_for_liquid_tag(tokenizer, parse_context)
39
39
  while (token = tokenizer.shift)
40
- unless token.empty? || token =~ WhitespaceOrNothing
40
+ unless token.empty? || token.match?(WhitespaceOrNothing)
41
41
  unless token =~ LiquidTagToken
42
42
  # line isn't empty but didn't match tag syntax, yield and let the
43
43
  # caller raise a syntax error
@@ -150,7 +150,7 @@ module Liquid
150
150
  end
151
151
  parse_context.trim_whitespace = false
152
152
  @nodelist << token
153
- @blank &&= !!(token =~ WhitespaceOrNothing)
153
+ @blank &&= token.match?(WhitespaceOrNothing)
154
154
  end
155
155
  parse_context.line_number = tokenizer.line_number
156
156
  end
@@ -231,8 +231,8 @@ module Liquid
231
231
  end
232
232
 
233
233
  def create_variable(token, parse_context)
234
- token.scan(ContentOfVariable) do |content|
235
- markup = content.first
234
+ if token =~ ContentOfVariable
235
+ markup = Regexp.last_match(1)
236
236
  return Variable.new(markup, parse_context)
237
237
  end
238
238
  BlockBody.raise_missing_variable_terminator(token, parse_context)
@@ -61,7 +61,7 @@ module Liquid
61
61
  @child_condition = nil
62
62
  end
63
63
 
64
- def evaluate(context = Context.new)
64
+ def evaluate(context = deprecated_default_context)
65
65
  condition = self
66
66
  result = nil
67
67
  loop do
@@ -150,6 +150,12 @@ module Liquid
150
150
  end
151
151
  end
152
152
 
153
+ def deprecated_default_context
154
+ warn("DEPRECATION WARNING: Condition#evaluate without a context argument is deprecated" \
155
+ " and will be removed from Liquid 6.0.0.")
156
+ Context.new
157
+ end
158
+
153
159
  class ParseTreeVisitor < Liquid::ParseTreeVisitor
154
160
  def children
155
161
  [
@@ -28,7 +28,7 @@ module Liquid
28
28
 
29
29
  @static_environments = [static_environments].flat_map(&:freeze).freeze
30
30
  @scopes = [(outer_scope || {})]
31
- @registers = registers
31
+ @registers = registers.is_a?(Registers) ? registers : Registers.new(registers)
32
32
  @errors = []
33
33
  @partial = false
34
34
  @strict_variables = false
@@ -39,6 +39,10 @@ module Liquid
39
39
  @global_filter = nil
40
40
  @disabled_tags = {}
41
41
 
42
+ @registers.static[:cached_partials] ||= {}
43
+ @registers.static[:file_system] ||= Liquid::Template.file_system
44
+ @registers.static[:template_factory] ||= Liquid::TemplateFactory.new
45
+
42
46
  self.exception_renderer = Template.default_exception_renderer
43
47
  if rethrow_errors
44
48
  self.exception_renderer = Liquid::RAISE_EXCEPTION_LAMBDA
@@ -140,7 +144,7 @@ module Liquid
140
144
  self.class.build(
141
145
  resource_limits: resource_limits,
142
146
  static_environments: static_environments,
143
- registers: StaticRegisters.new(registers)
147
+ registers: Registers.new(registers)
144
148
  ).tap do |subcontext|
145
149
  subcontext.base_scope_depth = base_scope_depth + 1
146
150
  subcontext.exception_renderer = exception_renderer
@@ -10,21 +10,23 @@ module Liquid
10
10
  'empty' => ''
11
11
  }.freeze
12
12
 
13
- SINGLE_QUOTED_STRING = /\A\s*'(.*)'\s*\z/m
14
- DOUBLE_QUOTED_STRING = /\A\s*"(.*)"\s*\z/m
15
- INTEGERS_REGEX = /\A\s*(-?\d+)\s*\z/
16
- FLOATS_REGEX = /\A\s*(-?\d[\d\.]+)\s*\z/
13
+ INTEGERS_REGEX = /\A(-?\d+)\z/
14
+ FLOATS_REGEX = /\A(-?\d[\d\.]+)\z/
17
15
 
18
16
  # Use an atomic group (?>...) to avoid pathological backtracing from
19
17
  # malicious input as described in https://github.com/Shopify/liquid/issues/1357
20
- RANGES_REGEX = /\A\s*\(\s*(?>(\S+)\s*\.\.)\s*(\S+)\s*\)\s*\z/
18
+ RANGES_REGEX = /\A\(\s*(?>(\S+)\s*\.\.)\s*(\S+)\s*\)\z/
21
19
 
22
20
  def self.parse(markup)
21
+ return nil unless markup
22
+
23
+ markup = markup.strip
24
+ if (markup.start_with?('"') && markup.end_with?('"')) ||
25
+ (markup.start_with?("'") && markup.end_with?("'"))
26
+ return markup[1..-2]
27
+ end
28
+
23
29
  case markup
24
- when nil
25
- nil
26
- when SINGLE_QUOTED_STRING, DOUBLE_QUOTED_STRING
27
- Regexp.last_match(1)
28
30
  when INTEGERS_REGEX
29
31
  Regexp.last_match(1).to_i
30
32
  when RANGES_REGEX
@@ -32,7 +34,6 @@ module Liquid
32
34
  when FLOATS_REGEX
33
35
  Regexp.last_match(1).to_f
34
36
  else
35
- markup = markup.strip
36
37
  if LITERALS.key?(markup)
37
38
  LITERALS[markup]
38
39
  else
@@ -1,6 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Liquid
4
+ # @liquid_public_docs
5
+ # @liquid_type object
6
+ # @liquid_name forloop
7
+ # @liquid_summary
8
+ # Information about a parent [`for` loop](/api/liquid/tags#for).
4
9
  class ForloopDrop < Drop
5
10
  def initialize(name, length, parentloop)
6
11
  @name = name
@@ -9,33 +14,71 @@ module Liquid
9
14
  @index = 0
10
15
  end
11
16
 
12
- attr_reader :length, :parentloop
17
+ # @liquid_public_docs
18
+ # @liquid_name length
19
+ # @liquid_summary
20
+ # The total number of iterations in the loop.
21
+ # @liquid_return [number]
22
+ attr_reader :length
23
+
24
+ # @liquid_public_docs
25
+ # @liquid_name parentloop
26
+ # @liquid_summary
27
+ # The parent `forloop` object.
28
+ # @liquid_description
29
+ # If the current `for` loop isn't nested inside another `for` loop, then `nil` is returned.
30
+ # @liquid_return [forloop]
31
+ attr_reader :parentloop
13
32
 
14
33
  def name
15
34
  Usage.increment('forloop_drop_name')
16
35
  @name
17
36
  end
18
37
 
38
+ # @liquid_public_docs
39
+ # @liquid_summary
40
+ # The 1-based index of the current iteration.
41
+ # @liquid_return [number]
19
42
  def index
20
43
  @index + 1
21
44
  end
22
45
 
46
+ # @liquid_public_docs
47
+ # @liquid_summary
48
+ # The 0-based index of the current iteration.
49
+ # @liquid_return [number]
23
50
  def index0
24
51
  @index
25
52
  end
26
53
 
54
+ # @liquid_public_docs
55
+ # @liquid_summary
56
+ # The 1-based index of the current iteration, in reverse order.
57
+ # @liquid_return [number]
27
58
  def rindex
28
59
  @length - @index
29
60
  end
30
61
 
62
+ # @liquid_public_docs
63
+ # @liquid_summary
64
+ # The 0-based index of the current iteration, in reverse order.
65
+ # @liquid_return [number]
31
66
  def rindex0
32
67
  @length - @index - 1
33
68
  end
34
69
 
70
+ # @liquid_public_docs
71
+ # @liquid_summary
72
+ # Returns `true` if the current iteration is the first. Returns `false` if not.
73
+ # @liquid_return [boolean]
35
74
  def first
36
75
  @index == 0
37
76
  end
38
77
 
78
+ # @liquid_public_docs
79
+ # @liquid_summary
80
+ # Returns `true` if the current iteration is the last. Returns `false` if not.
81
+ # @liquid_return [boolean]
39
82
  def last
40
83
  @index == @length - 1
41
84
  end
@@ -13,15 +13,16 @@
13
13
  for_invalid_attribute: "Invalid attribute in for loop. Valid attributes are limit and offset"
14
14
  if: "Syntax Error in tag 'if' - Valid syntax: if [expression]"
15
15
  include: "Error in tag 'include' - Valid syntax: include '[template]' (with|for) [object|collection]"
16
- unknown_tag: "Unknown tag '%{tag}'"
16
+ inline_comment_invalid: "Syntax error in tag '#' - Each line of comments must be prefixed by the '#' character"
17
17
  invalid_delimiter: "'%{tag}' is not a valid delimiter for %{block_name} tags. use %{block_delimiter}"
18
+ render: "Syntax error in tag 'render' - Template name must be a quoted string"
19
+ table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"
20
+ tag_never_closed: "'%{block_name}' tag was never closed"
21
+ tag_termination: "Tag '%{token}' was not properly terminated with regexp: %{tag_end}"
18
22
  unexpected_else: "%{block_name} tag does not expect 'else' tag"
19
23
  unexpected_outer_tag: "Unexpected outer '%{tag}' tag"
20
- tag_termination: "Tag '%{token}' was not properly terminated with regexp: %{tag_end}"
24
+ unknown_tag: "Unknown tag '%{tag}'"
21
25
  variable_termination: "Variable '%{token}' was not properly terminated with regexp: %{tag_end}"
22
- tag_never_closed: "'%{block_name}' tag was never closed"
23
- table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"
24
- render: "Syntax error in tag 'render' - Template name must be a quoted string"
25
26
  argument:
26
27
  include: "Argument error in tag 'include' - Illegal template name"
27
28
  disabled:
@@ -3,16 +3,16 @@
3
3
  module Liquid
4
4
  class PartialCache
5
5
  def self.load(template_name, context:, parse_context:)
6
- cached_partials = (context.registers[:cached_partials] ||= {})
6
+ cached_partials = context.registers[:cached_partials]
7
7
  cached = cached_partials[template_name]
8
8
  return cached if cached
9
9
 
10
- file_system = (context.registers[:file_system] ||= Liquid::Template.file_system)
10
+ file_system = context.registers[:file_system]
11
11
  source = file_system.read_template_file(template_name)
12
12
 
13
13
  parse_context.partial = true
14
14
 
15
- template_factory = (context.registers[:template_factory] ||= Liquid::TemplateFactory.new)
15
+ template_factory = context.registers[:template_factory]
16
16
  template = template_factory.for(template_name)
17
17
 
18
18
  partial = template.parse(source, parse_context)
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Liquid
4
+ class Registers
5
+ attr_reader :static
6
+
7
+ def initialize(registers = {})
8
+ @static = registers.is_a?(Registers) ? registers.static : registers
9
+ @changes = {}
10
+ end
11
+
12
+ def []=(key, value)
13
+ @changes[key] = value
14
+ end
15
+
16
+ def [](key)
17
+ if @changes.key?(key)
18
+ @changes[key]
19
+ else
20
+ @static[key]
21
+ end
22
+ end
23
+
24
+ def delete(key)
25
+ @changes.delete(key)
26
+ end
27
+
28
+ UNDEFINED = Object.new
29
+
30
+ def fetch(key, default = UNDEFINED, &block)
31
+ if @changes.key?(key)
32
+ @changes.fetch(key)
33
+ elsif default != UNDEFINED
34
+ if block_given?
35
+ @static.fetch(key, &block)
36
+ else
37
+ @static.fetch(key, default)
38
+ end
39
+ else
40
+ @static.fetch(key, &block)
41
+ end
42
+ end
43
+
44
+ def key?(key)
45
+ @changes.key?(key) || @static.key?(key)
46
+ end
47
+ end
48
+
49
+ # Alias for backwards compatibility
50
+ StaticRegisters = Registers
51
+ end