babl-json 0.5.6 → 0.5.7

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
  SHA1:
3
- metadata.gz: ea8f407140ea61dc83be26fece70b85e47280b09
4
- data.tar.gz: d2503155b43b8ae0064d30808c30843c56b25702
3
+ metadata.gz: 3d16dfb585fb3f79b1242b92cd8ddf20663e8f18
4
+ data.tar.gz: 6fb4483228832e5d1016d92ef561c9dca4e34352
5
5
  SHA512:
6
- metadata.gz: 0725f1502d153f9de8dbd126dd3b5c03c9211c696b39a778aa756f9d8bc85f6db4fe10260bd39626edaf71b59d074af20b9af6aba49cba736e0eb72a70aca759
7
- data.tar.gz: 4e213c4de1d6bcd517e7b945b6eb3cd0004891c1356065a2c4716269f669b8fee63049897cbc4c4fc7be504ee8a6b02c209e3ba0a282fe1cd541331efaef2d9f
6
+ metadata.gz: 98ca371092e8bfdb4a49165439521aed3b7456bc350ae8908a700329f9da876133b91ae2c4adf982638f35a31a5d02efe1b540f647bd30f96699c745cf8a6d62
7
+ data.tar.gz: c30279d940b40fd1887a0e28b2885124bc1d84a2faac887dc667caf74ef2ef0dd92f4b4d67da443a3e08ab7197d4f3378003d692fbc3b1b5980a2b384d63168c
@@ -75,12 +75,12 @@ module Babl
75
75
 
76
76
  def template
77
77
  cached = @cached_template
78
- return cached.last if cached && config.using == cached.first
78
+ return cached.last if cached && [config.using].flatten == cached.first
79
79
  # Calling 'using' is a very inefficient operation, because
80
80
  # it creates a new class. We can avoid that cost most of the
81
81
  # time, assuming 'config.using' does not change often (typically
82
82
  # it should only change once at startup)
83
- modules = config.using.dup
83
+ modules = [config.using].flatten.dup
84
84
  template = Template.new.using(*modules)
85
85
  @cached_template = [modules, template]
86
86
  template
@@ -70,16 +70,12 @@ module Babl
70
70
  end
71
71
 
72
72
  def precompile(node)
73
- scope[node]
73
+ @scope[node]
74
74
  end
75
75
 
76
76
  def nest(context)
77
- self.class.new(context) { |node| scope[yield node] }
77
+ self.class.new(context) { |node| @scope[yield node] }
78
78
  end
79
-
80
- private
81
-
82
- attr_reader :scope
83
79
  end
84
80
  end
85
81
  end
@@ -17,33 +17,25 @@ module Babl
17
17
  end
18
18
 
19
19
  def compile(preloader: Rendering::NoopPreloader, pretty: true, optimize: true, lookup_context: nil)
20
- # Compute dependencies & schema on the non-simplified node tree in order
21
- # to catch all errors.
22
20
  tree = precompile(lookup_context: lookup_context)
21
+ tree = tree.optimize if optimize
23
22
  validate(tree)
24
23
 
25
- dependencies = tree.dependencies
26
- schema = tree.schema
27
-
28
- # Recompute dependencies & schema on the simplified tree before
29
- # exposing them to the user.
30
- if optimize
31
- tree = tree.optimize
32
- dependencies = tree.dependencies
33
- schema = tree.schema
34
- end
35
-
36
24
  Rendering::CompiledTemplate.with(
37
25
  preloader: preloader,
38
26
  pretty: pretty,
39
27
  node: tree,
40
- dependencies: dependencies,
41
- schema: schema
28
+ dependencies: tree.dependencies,
29
+ schema: tree.schema
42
30
  )
43
31
  end
44
32
 
33
+ def self.unscoped
34
+ @unscoped ||= new
35
+ end
36
+
45
37
  def unscoped
46
- self.class.new
38
+ self.class.unscoped
47
39
  end
48
40
 
49
41
  protected
@@ -48,11 +48,14 @@ module Babl
48
48
  def optimize_single
49
49
  return unless nodes.size == 1
50
50
  optimized = nodes.first.optimize
51
- case
52
- when FixedArray === optimized
53
- optimized
54
- when Constant === optimized
55
- optimized.value.nil? ? FixedArray::EMPTY : optimized
51
+
52
+ case optimized
53
+ when FixedArray then optimized
54
+ when Constant
55
+ case optimized.value
56
+ when ::Array then optimized
57
+ when ::NilClass then FixedArray::EMPTY
58
+ end
56
59
  end
57
60
  end
58
61
 
@@ -45,11 +45,14 @@ module Babl
45
45
  def optimize_single
46
46
  return unless nodes.size == 1
47
47
  optimized = nodes.first.optimize
48
- case
49
- when Object === optimized
50
- optimized
51
- when Constant === optimized
52
- optimized.value.nil? ? Object::EMPTY : optimized
48
+
49
+ case optimized
50
+ when Object then optimized
51
+ when Constant
52
+ case optimized.value
53
+ when ::Hash then optimized
54
+ when ::NilClass then Object::EMPTY
55
+ end
53
56
  end
54
57
  end
55
58
 
@@ -26,7 +26,7 @@ module Babl
26
26
 
27
27
  memoize def optimize
28
28
  optimized = node.optimize
29
- return optimized if Constant === optimized
29
+ return optimized if Constant === optimized || GotoPin === optimized
30
30
  return optimized.node if Parent === optimized
31
31
  return self if optimized.equal?(node)
32
32
  Nav.new(property, optimized)
@@ -21,7 +21,7 @@ module Babl
21
21
 
22
22
  memoize def optimize
23
23
  optimized = node.optimize
