curlybars 0.9.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/curlybars.rb +108 -0
- data/lib/curlybars/configuration.rb +41 -0
- data/lib/curlybars/dependency_tracker.rb +8 -0
- data/lib/curlybars/error/base.rb +18 -0
- data/lib/curlybars/error/compile.rb +11 -0
- data/lib/curlybars/error/lex.rb +22 -0
- data/lib/curlybars/error/parse.rb +41 -0
- data/lib/curlybars/error/presenter/not_found.rb +23 -0
- data/lib/curlybars/error/render.rb +11 -0
- data/lib/curlybars/error/validate.rb +18 -0
- data/lib/curlybars/lexer.rb +60 -0
- data/lib/curlybars/method_whitelist.rb +69 -0
- data/lib/curlybars/node/block_helper_else.rb +108 -0
- data/lib/curlybars/node/boolean.rb +24 -0
- data/lib/curlybars/node/each_else.rb +69 -0
- data/lib/curlybars/node/if_else.rb +33 -0
- data/lib/curlybars/node/item.rb +31 -0
- data/lib/curlybars/node/literal.rb +28 -0
- data/lib/curlybars/node/option.rb +25 -0
- data/lib/curlybars/node/output.rb +24 -0
- data/lib/curlybars/node/partial.rb +24 -0
- data/lib/curlybars/node/path.rb +137 -0
- data/lib/curlybars/node/root.rb +29 -0
- data/lib/curlybars/node/string.rb +24 -0
- data/lib/curlybars/node/template.rb +32 -0
- data/lib/curlybars/node/text.rb +24 -0
- data/lib/curlybars/node/unless_else.rb +33 -0
- data/lib/curlybars/node/variable.rb +34 -0
- data/lib/curlybars/node/with_else.rb +54 -0
- data/lib/curlybars/parser.rb +183 -0
- data/lib/curlybars/position.rb +7 -0
- data/lib/curlybars/presenter.rb +288 -0
- data/lib/curlybars/processor/tilde.rb +31 -0
- data/lib/curlybars/processor/token_factory.rb +9 -0
- data/lib/curlybars/railtie.rb +18 -0
- data/lib/curlybars/rendering_support.rb +222 -0
- data/lib/curlybars/safe_buffer.rb +11 -0
- data/lib/curlybars/template_handler.rb +93 -0
- data/lib/curlybars/version.rb +3 -0
- data/spec/acceptance/application_layout_spec.rb +60 -0
- data/spec/acceptance/collection_blocks_spec.rb +28 -0
- data/spec/acceptance/global_helper_spec.rb +25 -0
- data/spec/curlybars/configuration_spec.rb +57 -0
- data/spec/curlybars/error/base_spec.rb +41 -0
- data/spec/curlybars/error/compile_spec.rb +19 -0
- data/spec/curlybars/error/lex_spec.rb +25 -0
- data/spec/curlybars/error/parse_spec.rb +74 -0
- data/spec/curlybars/error/render_spec.rb +19 -0
- data/spec/curlybars/error/validate_spec.rb +19 -0
- data/spec/curlybars/lexer_spec.rb +466 -0
- data/spec/curlybars/method_whitelist_spec.rb +168 -0
- data/spec/curlybars/processor/tilde_spec.rb +60 -0
- data/spec/curlybars/rendering_support_spec.rb +426 -0
- data/spec/curlybars/safe_buffer_spec.rb +46 -0
- data/spec/curlybars/template_handler_spec.rb +222 -0
- data/spec/integration/cache_spec.rb +124 -0
- data/spec/integration/comment_spec.rb +60 -0
- data/spec/integration/exception_spec.rb +31 -0
- data/spec/integration/node/block_helper_else_spec.rb +422 -0
- data/spec/integration/node/each_else_spec.rb +204 -0
- data/spec/integration/node/each_spec.rb +291 -0
- data/spec/integration/node/escape_spec.rb +27 -0
- data/spec/integration/node/helper_spec.rb +176 -0
- data/spec/integration/node/if_else_spec.rb +129 -0
- data/spec/integration/node/if_spec.rb +143 -0
- data/spec/integration/node/output_spec.rb +68 -0
- data/spec/integration/node/partial_spec.rb +66 -0
- data/spec/integration/node/path_spec.rb +286 -0
- data/spec/integration/node/root_spec.rb +15 -0
- data/spec/integration/node/template_spec.rb +86 -0
- data/spec/integration/node/unless_else_spec.rb +129 -0
- data/spec/integration/node/unless_spec.rb +130 -0
- data/spec/integration/node/with_spec.rb +116 -0
- data/spec/integration/processor/tilde_spec.rb +38 -0
- data/spec/integration/processors_spec.rb +30 -0
- metadata +358 -0
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'curlybars/error/compile'
|
2
|
+
|
3
|
+
module Curlybars
|
4
|
+
module Node
|
5
|
+
BlockHelperElse = Struct.new(:helper, :arguments, :options, :helper_template, :else_template, :helperclose, :position) do
|
6
|
+
def compile
|
7
|
+
check_open_and_close_elements(helper, helperclose, Curlybars::Error::Compile)
|
8
|
+
|
9
|
+
compiled_arguments = arguments.map do |argument|
|
10
|
+
"arguments.push(rendering.cached_call(#{argument.compile}))"
|
11
|
+
end.join("\n")
|
12
|
+
|
13
|
+
compiled_options = options.map do |option|
|
14
|
+
"options.merge!(#{option.compile})"
|
15
|
+
end.join("\n")
|
16
|
+
|
17
|
+
# NOTE: the following is a heredoc string, representing the ruby code fragment
|
18
|
+
# outputted by this node.
|
19
|
+
<<-RUBY
|
20
|
+
options = ::ActiveSupport::HashWithIndifferentAccess.new
|
21
|
+
#{compiled_options}
|
22
|
+
|
23
|
+
arguments = []
|
24
|
+
#{compiled_arguments}
|
25
|
+
|
26
|
+
helper = #{helper.compile}
|
27
|
+
helper_position = rendering.position(#{helper.position.line_number},
|
28
|
+
#{helper.position.line_offset})
|
29
|
+
|
30
|
+
options[:fn] = ->(**vars) do
|
31
|
+
variables.push(vars.symbolize_keys)
|
32
|
+
outer_buffer = buffer
|
33
|
+
begin
|
34
|
+
buffer = ::Curlybars::SafeBuffer.new
|
35
|
+
#{helper_template.compile}
|
36
|
+
buffer
|
37
|
+
ensure
|
38
|
+
buffer = outer_buffer
|
39
|
+
variables.pop
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
options[:inverse] = ->(**vars) do
|
44
|
+
variables.push(vars.symbolize_keys)
|
45
|
+
outer_buffer = buffer
|
46
|
+
begin
|
47
|
+
buffer = ::Curlybars::SafeBuffer.new
|
48
|
+
#{else_template.compile}
|
49
|
+
buffer
|
50
|
+
ensure
|
51
|
+
buffer = outer_buffer
|
52
|
+
variables.pop
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
options[:this] = contexts.last
|
57
|
+
|
58
|
+
result = rendering.call(helper, #{helper.path.inspect}, helper_position,
|
59
|
+
arguments, options, &options[:fn])
|
60
|
+
|
61
|
+
unless rendering.presenter?(result) || rendering.presenter_collection?(result)
|
62
|
+
buffer.concat(result.to_s)
|
63
|
+
end
|
64
|
+
RUBY
|
65
|
+
end
|
66
|
+
|
67
|
+
def validate(branches)
|
68
|
+
check_open_and_close_elements(helper, helperclose, Curlybars::Error::Validate)
|
69
|
+
|
70
|
+
if helper.leaf?(branches)
|
71
|
+
if arguments.any? || options.any?
|
72
|
+
message = "#{helper.path} doesn't accept any arguments or options"
|
73
|
+
Curlybars::Error::Validate.new('invalid_signature', message, helper.position)
|
74
|
+
end
|
75
|
+
elsif helper.helper?(branches)
|
76
|
+
[
|
77
|
+
helper_template.validate(branches),
|
78
|
+
else_template.validate(branches),
|
79
|
+
arguments.map { |argument| argument.validate_as_value(branches) },
|
80
|
+
options.map { |option| option.validate(branches) }
|
81
|
+
]
|
82
|
+
else
|
83
|
+
message = "#{helper.path} must be allowed as helper or leaf"
|
84
|
+
Curlybars::Error::Validate.new('invalid_block_helper', message, helper.position)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def cache_key
|
89
|
+
[
|
90
|
+
helper,
|
91
|
+
arguments,
|
92
|
+
options,
|
93
|
+
helper_template,
|
94
|
+
else_template,
|
95
|
+
helperclose
|
96
|
+
].flatten.map(&:cache_key).push(self.class.name).join("/")
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def check_open_and_close_elements(helper, helperclose, error_class)
|
102
|
+
return unless helper.path != helperclose.path
|
103
|
+
message = "block `#{helper.path}` cannot be closed by `#{helperclose.path}`"
|
104
|
+
raise error_class.new('closing_tag_mismatch', message, helperclose.position)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,24 @@
|
|
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)
|
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
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Curlybars
|
2
|
+
module Node
|
3
|
+
EachElse = Struct.new(:path, :each_template, :else_template, :position) 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
|
+
collection = rendering.cached_call(#{path.compile})
|
9
|
+
|
10
|
+
if rendering.to_bool(collection)
|
11
|
+
position = rendering.position(#{position.line_number}, #{position.line_offset})
|
12
|
+
template_cache_key = '#{each_template.cache_key}'
|
13
|
+
|
14
|
+
collection = rendering.coerce_to_hash!(collection, #{path.path.inspect}, position)
|
15
|
+
collection.each.with_index.map do |key_and_presenter, index|
|
16
|
+
rendering.check_timeout!
|
17
|
+
rendering.optional_presenter_cache(key_and_presenter[1], template_cache_key, buffer) do |buffer|
|
18
|
+
begin
|
19
|
+
contexts.push(key_and_presenter[1])
|
20
|
+
variables.push({
|
21
|
+
index: index,
|
22
|
+
key: key_and_presenter[0],
|
23
|
+
first: index == 0,
|
24
|
+
last: index == (collection.length - 1),
|
25
|
+
})
|
26
|
+
#{each_template.compile}
|
27
|
+
ensure
|
28
|
+
variables.pop
|
29
|
+
contexts.pop
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
else
|
34
|
+
#{else_template.compile}
|
35
|
+
end
|
36
|
+
RUBY
|
37
|
+
end
|
38
|
+
|
39
|
+
def validate(branches)
|
40
|
+
resolved = path.resolve_and_check!(branches, check_type: :presenter_collection)
|
41
|
+
sub_tree = resolved.first
|
42
|
+
|
43
|
+
each_template_errors = begin
|
44
|
+
branches.push(sub_tree)
|
45
|
+
each_template.validate(branches)
|
46
|
+
ensure
|
47
|
+
branches.pop
|
48
|
+
end
|
49
|
+
|
50
|
+
else_template_errors = else_template.validate(branches)
|
51
|
+
|
52
|
+
[
|
53
|
+
each_template_errors,
|
54
|
+
else_template_errors
|
55
|
+
]
|
56
|
+
rescue Curlybars::Error::Validate => path_error
|
57
|
+
path_error
|
58
|
+
end
|
59
|
+
|
60
|
+
def cache_key
|
61
|
+
[
|
62
|
+
path,
|
63
|
+
each_template,
|
64
|
+
else_template
|
65
|
+
].map(&:cache_key).push(self.class.name).join("/")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Curlybars
|
2
|
+
module Node
|
3
|
+
IfElse = Struct.new(:expression, :if_template, :else_template) 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
|
+
if rendering.to_bool(rendering.cached_call(#{expression.compile}))
|
9
|
+
#{if_template.compile}
|
10
|
+
else
|
11
|
+
#{else_template.compile}
|
12
|
+
end
|
13
|
+
RUBY
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate(branches)
|
17
|
+
[
|
18
|
+
expression.validate(branches),
|
19
|
+
if_template.validate(branches),
|
20
|
+
else_template.validate(branches)
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
def cache_key
|
25
|
+
[
|
26
|
+
expression,
|
27
|
+
if_template,
|
28
|
+
else_template
|
29
|
+
].map(&:cache_key).push(self.class.name).join("/")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Curlybars
|
2
|
+
module Node
|
3
|
+
Item = Struct.new(:item) 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
|
+
::Module.new do
|
9
|
+
def self.exec(contexts, rendering, variables, buffer)
|
10
|
+
rendering.check_timeout!
|
11
|
+
#{item.compile}
|
12
|
+
end
|
13
|
+
end.exec(contexts, rendering, variables, buffer)
|
14
|
+
RUBY
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate(branches)
|
18
|
+
catch(:skip_item_validation) do
|
19
|
+
item.validate(branches)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def cache_key
|
24
|
+
[
|
25
|
+
item.cache_key,
|
26
|
+
self.class.name
|
27
|
+
].join("/")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Curlybars
|
2
|
+
module Node
|
3
|
+
Literal = Struct.new(:literal) 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
|
+
->() { #{literal} }
|
9
|
+
RUBY
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate(branches)
|
13
|
+
# Nothing to validate here.
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate_as_value(branches)
|
17
|
+
# It is always a value.
|
18
|
+
end
|
19
|
+
|
20
|
+
def cache_key
|
21
|
+
[
|
22
|
+
literal.to_s,
|
23
|
+
self.class.name
|
24
|
+
].join("/")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Curlybars
|
2
|
+
module Node
|
3
|
+
Option = Struct.new(:key, :expression) 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
|
+
{ #{key.to_s.inspect} => rendering.cached_call(#{expression.compile}) }
|
9
|
+
RUBY
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate(branches)
|
13
|
+
expression.validate_as_value(branches)
|
14
|
+
end
|
15
|
+
|
16
|
+
def cache_key
|
17
|
+
[
|
18
|
+
key,
|
19
|
+
expression.cache_key,
|
20
|
+
self.class.name
|
21
|
+
].join("/")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Curlybars
|
2
|
+
module Node
|
3
|
+
Output = Struct.new(:value) 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
|
+
buffer.concat(rendering.cached_call(#{value.compile}).to_s)
|
9
|
+
RUBY
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate(branches)
|
13
|
+
value.validate(branches)
|
14
|
+
end
|
15
|
+
|
16
|
+
def cache_key
|
17
|
+
[
|
18
|
+
value.cache_key,
|
19
|
+
self.class.name
|
20
|
+
].join("/")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Curlybars
|
2
|
+
module Node
|
3
|
+
Partial = Struct.new(:path) 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
|
+
buffer.concat(rendering.cached_call(#{path.compile}).to_s)
|
9
|
+
RUBY
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate(branches)
|
13
|
+
path.validate(branches, check_type: :partial)
|
14
|
+
end
|
15
|
+
|
16
|
+
def cache_key
|
17
|
+
[
|
18
|
+
path.cache_key,
|
19
|
+
self.class.name
|
20
|
+
].join("/")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module Curlybars
|
2
|
+
module Node
|
3
|
+
Path = Struct.new(:path, :position) 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
|
+
rendering.path(
|
9
|
+
#{path.inspect},
|
10
|
+
rendering.position(#{position.line_number}, #{position.line_offset})
|
11
|
+
)
|
12
|
+
RUBY
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate_as_value(branches)
|
16
|
+
validate(branches, check_type: :leaf)
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate(branches, check_type: :anything)
|
20
|
+
resolve_and_check!(branches, check_type: check_type)
|
21
|
+
[]
|
22
|
+
rescue Curlybars::Error::Validate => path_error
|
23
|
+
path_error
|
24
|
+
end
|
25
|
+
|
26
|
+
def resolve_and_check!(branches, check_type: :anything)
|
27
|
+
value = resolve(branches)
|
28
|
+
|
29
|
+
check_type_of(branches, check_type)
|
30
|
+
|
31
|
+
value
|
32
|
+
end
|
33
|
+
|
34
|
+
def presenter?(branches)
|
35
|
+
resolve(branches).is_a?(Hash)
|
36
|
+
end
|
37
|
+
|
38
|
+
def presenter_collection?(branches)
|
39
|
+
value = resolve(branches)
|
40
|
+
value.is_a?(Array) && value.first.is_a?(Hash)
|
41
|
+
end
|
42
|
+
|
43
|
+
def leaf?(branches)
|
44
|
+
value = resolve(branches)
|
45
|
+
value.nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
def partial?(branches)
|
49
|
+
resolve(branches) == :partial
|
50
|
+
end
|
51
|
+
|
52
|
+
def helper?(branches)
|
53
|
+
resolve(branches) == :helper
|
54
|
+
end
|
55
|
+
|
56
|
+
def resolve(branches)
|
57
|
+
@value ||= begin
|
58
|
+
return :helper if global_helpers_dependency_tree.key?(path.to_sym)
|
59
|
+
|
60
|
+
path_split_by_slashes = path.split('/')
|
61
|
+
backward_steps_on_branches = path_split_by_slashes.count - 1
|
62
|
+
base_tree_position = branches.length - backward_steps_on_branches
|
63
|
+
|
64
|
+
throw :skip_item_validation unless base_tree_position > 0
|
65
|
+
|
66
|
+
base_tree_index = base_tree_position - 1
|
67
|
+
base_tree = branches[base_tree_index]
|
68
|
+
|
69
|
+
dotted_path_side = path_split_by_slashes.last
|
70
|
+
|
71
|
+
offset_adjustment = 0
|
72
|
+
dotted_path_side.split(/\./).map(&:to_sym).inject(base_tree) do |sub_tree, step|
|
73
|
+
begin
|
74
|
+
if step == :this
|
75
|
+
next sub_tree
|
76
|
+
elsif step == :length && (sub_tree.is_a?(Array) && sub_tree.first.is_a?(Hash))
|
77
|
+
next nil # :length is synthesised leaf
|
78
|
+
elsif !(sub_tree.is_a?(Hash) && sub_tree.key?(step))
|
79
|
+
message = step.to_s == path ? "'#{path}' does not exist" : "not possible to access `#{step}` in `#{path}`"
|
80
|
+
raise Curlybars::Error::Validate.new('unallowed_path', message, position, offset_adjustment, path: path, step: step)
|
81
|
+
end
|
82
|
+
|
83
|
+
sub_tree[step]
|
84
|
+
ensure
|
85
|
+
offset_adjustment += step.length + 1 # '1' is the length of the dot
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def cache_key
|
92
|
+
[
|
93
|
+
path,
|
94
|
+
self.class.name
|
95
|
+
].join("/")
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
# TODO: extract me away
|
101
|
+
def global_helpers_dependency_tree
|
102
|
+
@global_helpers_dependency_tree ||= begin
|
103
|
+
classes = Curlybars.configuration.global_helpers_provider_classes
|
104
|
+
classes.map(&:dependency_tree).inject({}, :merge)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def check_type_of(branches, check_type)
|
109
|
+
case check_type
|
110
|
+
when :presenter
|
111
|
+
return if presenter?(branches)
|
112
|
+
message = "`#{path}` must resolve to a presenter"
|
113
|
+
raise Curlybars::Error::Validate.new('not_a_presenter', message, position)
|
114
|
+
when :presenter_collection
|
115
|
+
return if presenter_collection?(branches)
|
116
|
+
message = "`#{path}` must resolve to a collection of presenters"
|
117
|
+
raise Curlybars::Error::Validate.new('not_a_presenter_collection', message, position)
|
118
|
+
when :leaf
|
119
|
+
return if leaf?(branches)
|
120
|
+
message = "`#{path}` cannot resolve to a component"
|
121
|
+
raise Curlybars::Error::Validate.new('not_a_leaf', message, position)
|
122
|
+
when :partial
|
123
|
+
return if partial?(branches)
|
124
|
+
message = "`#{path}` cannot resolve to a partial"
|
125
|
+
raise Curlybars::Error::Validate.new('not_a_partial', message, position)
|
126
|
+
when :helper
|
127
|
+
return if helper?(branches)
|
128
|
+
message = "`#{path}` cannot resolve to a helper"
|
129
|
+
raise Curlybars::Error::Validate.new('not_a_helper', message, position)
|
130
|
+
when :anything
|
131
|
+
else
|
132
|
+
raise "invalid type `#{check_type}`"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|