curlybars 1.1.4 → 1.2.0

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: d425b234907702e06326b091a5dd9bea96d8a5494796e122ee77c56a79dd63ae
4
- data.tar.gz: c23f25a52b8c252ebb5aae349c01faefb7daff9e3e8a112e12f676249ad21f23
3
+ metadata.gz: 7aaafd32b96d9cdf8e9af98ebe3636fc14d4df85761eea4ac804d4b623e1d186
4
+ data.tar.gz: f177926ffc2cf7c9026a15f6ba7f43089cc9bab4da6e3318ab29a38003f4afdd
5
5
  SHA512:
6
- metadata.gz: 63657e140e3377cea321adfb20ff4ff1445e1bb00901e49e5f9b095f65b25b6d89cd2ef814e425f9abc7b0ed62d4d003c52459f8f7810943359f9160a9c64b7a
7
- data.tar.gz: 077401e926e847f7ee34df7ebce3a0323ae57c9ce6daa8454b67bc6ce6785807cfe96dfcdf406f8a7928f2d2ba992e344d8a7a8581f32c55e3f0459a82dd1f94
6
+ metadata.gz: 25125dc3e0887ee7878a09f29e96c56f6d863d4aea21cb4c37e226d032cd9b5006c6a512837a9893b95188308d72de426673c8d8815c6d942bdad1ca60032403
7
+ data.tar.gz: 2cc5791470872a77703979523e3de41a0db3491b8dd453628dc2c68ffe00dbef6374db91feb2da56ddae6edf75d5e6c21c5da3947048a3e320eb67da4d6a10c6
@@ -28,12 +28,7 @@ module Curlybars
28
28
  cache_key = ["Curlybars.compile", identifier, Digest::SHA256.hexdigest(source)]
29
29
 
30
30
  cache.fetch(cache_key) do
31
- transformers = Curlybars.configuration.compiler_transformers
32
- transformed_source = transformers.inject(source) do |memo, transformer|
33
- transformer.transform(memo, identifier)
34
- end
35
-
36
- ast(transformed_source, identifier, run_processors: true).compile
31
+ ast(transformed_source(source), identifier, run_processors: true).compile
37
32
  end
38
33
  end
39
34
 
@@ -72,6 +67,16 @@ module Curlybars
72
67
  errors.empty?
73
68
  end
74
69
 
70
+ # Visit nodes in the AST.
71
+ #
72
+ # visitor - An instance of a subclass of `Curlybars::Visitor`.
73
+ # source - The source HBS String used to generate an AST.
74
+ # identifier - The the file name of the template being checked (defaults to `nil`).
75
+ def visit(visitor, source, identifier = nil)
76
+ tree = ast(transformed_source(source), identifier, run_processors: true)
77
+ visitor.accept(tree)
78
+ end
79
+
75
80
  def cache
76
81
  @cache ||= ActiveSupport::Cache::MemoryStore.new
77
82
  end
@@ -80,6 +85,13 @@ module Curlybars
80
85
 
81
86
  private
82
87
 
88
+ def transformed_source(source)
89
+ transformers = Curlybars.configuration.compiler_transformers
90
+ transformers.inject(source) do |memo, transformer|
91
+ transformer.transform(memo, identifier)
92
+ end
93
+ end
94
+
83
95
  def ast(source, identifier, run_processors:)
84
96
  tokens = Curlybars::Lexer.lex(source, identifier)
85
97
 
@@ -118,3 +130,4 @@ require 'curlybars/template_handler'
118
130
  require 'curlybars/railtie' if defined?(Rails)
119
131
  require 'curlybars/presenter'
120
132
  require 'curlybars/method_whitelist'
133
+ require 'curlybars/visitor'
@@ -1,3 +1,3 @@
1
1
  module Curlybars
2
- VERSION = '1.1.4'.freeze
2
+ VERSION = '1.2.0'.freeze
3
3
  end
