curlybars 1.1.4 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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