hamlit 2.9.5-java → 2.10.0-java

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: 193802f1d67fc26bc7768ebc12ffaec1a57bbff9595a6ba6988ae923f1e0c296
4
- data.tar.gz: e6c7e8704302d2580963d95d65973920bd343e2e1c13a8fc67f0c6a7dcb459f6
3
+ metadata.gz: 99cd9c02b87a3dc2b594a21125b5e8ce015b51b6f601c5eddd04e4f383e867e6
4
+ data.tar.gz: bd8c5109399f8ff52e7778a906ae4c4b1060a8f8479c03c4001c1a8f0d1c3b0c
5
5
  SHA512:
6
- metadata.gz: 73245cb64fbe0fe915c7e8e2a5b22fe350190348ce39ceb0be4ad36ced4c3551f29c2bbde88dc11b4bf5bb3acc5c54eb5b2bb708abd1907dfdc6ef8abb6f4849
7
- data.tar.gz: a543965e78ecccf8d3a9f4c98a6e1b627d3a7586549b662917da462dc542437aadd93e2279e371a7bc9d1b3463bc404ca721c19cef75875ac1f61663f781211a
6
+ metadata.gz: fc49deaa8ad1b706409f3a8ceb126061e80b765724b55972c084e092fcf41d3f221fbc799900adcd7d6974b5a84938f977d1ae02a81b8bcbe8e0ced825487e2f
7
+ data.tar.gz: 0b5a729b3fc2302d66d41dc82f8d65b1f93b75b89c46b822d28b96ee19d36307c4d6ef111b1894c5df21153023f8a7f9e58cfc7d29cb84af49969633da835c6f
data/.gitignore CHANGED
@@ -11,6 +11,7 @@
11
11
  .ruby-version
12
12
  *.bundle
13
13
  *.so
14
+ *.su
14
15
  *.o
15
16
  *.a