@@ -0,0 +1,100 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+
3
+ module Curlybars
4
+ class Visitor
5
+ attr_accessor :context
6
+
7
+ def initialize(context)
8
+ @context = context
9
+ end
10
+
11
+ def accept(node)
12
+ visit(node)
13
+ context
14
+ end
15
+
16
+ private
17
+
18
+ def visit(node)
19
+ class_name = node.class.name.to_s
20
+ return unless class_name.start_with?('Curlybars::Node')
21
+
22
+ method_name = class_name.demodulize.underscore
23
+ send("visit_#{method_name}", node)
24
+ end
25
+
26
+ def visit_block_helper_else(node)
27
+ node.arguments.each { |arg| visit(arg) }
28
+ node.options.each { |opt| visit(opt) }
29
+ visit(node.helper)
30
+ visit(node.helper_template)
31
+ visit(node.else_template)
32
+ end
33
+
34
+ def visit_boolean(_node)
35
+ end
36
+
37
+ def visit_each_else(node)
38
+ visit(node.path)
39
+ visit(node.each_template)
40
+ visit(node.else_template)
41
+ end
42
+
43
+ def visit_if_else(node)
44
+ visit(node.expression)
45
+ visit(node.if_template)
46
+ visit(node.else_template)
47
+ end
48
+
49
+ def visit_item(node)
50
+ visit(node.item)
51
+ end
52
+
53
+ def visit_literal(_node)
54
+ end
55
+
56
+ def visit_option(node)
57
+ visit(node.expression)
58
+ end
59
+
60
+ def visit_output(node)
61
+ visit(node.value)
62
+ end
63
+
64
+ def visit_partial(node)
65
+ visit(node.path)
66
+ end
67
+
68
+ def visit_path(_node)
69
+ end
70
+
71
+ def visit_root(node)
72
+ visit(node.template)
73
+ end
74
+
75
+ def visit_string(_node)
76
+ end
77
+
78
+ def visit_template(node)
79
+ node.items.each { |item| visit(item) }
80
+ end
81
+
82
+ def visit_text(_node)
83
+ end
84
+
85
+ def visit_unless_else(node)
86
+ visit(node.expression)
87
+ visit(node.unless_template)
88
+ visit(node.else_template)
89
+ end
90
+
91
+ def visit_variable(_node)
92
+ end
93
+
94
+ def visit_with_else(node)
95
+ visit(node.path)
96
+ visit(node.with_template)
97
+ visit(node.else_template)
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,146 @@
1
+ describe "visitor" do
2
+ let(:source) do
3
+ <<-HBS
4
+ {{#print_args_and_options 'first' 'second' key='value'}}
5
+ {{/print_args_and_options}}
6
+
7
+ {{#render_inverse}}
8
+ fn
9
+ {{else}}
10
+ inverse
11
+ {{@variable}}
12
+ {{/render_inverse}}
13
+
14
+ {{#each foo}}
15
+ top
16
+ {{#each bar}}
17
+ middle
18
+ {{#each baz}}
19
+ inner
20
+ {{else}}
21
+ inner inverse
22
+ {{/each}}
23
+ {{/each}}
24
+ {{/each}}
25
+
26
+ {{#if valid}}
27
+ if_template
28
+ {{#if bar}}
29
+ foo
30
+ {{else}}
31
+ qux
32
+ {{/if}}
33
+ {{/if}}
34
+
35
+ {{#if baz}}
36
+ qux
37
+ {{/if}}
38
+
39
+ {{> partial}}
40
+
41
+ {{user.avatar.url}}
42
+ {{#with this}}
43
+ {{user.avatar.url}}
44
+ {{/with}}
45
+
46
+ {{#unless things}}
47
+ hi
48
+ {{/unless}}
49
+ HBS
50
+ end
51
+
52
+ describe ".visit" do
53
+ it "visits BlockHelperElse nodes" do
54
+ visitor = counting_visitor_for(Curlybars::Node::BlockHelperElse)
55
+ output = Curlybars.visit(visitor, source)
56
+ expect(output).to eq(4)
57
+ end
58
+
59
+ it "visits EachElse nodes" do
60
+ visitor = counting_visitor_for(Curlybars::Node::EachElse)
61
+ output = Curlybars.visit(visitor, source)
62
+ expect(output).to eq(3)
63
+ end
64
+
65
+ it "visits IfElse nodes" do
66
+ visitor = counting_visitor_for(Curlybars::Node::IfElse)
67
+ output = Curlybars.visit(visitor, source)
68
+ expect(output).to eq(3)
69
+ end
70
+
71
+ it "visits Item nodes" do
72
+ visitor = counting_visitor_for(Curlybars::Node::Item)
73
+ output = Curlybars.visit(visitor, source)
74
+ expect(output).to eq(42)
75
+ end
76
+
77
+ it "visits Literal nodes" do
78
+ visitor = counting_visitor_for(Curlybars::Node::Literal)
79
+ output = Curlybars.visit(visitor, source)
80
+ expect(output).to eq(3)
81
+ end
82
+
83
+ it "visits Option nodes" do
84
+ visitor = counting_visitor_for(Curlybars::Node::Option)
85
+ output = Curlybars.visit(visitor, source)
86
+ expect(output).to eq(1)
87
+ end
88
+
89
+ it "visits Partial nodes" do
90
+ visitor = counting_visitor_for(Curlybars::Node::Partial)
91
+ output = Curlybars.visit(visitor, source)
92
+ expect(output).to eq(1)
93
+ end
94
+
95
+ it "visits Path nodes" do
96
+ visitor = counting_visitor_for(Curlybars::Node::Path)
97
+ output = Curlybars.visit(visitor, source)
98
+ expect(output).to eq(13)
99
+ end
100
+
101
+ it "visits Root nodes" do
102
+ visitor = counting_visitor_for(Curlybars::Node::Root)
103
+ output = Curlybars.visit(visitor, source)
104
+ expect(output).to eq(1)
105
+ end
106
+
107
+ it "visits Template nodes" do
108
+ visitor = counting_visitor_for(Curlybars::Node::Template)
109
+ output = Curlybars.visit(visitor, source)
110
+ expect(output).to eq(14)
111
+ end
112
+
113
+ it "visits Text nodes" do
114
+ visitor = counting_visitor_for(Curlybars::Node::Text)
115
+ output = Curlybars.visit(visitor, source)
116
+ expect(output).to eq(28)
117
+ end
118
+
119
+ it "visits UnlessElse nodes" do
120
+ visitor = counting_visitor_for(Curlybars::Node::UnlessElse)
121
+ output = Curlybars.visit(visitor, source)
122
+ expect(output).to eq(1)
123
+ end
124
+
125
+ it "visits Variable nodes" do
126
+ visitor = counting_visitor_for(Curlybars::Node::Variable)
127
+ output = Curlybars.visit(visitor, source)
128
+ expect(output).to eq(1)
129
+ end
130
+
131
+ it "visits WithElse nodes" do
132
+ visitor = counting_visitor_for(Curlybars::Node::WithElse)
133
+ output = Curlybars.visit(visitor, source)
134
+ expect(output).to eq(1)
135
+ end
136
+ end
137
+
138
+ def counting_visitor_for(klass)
139
+ Class.new(Curlybars::Visitor) do
140
+ define_method "visit_#{klass.name.demodulize.underscore}" do |node|
141
+ self.context += 1
142
+ super(node)
143
+ end
144
+ end.new(0)
145
+ end
146
+ end
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.1.4
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Libo Cannici
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2018-10-25 00:00:00.000000000 Z
16
+ date: 2019-03-15 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: actionpack
@@ -234,6 +234,7 @@ files:
234
234
  - lib/curlybars/safe_buffer.rb
235
235
  - lib/curlybars/template_handler.rb
236
236
  - lib/curlybars/version.rb
237
+ - lib/curlybars/visitor.rb
237
238
  - spec/acceptance/application_layout_spec.rb
238
239
  - spec/acceptance/collection_blocks_spec.rb
239
240
  - spec/acceptance/global_helper_spec.rb
@@ -270,6 +271,7 @@ files:
270
271
  - spec/integration/node/with_spec.rb
271
272
  - spec/integration/processor/tilde_spec.rb
272
273
  - spec/integration/processors_spec.rb
274
+ - spec/integration/visitor_spec.rb
273
275
  homepage: https://github.com/zendesk/curlybars
274
276
  licenses:
275
277
  - Apache-2.0
@@ -291,7 +293,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
291
293
  version: '0'
292
294
  requirements: []
293
295
  rubyforge_project:
294
- rubygems_version: 2.7.3
296
+ rubygems_version: 2.7.6
295
297
  signing_key:
296
298
  specification_version: 4
297
299
  summary: Create your views using Handlebars templates!
@@ -312,6 +314,7 @@ test_files:
312
314
  - spec/integration/processor/tilde_spec.rb
313
315
  - spec/integration/exception_spec.rb
314
316
  - spec/integration/processors_spec.rb
317
+ - spec/integration/visitor_spec.rb
315
318
  - spec/integration/node/escape_spec.rb
316
319
  - spec/integration/node/unless_else_spec.rb
317
320
  - spec/integration/node/output_spec.rb