curlybars 1.16.1.pre.3 → 1.16.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8152eb9d4e5789fce89e656283b0ae7be78799bafcd9755c99d793674a01d9a
4
- data.tar.gz: 57102435a47d352a31c16d994e36bd61436b777e0e98409355bc31161045a44d
3
+ metadata.gz: 746a0625058bd9a2bca9ebf655c36f7cbd7e11e43000a051f4a76516ce73150b
4
+ data.tar.gz: f631902fba5a77cce57a36472636b99a5c03450dfbe5943e058c92b7c09e1d07
5
5
  SHA512:
6
- metadata.gz: 797b775e410fff90804ecfad939a0f31add15dc199a4b3221dba6ab4d9ee165134b07c40b90d6e16ea87f331ee80226d9ab0ae28823c8508a0dd7c8c5671a57f
7
- data.tar.gz: 5b2f6719689b4c047d3fa8a0b31dccd92457d5147eb40a0092331eb7b2f349297bdebd0b15b04702d0808bf154b6bbe69f9c2a7a83ddc71df80aae2fa3dbce0b
6
+ metadata.gz: c0fb5fb5398bf4643f679fdb07403de92892ee84efb70bae6a689297251e1ff9e79311b1c7711a6ba6a247a84eac945d735f72deacd8a555c9cd8ebfd75e9d81
7
+ data.tar.gz: ac273a2a866a2634c6d17ebf4a4bfd32b656c765e896214e2f3d6d2d49069232503e96bdc04a23b698d8f569cf5d368f5ab736699e280e404b9765bb370b4132
@@ -178,4 +178,6 @@ def main
178
178
  end
179
179
  end
180
180
 
181
+ # simplecov:disable
181
182
  main if __FILE__ == $PROGRAM_NAME
183
+ # simplecov:enable
@@ -13,6 +13,7 @@ module Curlybars
13
13
 
14
14
  def self.reset
15
15
  @configuration = Configuration.new
16
+ @global_helpers_dependency_tree = nil
16
17
  end
17
18
 
18
19
  class Configuration
@@ -12,6 +12,7 @@ module Curlybars
12
12
  template_cache_key = '#{each_template.cache_key}'
13
13
 
