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 +4 -4
- data/.travis.yml +10 -4
- data/Gemfile +1 -0
- data/ext/liquid_c/block.c +27 -7
- data/ext/liquid_c/liquid.c +2 -1
- data/ext/liquid_c/liquid.h +1 -1
- data/ext/liquid_c/parser.c +7 -9
- data/ext/liquid_c/tokenizer.c +49 -5
- data/ext/liquid_c/tokenizer.h +4 -0
- data/lib/liquid/c.rb +7 -11
- data/lib/liquid/c/version.rb +1 -1
- data/liquid-c.gemspec +2 -1
- data/test/unit/tokenizer_test.rb +1 -1
- data/test/unit/variable_test.rb +7 -3
- metadata +20 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c625a10bf29068a8d124df52ea012868d936f2ea
|
|
4
|
+
data.tar.gz: 537c2e49a4a6b65c693e7f51d2432d0f969dcb3f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5390b71dc89234cd139d6e3234473cc00c200e37380ba8a140c1e49c58fe1d7db68dd98ee79d8d023cf4994c9c7b472031504bde9b2bc27312f9f0bb04a56902
|
|
7
|
+
data.tar.gz: 99565b5eb0e6458afa0b9d7608b67160b1972892c6fa2bf2a4850eca80428b25f49743a57e9380ce6294448442f462109c917c7a702f647597a78d4443215402
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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);
|
data/ext/liquid_c/liquid.c
CHANGED
|
@@ -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"));
|
data/ext/liquid_c/liquid.h
CHANGED
|
@@ -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
|
data/ext/liquid_c/parser.c
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#include "parser.h"
|
|
3
3
|
#include "lexer.h"
|
|
4
4
|
|
|
5
|
-
static VALUE cLiquidRangeLookup, cLiquidVariableLookup, cRange,
|
|
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
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (
|
|
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
|
|
data/ext/liquid_c/tokenizer.c
CHANGED
|
@@ -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
|
|
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(
|
|
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,
|
|
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
|
|
data/ext/liquid_c/tokenizer.h
CHANGED
|
@@ -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::
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
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[:
|
|
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 =
|
|
42
|
+
stats = options[:stats_callbacks]
|
|
47
43
|
stats[:variable_parse].call if stats
|
|
48
44
|
|
|
49
45
|
if Liquid::C.enabled
|
data/lib/liquid/c/version.rb
CHANGED
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 = ["
|
|
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
|
data/test/unit/tokenizer_test.rb
CHANGED
data/test/unit/variable_test.rb
CHANGED
|
@@ -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, [
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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
|
-
-
|
|
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:
|
|
150
|
+
version: 1.3.1
|
|
138
151
|
requirements: []
|
|
139
152
|
rubyforge_project:
|
|
140
|
-
rubygems_version: 2.
|
|
153
|
+
rubygems_version: 2.4.5
|
|
141
154
|
signing_key:
|
|
142
155
|
specification_version: 4
|
|
143
156
|
summary: Liquid performance extension in C
|