16
17
  *.swp
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. This
4
4
  project adheres to [Semantic Versioning](http://semver.org/). This change log is based upon
5
5
  [keep-a-changelog](https://github.com/olivierlacan/keep-a-changelog).
6
6
 
7
+ ## [2.10.0](https://github.com/k0kubun/hamlit/compare/v2.9.5...v2.10.0) - 2019-09-15
8
+
9
+ ### Added
10
+
11
+ - Optimize template rendering by exploiting string interpolation [#146](https://github.com/k0kubun/hamlit/issues/146)
12
+ - Exploiting pre-allocation of string interpolation introduced in Ruby 2.5 [ruby/ruby#1626](https://github.com/ruby/ruby/pull/1626)
13
+ - Require temple.gem >= 0.8.2
14
+
7
15
  ## [2.9.5](https://github.com/k0kubun/hamlit/compare/v2.9.4...v2.9.5) - 2019-09-08
8
16
 
9
17
  ### Added
data/Gemfile CHANGED
@@ -14,11 +14,11 @@ end
14
14
 
15
15
  gem 'benchmark-ips', '2.3.0'
16
16
  gem 'maxitest'
17
+ gem 'pry'
17
18
 
18
19
  if /java/ === RUBY_PLATFORM # JRuby
19
20
  gem 'pandoc-ruby'
20
21
  else
21
- gem 'pry-byebug'
22
22
  gem 'redcarpet'
23
23
 
24
24
  if RUBY_PLATFORM !~ /mswin|mingw/ && RUBY_ENGINE != 'truffleruby'
@@ -0,0 +1,25 @@
1
+ # Original: https://github.com/amatsuda/string_template/blob/master/benchmark.rb
2
+ require 'benchmark_driver'
3
+
4
+ Benchmark.driver(repeat_count: 8) do |x|
5
+ x.prelude %{
6
+ require 'rails'
7
+ require 'action_view'
8
+ require 'string_template'
9
+ StringTemplate::Railtie.run_initializers
10
+ require 'hamlit'
11
+ Hamlit::Railtie.run_initializers
12
+ Hamlit::RailsTemplate.set_options(escape_html: false, generator: Temple::Generators::ArrayBuffer)
13
+ require 'action_view/base'
14
+
15
+ (view = Class.new(ActionView::Base).new(ActionView::LookupContext.new(''))).instance_variable_set(:@world, 'world!')
16
+
17
+ # compile template
18
+ hello = 'benchmark/dynamic_merger/hello'
19
+ view.render(template: hello, handlers: 'string')
20
+ view.render(template: hello, handlers: 'haml')
21
+ }
22
+ x.report 'string', %{ view.render(template: hello, handlers: 'string') }
23
+ x.report 'hamlit', %{ view.render(template: hello, handlers: 'haml') }
24
+ x.loop_count 100_000
25
+ end
@@ -0,0 +1,50 @@
1
+ hello, #{ @world }
2
+ hello, #{ @world }
3
+ hello, #{ @world }
4
+ hello, #{ @world }
5
+ hello, #{ @world }
6
+ hello, #{ @world }
7
+ hello, #{ @world }
8
+ hello, #{ @world }
9
+ hello, #{ @world }
10
+ hello, #{ @world }
11
+ hello, #{ @world }
12
+ hello, #{ @world }
13
+ hello, #{ @world }
14
+ hello, #{ @world }
15
+ hello, #{ @world }
16
+ hello, #{ @world }
17
+ hello, #{ @world }
18
+ hello, #{ @world }
19
+ hello, #{ @world }
20
+ hello, #{ @world }
21
+ hello, #{ @world }
22
+ hello, #{ @world }
23
+ hello, #{ @world }
24
+ hello, #{ @world }
25
+ hello, #{ @world }
26
+ hello, #{ @world }
27
+ hello, #{ @world }
28
+ hello, #{ @world }
29
+ hello, #{ @world }
30
+ hello, #{ @world }
31
+ hello, #{ @world }
32
+ hello, #{ @world }
33
+ hello, #{ @world }
34
+ hello, #{ @world }
35
+ hello, #{ @world }
36
+ hello, #{ @world }
37
+ hello, #{ @world }
38
+ hello, #{ @world }
39
+ hello, #{ @world }
40
+ hello, #{ @world }
41
+ hello, #{ @world }
42
+ hello, #{ @world }
43
+ hello, #{ @world }
44
+ hello, #{ @world }
45
+ hello, #{ @world }
46
+ hello, #{ @world }
47
+ hello, #{ @world }
48
+ hello, #{ @world }
49
+ hello, #{ @world }
50
+ hello, #{ @world }
@@ -0,0 +1,50 @@
1
+ hello, #{ @world }
2
+ hello, #{ @world }
3
+ hello, #{ @world }
4
+ hello, #{ @world }
5
+ hello, #{ @world }
6
+ hello, #{ @world }
7
+ hello, #{ @world }
8
+ hello, #{ @world }
9
+ hello, #{ @world }
10
+ hello, #{ @world }
11
+ hello, #{ @world }
12
+ hello, #{ @world }
13
+ hello, #{ @world }
14
+ hello, #{ @world }
15
+ hello, #{ @world }
16
+ hello, #{ @world }
17
+ hello, #{ @world }
18
+ hello, #{ @world }
19
+ hello, #{ @world }
20
+ hello, #{ @world }
21
+ hello, #{ @world }
22
+ hello, #{ @world }
23
+ hello, #{ @world }
24
+ hello, #{ @world }
25
+ hello, #{ @world }
26
+ hello, #{ @world }
27
+ hello, #{ @world }
28
+ hello, #{ @world }
29
+ hello, #{ @world }
30
+ hello, #{ @world }
31
+ hello, #{ @world }
32
+ hello, #{ @world }
33
+ hello, #{ @world }
34
+ hello, #{ @world }
35
+ hello, #{ @world }
36
+ hello, #{ @world }
37
+ hello, #{ @world }
38
+ hello, #{ @world }
39
+ hello, #{ @world }
40
+ hello, #{ @world }
41
+ hello, #{ @world }
42
+ hello, #{ @world }
43
+ hello, #{ @world }
44
+ hello, #{ @world }
45
+ hello, #{ @world }
46
+ hello, #{ @world }
47
+ hello, #{ @world }
48
+ hello, #{ @world }
49
+ hello, #{ @world }
50
+ hello, #{ @world }
data/bin/bench CHANGED
@@ -25,7 +25,7 @@ class Bench < Thor
25
25
  haml = File.read(file)
26
26
 
27
27
  Benchmark.ips do |x|
28
- x.report("haml v#{Haml::VERSION}") { Haml::Engine.new(haml, escape_html: true, escape_attrs: true, ugly: true).precompiled }
28
+ x.report("haml v#{Haml::VERSION}") { Haml::Engine.new(haml, escape_html: true, escape_attrs: true).precompiled }
29
29
  x.report("faml v#{Faml::VERSION}") { Faml::Engine.new.call(haml) }
30
30
  x.report("hamlit v#{Hamlit::VERSION}") { Hamlit::Engine.new.call(haml) }
31
31
  x.compare!
@@ -26,10 +26,11 @@ Gem::Specification.new do |spec|
26
26
  spec.required_ruby_version = '>= 2.1.0'
27
27
  end
28
28
 
29
- spec.add_dependency 'temple', '>= 0.8.0'
29
+ spec.add_dependency 'temple', '>= 0.8.2'
30
30
  spec.add_dependency 'thor'
31
31
  spec.add_dependency 'tilt'
32
32
 
33
+ spec.add_development_dependency 'benchmark_driver'
33
34
  spec.add_development_dependency 'bundler'
34
35
  spec.add_development_dependency 'coffee-script'
35
36
  spec.add_development_dependency 'erubi'
@@ -41,5 +42,6 @@ Gem::Specification.new do |spec|
41
42
  spec.add_development_dependency 'rake-compiler'
42
43
  spec.add_development_dependency 'sass'
43
44
  spec.add_development_dependency 'slim'
45
+ spec.add_development_dependency 'string_template'
44
46
  spec.add_development_dependency 'unindent'
45
47
  end
@@ -55,10 +55,6 @@ module Hamlit
55
55
 
56
56
  # We should handle interpolation here to escape only interpolated values.
57
57
  def compile_interpolated_plain(node)
58
- unless Ripper.respond_to?(:lex) # No Ripper.lex in truffleruby
59
- return [:multi, [:escape, node.value[:escape_interpolation], [:dynamic, "%Q[#{node.value[:value]}]"]], [:newline]]
60
- end
61
-
62
58
  temple = [:multi]
63
59
  StringSplitter.compile(node.value[:value]).each do |type, value|
64
60
  case type
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+ module Hamlit
3
+ # Compile [:multi, [:static, 'foo'], [:dynamic, 'bar']] to [:dynamic, '"foo#{bar}"']
4
+ class DynamicMerger < Temple::Filter
5
+ def on_multi(*exps)
6
+ exps = exps.dup
7
+ result = [:multi]
8
+ buffer = []
9
+
10
+ until exps.empty?
11
+ type, arg = exps.first
12
+ if type == :dynamic && arg.count("\n") == 0
13
+ buffer << exps.shift
14
+ elsif type == :static && exps.size > (count = arg.count("\n")) &&
15
+ exps[1, count].all? { |e| e == [:newline] }
16
+ (1 + count).times { buffer << exps.shift }
17
+ elsif type == :newline && exps.size > (count = count_newline(exps)) &&
18
+ exps[count].first == :static && count == exps[count].last.count("\n")
19
+ (count + 1).times { buffer << exps.shift }
20
+ else
21
+ result.concat(merge_dynamic(buffer))
22
+ buffer = []
23
+ result << compile(exps.shift)
24
+ end
25
+ end
26
+ result.concat(merge_dynamic(buffer))
27
+
28
+ result.size == 2 ? result[1] : result
29
+ end
30
+
31
+ private
32
+
33
+ def merge_dynamic(exps)
34
+ # Merge exps only when they have both :static and :dynamic
35
+ unless exps.any? { |type,| type == :static } && exps.any? { |type,| type == :dynamic }
36
+ return exps
37
+ end
38
+
39
+ strlit_body = String.new
40
+ exps.each do |type, arg|
41
+ case type
42
+ when :static
43
+ strlit_body << arg.dump.sub!(/\A"/, '').sub!(/"\z/, '').gsub('\n', "\n")
44
+ when :dynamic
45
+ strlit_body << "\#{#{arg}}"
46
+ when :newline
47
+ # newline is added by `gsub('\n', "\n")`
48
+ else
49
+ raise "unexpected type #{type.inspect} is given to #merge_dynamic"
50
+ end
51
+ end
52
+ [[:dynamic, "%Q\0#{strlit_body}\0"]]
53
+ end
54
+
55
+ def count_newline(exps)
56
+ count = 0
57
+ exps.each do |exp|
58
+ if exp == [:newline]
59
+ count += 1
60
+ else
61
+ return count
62
+ end
63
+ end
64
+ return count
65
+ end
66
+ end
67
+ end
@@ -2,10 +2,10 @@
2
2
  require 'temple'
3
3
  require 'hamlit/parser'
4
4
  require 'hamlit/compiler'
5
+ require 'hamlit/html'
5
6
  require 'hamlit/escapable'
6
7
  require 'hamlit/force_escapable'
7
- require 'hamlit/html'
8
- require 'hamlit/string_splitter'
8
+ require 'hamlit/dynamic_merger'
9
9
 
10
10
  module Hamlit
11
11
  class Engine < Temple::Engine
@@ -25,15 +25,14 @@ module Hamlit
25
25
  use Parser
26
26
  use Compiler
27
27
  use HTML
28
- if Ripper.respond_to?(:lex) # No Ripper.lex in truffleruby
29
- use StringSplitter
30
- filter :StaticAnalyzer
31
- end
28
+ filter :StringSplitter
29
+ filter :StaticAnalyzer
32
30
  use Escapable
33
31
  use ForceEscapable
34
32
  filter :ControlFlow
35
33
  filter :MultiFlattener
36
34
  filter :StaticMerger
35
+ use DynamicMerger
37
36
  use :Generator, -> { options[:generator] }
38
37
  end
39
38
  end
@@ -14,10 +14,6 @@ module Hamlit
14
14
 
15
15
  def compile_plain(text)
16
16
  string_literal = ::Hamlit::HamlUtil.unescape_interpolation(text)
17
- unless Ripper.respond_to?(:lex) # truffleruby doesn't have Ripper.lex
18
- return [[:escape, false, [:dynamic, string_literal]]]
19
- end
20
-
21
17
  StringSplitter.compile(string_literal).map do |temple|
22
18
  type, str = temple
23
19
  case type
@@ -2,87 +2,18 @@ require 'ripper'
2
2
  require 'hamlit/ruby_expression'
3
3
 
4
4
  module Hamlit
5
- class StringSplitter < Temple::Filter
6
- class << self
7
- # `code` param must be valid string literal
8
- def compile(code)
9
- [].tap do |exps|
10
- tokens = Ripper.lex(code.strip)
11
- tokens.pop while tokens.last && %i[on_comment on_sp].include?(tokens.last[1])
12
-
13
- if tokens.size < 2
14
- raise Hamlit::InternalError.new("Expected token size >= 2 but got: #{tokens.size}")
15
- end
16
- compile_tokens!(exps, tokens)
17
- end
18
- end
19
-
20
- private
21
-
22
- def strip_quotes!(tokens)
23
- _, type, beg_str = tokens.shift
24
- if type != :on_tstring_beg
25
- raise Hamlit::InternalError.new("Expected :on_tstring_beg but got: #{type}")
26
- end
27
-
28
- _, type, end_str = tokens.pop
29
- if type != :on_tstring_end
30
- raise Hamlit::InternalError.new("Expected :on_tstring_end but got: #{type}")
31
- end
32
-
33
- [beg_str, end_str]
34
- end
35
-
36
- def compile_tokens!(exps, tokens)
37
- beg_str, end_str = strip_quotes!(tokens)
38
-
39
- until tokens.empty?
40
- _, type, str = tokens.shift
41
-
42
- case type
43
- when :on_tstring_content
44
- exps << [:static, eval("#{beg_str}#{str}#{end_str}")]
45
- when :on_embexpr_beg
46
- embedded = shift_balanced_embexpr(tokens)
47
- exps << [:dynamic, embedded] unless embedded.empty?
48
- end
49
- end
50
- end
51
-
52
- def shift_balanced_embexpr(tokens)
53
- String.new.tap do |embedded|
54
- embexpr_open = 1
55
-
56
- until tokens.empty?
57
- _, type, str = tokens.shift
58
- case type
59
- when :on_embexpr_beg
60
- embexpr_open += 1
61
- when :on_embexpr_end
62
- embexpr_open -= 1
63
- break if embexpr_open == 0
64
- end
65
-
66
- embedded << str
67
- end
68
- end
5
+ module StringSplitter
6
+ # `code` param must be valid string literal
7
+ def self.compile(code)
8
+ unless Ripper.respond_to?(:lex) # truffleruby doesn't have Ripper.lex
9
+ return [[:dynamic, code]]
69
10
  end
70
- end
71
-
72
- def on_dynamic(code)
73
- return [:dynamic, code] unless RubyExpression.string_literal?(code)
74
- return [:dynamic, code] if code.include?("\n")
75
11
 
76
- temple = [:multi]
77
- StringSplitter.compile(code).each do |type, content|
78
- case type
79
- when :static
80
- temple << [:static, content]
81
- when :dynamic
82
- temple << on_dynamic(content)
83
- end
12
+ begin
13
+ Temple::Filters::StringSplitter.compile(code)
14
+ rescue Temple::FilterError => e
15
+ raise Hamlit::InternalError.new(e.message)
84
16
  end
85
- temple
86
17
  end
87
18
  end
88
19
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Hamlit
3
- VERSION = '2.9.5'
3
+ VERSION = '2.10.0'
4
4
  end
metadata CHANGED
@@ -1,21 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hamlit
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.5
4
+ version: 2.10.0
5
5
  platform: java
6
6
  authors:
7
7
  - Takashi Kokubun
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-09-08 00:00:00.000000000 Z
11
+ date: 2019-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 0.8.0
18
+ version: 0.8.2
19
19
  name: temple
20
20
  prerelease: false
21
21
  type: :runtime
@@ -23,7 +23,7 @@ dependencies:
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.8.0
26
+ version: 0.8.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ name: benchmark_driver
62
+ prerelease: false
63
+ type: :development
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  requirement: !ruby/object:Gem::Requirement
57
71
  requirements:
@@ -206,6 +220,20 @@ dependencies:
206
220
  - - ">="
207
221
  - !ruby/object:Gem::Version
208
222
  version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ requirement: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - ">="
227
+ - !ruby/object:Gem::Version
228
+ version: '0'
229
+ name: string_template
230
+ prerelease: false
231
+ type: :development
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
209
237
  - !ruby/object:Gem::Dependency
210
238
  requirement: !ruby/object:Gem::Requirement
211
239
  requirements:
@@ -246,6 +274,9 @@ files:
246
274
  - benchmark/dynamic_attributes/data_attribute.haml
247
275
  - benchmark/dynamic_attributes/id_attribute.haml
248
276
  - benchmark/dynamic_boolean_attribute.haml
277
+ - benchmark/dynamic_merger/benchmark.rb
278
+ - benchmark/dynamic_merger/hello.haml
279
+ - benchmark/dynamic_merger/hello.string
249
280
  - benchmark/etc/attribute_builder.haml
250
281
  - benchmark/etc/real_sample.haml
251
282
  - benchmark/etc/real_sample.rb
@@ -289,6 +320,7 @@ files:
289
320
  - lib/hamlit/compiler/script_compiler.rb
290
321
  - lib/hamlit/compiler/silent_script_compiler.rb
291
322
  - lib/hamlit/compiler/tag_compiler.rb
323
+ - lib/hamlit/dynamic_merger.rb
292
324
  - lib/hamlit/engine.rb
293
325
  - lib/hamlit/error.rb
294
326
  - lib/hamlit/escapable.rb
@@ -310,7 +342,6 @@ files:
310
342
  - lib/hamlit/filters/text_base.rb
311
343
  - lib/hamlit/filters/tilt_base.rb
312
344
  - lib/hamlit/force_escapable.rb
313
- - lib/hamlit/hamlit.su
314
345
  - lib/hamlit/helpers.rb
315
346
  - lib/hamlit/html.rb
316
347
  - lib/hamlit/identity.rb
Binary file