24
- return optimized if Constant === optimized
24
+ return optimized if Constant === optimized || GotoPin === optimized
25
25
  return self if optimized.equal?(node)
26
26
  Parent.new(optimized)
27
27
  end
@@ -22,17 +22,31 @@ module Babl
22
22
 
23
23
  memoize def optimize
24
24
  optimized = node.optimize
25
- return optimized if Constant === optimized
25
+ return optimized if Constant === optimized || GotoPin === optimized
26
26
  return optimized.node if Parent === optimized
27
+ return self if nodes.empty?
28
+
27
29
  optimized_nodes = nodes.map(&:optimize)
30
+
31
+ if optimized_nodes.all? { |n| Constant === n }
32
+ value = begin
33
+ block.call(*optimized_nodes.map(&:value))
34
+ rescue StandardError => e
35
+ raise Errors::InvalidTemplate, e.message, e.backtrace
36
+ end
37
+ constant_block = Utils::Proc.constant(value)
38
+ return With.new(optimized, Utils::Array::EMPTY, constant_block)
39
+ end
40
+
28
41
  return self if optimized.equal?(node) && optimized_nodes.each_with_index.all? { |n, idx| n.equal?(nodes[idx]) }
29
42
  With.new(optimized, optimized_nodes, block)
30
43
  end
31
44
 
32
45
  def render(frame)
33
- values = nodes.empty? ? nil : nodes.map { |n| n.render(frame) }
46
+ values = nodes.map { |n| n.render(frame) }
47
+
34
48
  value = begin
35
- nodes.empty? ? frame.object.instance_exec(&block) : block.call(*values)
49
+ block.call(*values)
36
50
  rescue StandardError => e
37
51
  raise Errors::RenderingError, "#{e.message}\n" + frame.formatted_stack(:__block__), e.backtrace
38
52
  end
@@ -10,7 +10,11 @@ module Babl
10
10
  def call(*args, &block)
11
11
  if block
12
12
  raise Errors::InvalidTemplate, 'call() expects no argument when a block is given' unless args.empty?
13
- return with(&block)
13
+
14
+ # The 'block' is wrapped by #selfify such that there is no implicit closure referencing the current
15
+ # template. Ideally, once a template has been compiled, all intermediate template objects should be
16
+ # garbage collectable.
17
+ return with(unscoped, &Utils::Proc.selfify(block))
14
18
  end
15
19
 
16
20
  raise Errors::InvalidTemplate, 'call() expects exactly 1 argument (unless block)' unless args.size == 1
@@ -3,10 +3,12 @@ module Babl
3
3
  module Operators
4
4
  module Extends
5
5
  module DSL
6
- def extends(partial_path, *args)
6
+ def extends(*partial_paths, extended_with)
7
7
  source {
8
- partial_template = partial(partial_path)
9
- args.empty? ? partial_template : merge(partial_template, *args)
8
+ merge(
9
+ *partial_paths.map { |path| partial(path) },
10
+ extended_with
11
+ )
10
12
  }
11
13
  end
12
14
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require 'babl/utils/array'
3
+ require 'babl/utils/dsl_proxy'
3
4
  require 'babl/utils/hash'
5
+ require 'babl/utils/proc'
4
6
  require 'babl/utils/ref'
5
7
  require 'babl/utils/value'
6
- require 'babl/utils/dsl_proxy'
@@ -4,16 +4,18 @@ module Babl
4
4
  class Hash
5
5
  EMPTY = {}.freeze
6
6
 
7
- def self.deep_merge(*hashes)
8
- filtered_hashes = hashes.reject(&:empty?)
9
- return EMPTY if filtered_hashes.empty?
10
- return filtered_hashes.first if filtered_hashes.size == 1
11
- filtered_hashes.reduce({}) { |out, hash| deep_merge_inplace(out, hash) }
12
- end
7
+ class << self
8
+ def deep_merge(*hashes)
9
+ filtered_hashes = hashes.reject(&:empty?)
10
+ return EMPTY if filtered_hashes.empty?
11
+ return filtered_hashes.first if filtered_hashes.size == 1
12
+ filtered_hashes.reduce({}) { |out, hash| deep_merge_inplace(out, hash) }
13
+ end
13
14
 
14
- def self.deep_merge_inplace(target, source)
15
- source.each { |k, v| target[k] = deep_merge_inplace(target[k] || {}, v) }
16
- target
15
+ def deep_merge_inplace(target, source)
16
+ source.each { |k, v| target[k] = deep_merge_inplace(target[k] || {}, v) }
17
+ target
18
+ end
17
19
  end
18
20
  end
19
21
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ module Babl
3
+ module Utils
4
+ class Proc
5
+ class << self
6
+ # Wrap a proc in a lambda, so that it is executed in the context of its first (and only) argument.
7
+ def selfify(proc)
8
+ ->(this) { this.instance_exec(&proc) }
9
+ end
10
+
11
+ # Create a lambda returning a constant.
12
+ def constant(value)
13
+ -> { value }
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Babl
3
- VERSION = '0.5.6'
3
+ VERSION = '0.5.7'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: babl-json
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.6
4
+ version: 0.5.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frederic Terrazzoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-05 00:00:00.000000000 Z
11
+ date: 2018-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coveralls
@@ -195,6 +195,7 @@ files:
195
195
  - lib/babl/utils/array.rb
196
196
  - lib/babl/utils/dsl_proxy.rb
197
197
  - lib/babl/utils/hash.rb
198
+ - lib/babl/utils/proc.rb
198
199
  - lib/babl/utils/ref.rb
199
200
  - lib/babl/utils/value.rb
200
201
  - lib/babl/version.rb