liquid-c 3.0.0 → 4.0.0.rc1

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
  SHA1:
3
- metadata.gz: f2140b7f3e49dc914ab2d474dee3bca94c6f5923
4
- data.tar.gz: d0d2ef0d9a4ab5d291b560e9d35c3391a7b456d8
3
+ metadata.gz: c625a10bf29068a8d124df52ea012868d936f2ea
4
+ data.tar.gz: 537c2e49a4a6b65c693e7f51d2432d0f969dcb3f
5
5
  SHA512:
6
- metadata.gz: b019264cea1628bbdb4194685d660a378107ce68561a549324d7171f088491219fa0b95970175cb9aa7078e68c2603c58dde78a5e61beac03b0cd49d2dc8082e
7
- data.tar.gz: ddf7b182c306787f2c31451b3af77f6dae6b22c83c79fddfbaba5e4243a1f54c3419607f3e4629a24fd13bc79ea1d462ed1c07eb77e3424094bdaf57bddb19c0
6
+ metadata.gz: 5390b71dc89234cd139d6e3234473cc00c200e37380ba8a140c1e49c58fe1d7db68dd98ee79d8d023cf4994c9c7b472031504bde9b2bc27312f9f0bb04a56902
7
+ data.tar.gz: 99565b5eb0e6458afa0b9d7608b67160b1972892c6fa2bf2a4850eca80428b25f49743a57e9380ce6294448442f462109c917c7a702f647597a78d4443215402
data/.travis.yml CHANGED
@@ -1,6 +1,12 @@
1
1
  language: ruby
2
+
2
3
  rvm:
3
- - 2.0.0
4
- - 2.1.0
5
- gemfile:
6
- - Gemfile
4
+ - 2.0
5
+ - 2.1
6
+ - 2.2
7
+ - ruby-head
8
+
9
+ sudo: false
10
+
11
+ notifications:
12
+ disable: true
data/Gemfile CHANGED
@@ -4,6 +4,7 @@ gemspec
4
4
 
5
5
  gem 'liquid', github: 'Shopify/liquid', branch: 'master'
6
6
 
7
+
7
8
  group :test do
8
9
  gem 'spy', '0.4.1'
9
10
  gem 'benchmark-ips'
data/ext/liquid_c/block.c CHANGED
@@ -9,9 +9,10 @@ static ID
9
9
  intern_blank,
10
10
  intern_is_blank,
11
11
  intern_clear,
12
- intern_tags,
12
+ intern_registered_tags,
13
13
  intern_parse,
14
- intern_square_brackets;
14
+ intern_square_brackets,
15
+ intern_set_line_number;
15
16
 
16
17
  static int is_id(int c)