14
14
  collection = rendering.coerce_to_hash!(collection, #{collection_path.path.inspect}, position)
15
+ rendering.check_nesting_not_too_deep(position)
15
16
  collection.each.with_index.map do |key_and_presenter, index|
16
17
  rendering.check_timeout!
17
18
  rendering.optional_presenter_cache(key_and_presenter[1], template_cache_key, buffer) do |buffer|
@@ -168,11 +168,6 @@ module Curlybars
168
168
 
169
169
  message = "`#{path}` cannot resolve to a helper"
170
170
  raise Curlybars::Error::Validate.new('not_a_helper', message, position)
171
- when :not_helper
172
- return unless helper?(branches)
173
-
174
- message = "`#{path}` resolves to a helper"
175
- raise Curlybars::Error::Validate.new('is_a_helper', message, position)
176
171
  when :anything
177
172
  else
178
173
  raise "invalid type `#{check_type}`"
@@ -63,22 +63,19 @@ module Curlybars
63
63
 
64
64
  type = node.resolve_and_check!(branches, check_type: check_type)
65
65
 
66
- if helper?(type)
67
- if generic_helper?(type)
68
- is_collection = type.last.is_a?(Array)
69
- return infer_generic_helper_type!(branches, is_collection: is_collection)
70
- end
71
-
72
- return type.last
66
+ if generic_helper?(type)
67
+ is_collection = type.last.is_a?(Array)
68
+ infer_generic_helper_type!(branches, is_collection: is_collection)
69
+ elsif helper?(type)
70
+ type.last
71
+ else
72
+ type
73
73
  end
74
-
75
- type
76
74
  end
77
75
 
78
76
  def generic_helper?(type)
79
- return false unless type.is_a?(Array)
77
+ return false unless helper?(type)
80
78
  return false unless type.size == 2
81
- return false unless type.first == :helper
82
79
 
83
80
  type.last == [{}] || type.last == {}
84
81
  end
@@ -9,11 +9,6 @@ module Curlybars
9
9
  <<-RUBY
10
10
  ::Module.new do
11
11
  def self.exec(contexts, rendering, variables, buffer)
12
- unless contexts.length < ::Curlybars.configuration.nesting_limit
13
- message = "Nesting too deep"
14
- position = rendering.position(#{position.line_number}, #{position.line_offset})
15
- raise ::Curlybars::Error::Render.new('nesting_too_deep', message, position)
16
- end
17
12
  #{compiled_items}
18
13
  end
19
14
  end.exec(contexts, rendering, variables, buffer)
@@ -10,6 +10,7 @@ module Curlybars
10
10
  if rendering.to_bool(compiled_path)
11
11
  position = rendering.position(#{position.line_number}, #{position.line_offset})
12
12
  rendering.check_context_is_presenter(compiled_path, #{presenter_path.path.inspect}, position)
13
+ rendering.check_nesting_not_too_deep(position)
13
14
 
14
15
  contexts.push(compiled_path)
15
16
  begin
@@ -82,8 +82,7 @@ module Curlybars
82
82
  stack.pop unless stack.empty?
83
83
  end
84
84
 
85
- remaining_segments = full_path.empty? ? [] : full_path.split('.')
86
- stack + remaining_segments
85
+ stack + full_path.split('.')
87
86
  end
88
87
 
89
88
  def handle_block_helper(node, context_stack)
@@ -31,6 +31,16 @@ module Curlybars
31
31
  raise ::Curlybars::Error::Render.new('timeout', message, nil)
32
32
  end
33
33
 
34
+ # Called before a #with or #each block pushes its context. The contexts
35
+ # stack starts with the root presenter, so its length is one more than
36
+ # the number of enclosing #with and #each blocks.
37
+ def check_nesting_not_too_deep(position)
38
+ return if contexts.length <= Curlybars.configuration.nesting_limit
39
+
40
+ message = "Nesting too deep (> #{Curlybars.configuration.nesting_limit} levels)"
41
+ raise Curlybars::Error::Render.new('nesting_too_deep', message, position)
42
+ end
43
+
34
44
  def check_context_is_presenter(context, path, position)
35
45
  return if presenter?(context)
36
46
 
@@ -257,8 +267,11 @@ module Curlybars
257
267
  raise Curlybars::Error::Render.new('unallowed_path', message, position)
258
268
  end
259
269
 
270
+ # Counts the dots after the final `/` in the path. Leading `../` segments
271
+ # move up the contexts stack rather than traversing, so they don't count.
260
272
  def check_traverse_not_too_deep(traverse, position)
261
- return unless traverse.count('.') > Curlybars.configuration.traversing_limit
273
+ dots = traverse.split('/').last.count('.')
274
+ return unless dots > Curlybars.configuration.traversing_limit
262
275
 
263
276
  message = "`#{traverse}` too deep"
264
277
  raise Curlybars::Error::Render.new('traverse_too_deep', message, position)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Curlybars
4
- VERSION = '1.16.1.pre.3'
4
+ VERSION = '1.16.1'
5
5
  end
data/lib/curlybars.rb CHANGED
@@ -29,7 +29,7 @@ module Curlybars
29
29
  cache_key = ["Curlybars.compile", Curlybars::VERSION, identifier, Digest::SHA256.hexdigest(source)]
30
30
 
31
31
  cache.fetch(cache_key) do
32
- ast(transformed_source(source), identifier, run_processors: true).compile
32
+ ast(transformed_source(source, identifier), identifier, run_processors: true).compile
33
33
  end
34
34
  end
35
35
 
@@ -76,7 +76,7 @@ module Curlybars
76
76
  # source - The source HBS String used to generate an AST.
77
77
  # identifier - The the file name of the template being checked (defaults to `nil`).
78
78
  def visit(visitor, source, identifier = nil)
79
- tree = ast(transformed_source(source), identifier, run_processors: true)
79
+ tree = ast(transformed_source(source, identifier), identifier, run_processors: true)
80
80
  visitor.accept(tree)
81
81
  end
82
82
 
@@ -99,7 +99,7 @@ module Curlybars
99
99
  #
100
100
  # Returns an Array of Curlybars::Node::Path instances that match the target path.
101
101
  def find(target_path, source, identifier = nil, role: nil)
102
- tree = ast(transformed_source(source), identifier, run_processors: true)
102
+ tree = ast(transformed_source(source, identifier), identifier, run_processors: true)
103
103
  finder = Curlybars::PathFinder.new(tree)
104
104
  finder.find(target_path, role: role)
105
105
  end
@@ -127,7 +127,7 @@ module Curlybars
127
127
 
128
128
  private
129
129
 
130
- def transformed_source(source)
130
+ def transformed_source(source, identifier)
131
131
  transformers = Curlybars.configuration.compiler_transformers
132
132
  transformers.inject(source) do |memo, transformer|
133
133
  transformer.transform(memo, identifier)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curlybars
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.1.pre.3
4
+ version: 1.16.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Libo Cannici
@@ -96,7 +96,6 @@ files:
96
96
  - lib/curlybars/lexer.rb
97
97
  - lib/curlybars/method_whitelist.rb
98
98
  - lib/curlybars/node/block_helper_else.rb
99
- - lib/curlybars/node/boolean.rb
100
99
  - lib/curlybars/node/each_else.rb
101
100
  - lib/curlybars/node/if_else.rb
102
101
  - lib/curlybars/node/item.rb
@@ -106,7 +105,6 @@ files:
106
105
  - lib/curlybars/node/partial.rb
107
106
  - lib/curlybars/node/path.rb
108
107
  - lib/curlybars/node/root.rb
109
- - lib/curlybars/node/string.rb
110
108
  - lib/curlybars/node/sub_expression.rb
111
109
  - lib/curlybars/node/template.rb
112
110
  - lib/curlybars/node/text.rb
@@ -140,7 +138,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
140
138
  requirements:
141
139
  - - ">="
142
140
  - !ruby/object:Gem::Version
143
- version: '3.2'
141
+ version: '3.3'
144
142
  required_rubygems_version: !ruby/object:Gem::Requirement
145
143
  requirements:
146
144
  - - ">="
@@ -1,24 +0,0 @@
1
- module Curlybars
2
- module Node
3
- Boolean = Struct.new(:boolean) do
4
- def compile
5
- # NOTE: the following is a heredoc string, representing the ruby code fragment
6
- # outputted by this node.
7
- <<-RUBY
8
- ->() { #{boolean} }
9
- RUBY
10
- end
11
-
12
- def validate(branches, context: nil)
13
- # Nothing to validate here.
14
- end
15
-
16
- def cache_key
17
- [
18
- boolean.to_s,
19
- self.class.name
20
- ].join("/")
21
- end
22
- end
23
- end
24
- end
@@ -1,24 +0,0 @@
1
- module Curlybars
2
- module Node
3
- String = Struct.new(:string) do
4
- def compile
5
- # NOTE: the following is a heredoc string, representing the ruby code fragment
6
- # outputted by this node.
7
- <<-RUBY
8
- ->() { #{string.inspect} }
9
- RUBY
10
- end
11
-
12
- def validate(branches, context: nil)
13
- # Nothing to validate here.
14
- end
15
-
16
- def cache_key
17
- [
18
- string,
19
- self.class.name
20
- ].join("/")
21
- end
22
- end
23
- end
24
- end