17
18
  {
@@ -24,6 +25,14 @@ inline static const char *read_while(const char *start, const char *end, int (fu
24
25
  return start;
25
26
  }
26
27
 
28
+ inline static const char *read_while_end(const char *start, const char *end, int (func)(int))
29
+ {
30
+ end--;
31
+ while (start < end && func((unsigned char) *end)) end--;
32
+ end++;
33
+ return end;
34
+ }
35
+
27
36
  static VALUE rb_block_parse(VALUE self, VALUE tokens, VALUE options)
28
37
  {
29
38
  tokenizer_t *tokenizer;
@@ -34,6 +43,9 @@ static VALUE rb_block_parse(VALUE self, VALUE tokens, VALUE options)
34
43
  VALUE nodelist = rb_ivar_get(self, intern_nodelist);
35
44
 
36
45
  while (true) {
46
+ if (tokenizer->line_number != 0) {
47
+ rb_funcall(options, intern_set_line_number, 1, UINT2NUM(tokenizer->line_number));
48
+ }
37
49
  tokenizer_next(tokenizer, &token);
38
50
 
39
51
  switch (token.type) {
@@ -51,7 +63,14 @@ static VALUE rb_block_parse(VALUE self, VALUE tokens, VALUE options)
51
63
  }
52
64
  case TOKEN_RAW:
53
65
  {
54
- VALUE str = rb_enc_str_new(token.str, token.length, utf8_encoding);
66
+ const char *start = token.str, *end = token.str + token.length, *token_start = start, *token_end = end;
67
+
68
+ if(token.lstrip)
69
+ token_start = read_while(start, end, rb_isspace);
70
+ if(token.rstrip)
71
+ token_end = read_while_end(token_start, end, rb_isspace);
72
+
73
+ VALUE str = rb_enc_str_new(token_start, token_end - token_start, utf8_encoding);
55
74
  rb_ary_push(nodelist, str);
56
75
 
57
76
  if (rb_ivar_get(self, intern_blank) == Qtrue) {
@@ -64,7 +83,7 @@ static VALUE rb_block_parse(VALUE self, VALUE tokens, VALUE options)
64
83
  }
65
84
  case TOKEN_VARIABLE:
66
85
  {
67
- VALUE args[2] = {rb_enc_str_new(token.str + 2, token.length - 4, utf8_encoding), options};
86
+ VALUE args[2] = {rb_enc_str_new(token.str + 2 + token.lstrip, token.length - 4 - token.lstrip - token.rstrip, utf8_encoding), options};
68
87
  VALUE var = rb_class_new_instance(2, args, cLiquidVariable);
69
88
  rb_ary_push(nodelist, var);
70
89
  rb_ivar_set(self, intern_blank, Qfalse);
@@ -72,7 +91,7 @@ static VALUE rb_block_parse(VALUE self, VALUE tokens, VALUE options)
72
91
  }
73
92
  case TOKEN_TAG:
74
93
  {
75
- const char *start = token.str + 2, *end = token.str + token.length - 2;
94
+ const char *start = token.str + 2 + token.lstrip, *end = token.str + token.length - 2 - token.rstrip;
76
95
 
77
96
  // Imitate \s*(\w+)\s*(.*)? regex
78
97
  const char *name_start = read_while(start, end, rb_isspace);
@@ -81,7 +100,7 @@ static VALUE rb_block_parse(VALUE self, VALUE tokens, VALUE options)
81
100
  VALUE tag_name = rb_enc_str_new(name_start, name_end - name_start, utf8_encoding);
82
101
 
83
102
  if (tags == Qnil)
84
- tags = rb_funcall(cLiquidTemplate, intern_tags, 0);
103
+ tags = rb_funcall(self, intern_registered_tags, 0);
85
104
 
86
105
  VALUE tag_class = rb_funcall(tags, intern_square_brackets, 1, tag_name);
87
106
 
@@ -112,9 +131,10 @@ void init_liquid_block()
112
131
  intern_blank = rb_intern("@blank");
113
132
  intern_is_blank = rb_intern("blank?");
114
133
  intern_clear = rb_intern("clear");
115
- intern_tags = rb_intern("tags");
134
+ intern_registered_tags = rb_intern("registered_tags");
116
135
  intern_parse = rb_intern("parse");
117
136
  intern_square_brackets = rb_intern("[]");
137
+ intern_set_line_number = rb_intern("line_number=");
118
138
 
119
139
  VALUE cLiquidBlockBody = rb_const_get(mLiquid, rb_intern("BlockBody"));
120
140
  rb_define_method(cLiquidBlockBody, "c_parse", rb_block_parse, 2);
@@ -5,13 +5,14 @@
5
5
  #include "parser.h"
6
6
  #include "block.h"
7
7
 
8
- VALUE mLiquid, cLiquidSyntaxError, cLiquidVariable, cLiquidTemplate;
8
+ VALUE mLiquid, mLiquidC, cLiquidSyntaxError, cLiquidVariable, cLiquidTemplate;
9
9
  rb_encoding *utf8_encoding;
10
10
 
11
11
  void Init_liquid_c(void)
12
12
  {
13
13
  utf8_encoding = rb_utf8_encoding();
14
14
  mLiquid = rb_define_module("Liquid");
15
+ mLiquidC = rb_define_module_under(mLiquid, "C");
15
16
  cLiquidSyntaxError = rb_const_get(mLiquid, rb_intern("SyntaxError"));
16
17
  cLiquidVariable = rb_const_get(mLiquid, rb_intern("Variable"));
17
18
  cLiquidTemplate = rb_const_get(mLiquid, rb_intern("Template"));
@@ -5,7 +5,7 @@
5
5
  #include <ruby/encoding.h>
6
6
  #include <stdbool.h>
7
7
 
8
- extern VALUE mLiquid, cLiquidSyntaxError, cLiquidVariable, cLiquidTemplate;
8
+ extern VALUE mLiquid, mLiquidC, cLiquidSyntaxError, cLiquidVariable, cLiquidTemplate;
9
9
  extern rb_encoding *utf8_encoding;
10
10
 
11
11
  #endif
@@ -2,7 +2,7 @@
2
2
  #include "parser.h"
3
3
  #include "lexer.h"
4
4
 
5
- static VALUE cLiquidRangeLookup, cLiquidVariableLookup, cRange, symBlank, symEmpty;
5
+ static VALUE cLiquidRangeLookup, cLiquidVariableLookup, cRange, vLiquidExpressionLiterals;
6
6
  static ID idToI, idEvaluate;
7
7
 
8
8
  void init_parser(parser_t *p, const char *str, const char *end)
@@ -119,12 +119,10 @@ static VALUE parse_variable(parser_t *p)
119
119
  }
120
120
  }
121
121
 
122
- if (RARRAY_LEN(lookups) == 0 && TYPE(name) == T_STRING) {
123
- if (rstring_eq(name, "nil") || rstring_eq(name, "null")) return Qnil;
124
- if (rstring_eq(name, "true")) return Qtrue;
125
- if (rstring_eq(name, "false")) return Qfalse;
126
- if (rstring_eq(name, "blank")) return symBlank;
127
- if (rstring_eq(name, "empty")) return symEmpty;
122
+ if (RARRAY_LEN(lookups) == 0) {
123
+ VALUE undefined = FIXNUM_P(-1);
124
+ VALUE literal = rb_hash_lookup2(vLiquidExpressionLiterals, name, undefined);
125
+ if (literal != undefined) return literal;
128
126
  }
129
127
 
130
128
  VALUE args[4] = {Qfalse, name, lookups, INT2FIX(command_flags)};
@@ -185,8 +183,6 @@ void init_liquid_parser(void)
185
183
  {
186
184
  idToI = rb_intern("to_i");
187
185
  idEvaluate = rb_intern("evaluate");
188
- symBlank = ID2SYM(rb_intern("blank?"));
189
- symEmpty = ID2SYM(rb_intern("empty?"));
190
186
 
191
187
  cLiquidRangeLookup = rb_const_get(mLiquid, rb_intern("RangeLookup"));
192
188
  cRange = rb_const_get(rb_cObject, rb_intern("Range"));
@@ -194,5 +190,7 @@ void init_liquid_parser(void)
194
190
 
195
191
  VALUE cLiquidExpression = rb_const_get(mLiquid, rb_intern("Expression"));
196
192
  rb_define_singleton_method(cLiquidExpression, "c_parse", rb_parse_expression, 1);
193
+
194
+ vLiquidExpressionLiterals = rb_const_get(cLiquidExpression, rb_intern("LITERALS"));
197
195
  }
198
196
 
@@ -38,7 +38,7 @@ static VALUE tokenizer_allocate(VALUE klass)
38
38
  return obj;
39
39
  }
40
40
 
41
- static VALUE tokenizer_initialize_method(VALUE self, VALUE source)
41
+ static VALUE tokenizer_initialize_method(VALUE self, VALUE source, VALUE line_numbers)
42
42
  {
43
43
  tokenizer_t *tokenizer;
44
44
 
@@ -48,6 +48,10 @@ static VALUE tokenizer_initialize_method(VALUE self, VALUE source)
48
48
  tokenizer->source = source;
49
49
  tokenizer->cursor = RSTRING_PTR(source);
50
50
  tokenizer->length = RSTRING_LEN(source);
51
+ tokenizer->lstrip_flag = 0;
52
+ // tokenizer->line_number keeps track of the current line number or it is 0
53
+ // to indicate that line numbers aren't being calculated
54
+ tokenizer->line_number = RTEST(line_numbers) ? 1 : 0;
51
55
  return Qnil;
52
56
  }
53
57
 
@@ -63,6 +67,8 @@ void tokenizer_next(tokenizer_t *tokenizer, token_t *token)
63
67
 
64
68
  token->str = cursor;
65
69
  token->type = TOKEN_RAW;
70
+ token->lstrip = 0;
71
+ token->rstrip = 0;
66
72
 
67
73
  while (cursor < last) {
68
74
  if (*cursor++ != '{')
@@ -71,12 +77,20 @@ void tokenizer_next(tokenizer_t *tokenizer, token_t *token)
71
77
  char c = *cursor++;
72
78
  if (c != '%' && c != '{')
73
79
  continue;
74
- if (cursor - tokenizer->cursor > 2) {
80
+ if (cursor <= last && *cursor == '-') {
81
+ cursor++;
82
+ token->rstrip = 1;
83
+ }
84
+ if (cursor - tokenizer->cursor > (ptrdiff_t)(2 + token->rstrip)) {
75
85
  token->type = TOKEN_RAW;
76
- cursor -= 2;
86
+ cursor -= 2 + token->rstrip;
87
+ token->lstrip = tokenizer->lstrip_flag;
88
+ tokenizer->lstrip_flag = 0;
77
89
  goto found;
78
90
  }
79
91
  token->type = TOKEN_INVALID;
92
+ token->lstrip = token->rstrip;
93
+ token->rstrip = 0;
80
94
  if (c == '%') {
81
95
  while (cursor < last) {
82
96
  if (*cursor++ != '%')
@@ -87,10 +101,13 @@ void tokenizer_next(tokenizer_t *tokenizer, token_t *token)
87
101
  if (c != '}')
88
102
  continue;
89
103
  token->type = TOKEN_TAG;
104
+ if(cursor[-3] == '-')
105
+ token->rstrip = tokenizer->lstrip_flag = 1;
90
106
  goto found;
91
107
  }
92
108
  // unterminated tag
93
109
  cursor = tokenizer->cursor + 2;
110
+ tokenizer->lstrip_flag = 0;
94
111
  goto found;
95
112
  } else {
96
113
  while (cursor < last) {
@@ -102,18 +119,33 @@ void tokenizer_next(tokenizer_t *tokenizer, token_t *token)
102
119
  goto found;
103
120
  }
104
121
  token->type = TOKEN_VARIABLE;
122
+ if(cursor[-3] == '-')
123
+ token->rstrip = tokenizer->lstrip_flag = 1;
105
124
  goto found;
106
125
  }
107
126
  // unterminated variable
108
127
  cursor = tokenizer->cursor + 2;
128
+ tokenizer->lstrip_flag = 0;
109
129
  goto found;
110
130
  }
111
131
  }
112
132
  cursor = last + 1;
133
+ token->lstrip = tokenizer->lstrip_flag;
134
+ tokenizer->lstrip_flag = 0;
113
135
  found:
114
136
  token->length = cursor - tokenizer->cursor;
115
137
  tokenizer->cursor += token->length;
116
138
  tokenizer->length -= token->length;
139
+
140
+ if (tokenizer->line_number) {
141
+ const char *cursor = token->str;
142
+ const char *end = token->str + token->length;
143
+ while (cursor < end) {
144
+ if (*cursor == '\n')
145
+ tokenizer->line_number++;
146
+ cursor++;
147
+ }
148
+ }
117
149
  }
118
150
 
119
151
  static VALUE tokenizer_shift_method(VALUE self)
@@ -129,11 +161,23 @@ static VALUE tokenizer_shift_method(VALUE self)
129
161
  return rb_enc_str_new(token.str, token.length, utf8_encoding);
130
162
  }
131
163
 
164
+ static VALUE tokenizer_line_number_method(VALUE self)
165
+ {
166
+ tokenizer_t *tokenizer;
167
+ Tokenizer_Get_Struct(self, tokenizer);
168
+
169
+ if (tokenizer->line_number == 0)
170
+ return Qnil;
171
+
172
+ return UINT2NUM(tokenizer->line_number);
173
+ }
174
+
132
175
  void init_liquid_tokenizer()
133
176
  {
134
- cLiquidTokenizer = rb_define_class_under(mLiquid, "Tokenizer", rb_cObject);
177
+ cLiquidTokenizer = rb_define_class_under(mLiquidC, "Tokenizer", rb_cObject);
135
178
  rb_define_alloc_func(cLiquidTokenizer, tokenizer_allocate);
136
- rb_define_method(cLiquidTokenizer, "initialize", tokenizer_initialize_method, 1);
179
+ rb_define_method(cLiquidTokenizer, "initialize", tokenizer_initialize_method, 2);
137
180
  rb_define_method(cLiquidTokenizer, "shift", tokenizer_shift_method, 0);
181
+ rb_define_method(cLiquidTokenizer, "line_number", tokenizer_line_number_method, 0);
138
182
  }
139
183
 
@@ -13,12 +13,16 @@ typedef struct token {
13
13
  enum token_type type;
14
14
  const char *str;
15
15
  long length;
16
+ unsigned int lstrip;
17
+ unsigned int rstrip;
16
18
  } token_t;
17
19
 
18
20
  typedef struct tokenizer {
19
21
  VALUE source;
20
22
  const char *cursor;
21
23
  long length;
24
+ unsigned int line_number;
25
+ unsigned int lstrip_flag;
22
26
  } tokenizer_t;
23
27
 
24
28
  extern VALUE cLiquidTokenizer;
data/lib/liquid/c.rb CHANGED
@@ -12,16 +12,12 @@ module Liquid
12
12
  end
13
13
  end
14
14
 
15
- Liquid::Template.class_eval do
16
- private
17
-
18
- alias_method :ruby_tokenize, :tokenize
19
-
20
- def tokenize(source)
21
- if Liquid::C.enabled && !@line_numbers
22
- Liquid::Tokenizer.new(source.to_s)
15
+ Liquid::Tokenizer.class_eval do
16
+ def self.new(source, line_numbers = false)
17
+ if Liquid::C.enabled
18
+ Liquid::C::Tokenizer.new(source.to_s, line_numbers)
23
19
  else
24
- ruby_tokenize(source)
20
+ super
25
21
  end
26
22
  end
27
23
  end
@@ -30,7 +26,7 @@ Liquid::BlockBody.class_eval do
30
26
  alias_method :ruby_parse, :parse
31
27
 
32
28
  def parse(tokens, options)
33
- if Liquid::C.enabled && !options[:line_numbers] && !options[:profile]
29
+ if Liquid::C.enabled && !options[:profile]
34
30
  c_parse(tokens, options) { |t, m| yield t, m }
35
31
  else
36
32
  ruby_parse(tokens, options) { |t, m| yield t, m }
@@ -43,7 +39,7 @@ Liquid::Variable.class_eval do
43
39
  alias_method :ruby_strict_parse, :strict_parse
44
40
 
45
41
  def lax_parse(markup)
46
- stats = @options[:stats_callbacks]
42
+ stats = options[:stats_callbacks]
47
43
  stats[:variable_parse].call if stats
48
44
 
49
45
  if Liquid::C.enabled
@@ -1,5 +1,5 @@
1
1
  module Liquid
2
2
  module C
3
- VERSION = "3.0.0"
3
+ VERSION = "4.0.0.rc1"
4
4
  end
5
5
  end
data/liquid-c.gemspec CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "liquid-c"
8
8
  spec.version = Liquid::C::VERSION
9
9
  spec.authors = ["Justin Li", "Dylan Thacker-Smith"]
10
- spec.email = ["jli@shopify.com", "Dylan.Smith@shopify.com"]
10
+ spec.email = ["gems@shopify.com"]
11
11
  spec.summary = "Liquid performance extension in C"
12
12
  spec.homepage = ""
13
13
  spec.license = "MIT"
@@ -23,5 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "bundler", "~> 1.5"
24
24
  spec.add_development_dependency "rake"
25
25
  spec.add_development_dependency 'rake-compiler'
26
+ spec.add_development_dependency 'minitest'
26
27
  spec.add_development_dependency 'stackprof' if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.1.0")
27
28
  end
@@ -33,7 +33,7 @@ class TokenizerTest < MiniTest::Unit::TestCase
33
33
  private
34
34
 
35
35
  def tokenize(source)
36
- tokenizer = Liquid::Tokenizer.new(source)
36
+ tokenizer = Liquid::C::Tokenizer.new(source, false)
37
37
  tokens = []
38
38
  while t = tokenizer.shift
39
39
  tokens << t
@@ -35,7 +35,7 @@ class VariableTest < MiniTest::Unit::TestCase
35
35
  assert_equal [123.4, []], variable_parse('123.4')
36
36
 
37
37
  assert_equal [lookup('[blank]'), []], variable_parse('[blank]')
38
- assert_equal [lookup(false, true, [:blank?], 0), []], variable_parse('[true][blank]')
38
+ assert_equal [lookup(false, true, [Liquid::Expression::LITERALS['blank']], 0), []], variable_parse('[true][blank]')
39
39
  assert_equal [lookup('[true][blank]'), []], variable_parse('[true][blank]')
40
40
  assert_equal [lookup('x["size"]'), []], variable_parse('x["size"]')
41
41
  end
@@ -84,17 +84,21 @@ class VariableTest < MiniTest::Unit::TestCase
84
84
  variable_fallback: lambda { variable_fallbacks += 1 }
85
85
  }
86
86
 
87
- Liquid::Variable.new('abc', error_mode: :lax, stats_callbacks: callbacks)
87
+ create_variable('abc', error_mode: :lax, stats_callbacks: callbacks)
88
88
  assert_equal 1, variable_parses
89
89
  assert_equal 0, variable_fallbacks
90
90
 
91
- Liquid::Variable.new('@!#', error_mode: :lax, stats_callbacks: callbacks)
91
+ create_variable('@!#', error_mode: :lax, stats_callbacks: callbacks)
92
92
  assert_equal 2, variable_parses
93
93
  assert_equal 1, variable_fallbacks
94
94
  end
95
95
 
96
96
  private
97
97
 
98
+ def create_variable(markup, options={})
99
+ Liquid::Variable.new(markup, Liquid::ParseContext.new(options))
100
+ end
101
+
98
102
  def variable_parse(markup)
99
103
  name = Liquid::Variable.c_strict_parse(markup, filters = [])
100
104
  [name, filters]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: liquid-c
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 4.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Li
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-01-31 00:00:00.000000000 Z
12
+ date: 2016-09-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: liquid
@@ -67,6 +67,20 @@ dependencies:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: minitest
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
70
84
  - !ruby/object:Gem::Dependency
71
85
  name: stackprof
72
86
  requirement: !ruby/object:Gem::Requirement
@@ -83,8 +97,7 @@ dependencies:
83
97
  version: '0'
84
98
  description:
85
99
  email:
86
- - jli@shopify.com
87
- - Dylan.Smith@shopify.com
100
+ - gems@shopify.com
88
101
  executables: []
89
102
  extensions:
90
103
  - ext/liquid_c/extconf.rb
@@ -132,12 +145,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
145
  version: '0'
133
146
  required_rubygems_version: !ruby/object:Gem::Requirement
134
147
  requirements:
135
- - - ">="
148
+ - - ">"
136
149
  - !ruby/object:Gem::Version
137
- version: '0'
150
+ version: 1.3.1
138
151
  requirements: []
139
152
  rubyforge_project:
140
- rubygems_version: 2.2.2
153
+ rubygems_version: 2.4.5
141
154
  signing_key:
142
155
  specification_version: 4
143
156
  summary: Liquid performance extension in C