sassc 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/libsass/.gitignore +6 -0
  4. data/ext/libsass/.travis.yml +5 -1
  5. data/ext/libsass/Makefile +12 -3
  6. data/ext/libsass/Makefile.am +16 -28
  7. data/ext/libsass/Readme.md +1 -0
  8. data/ext/libsass/appveyor.yml +1 -2
  9. data/ext/libsass/ast.cpp +9 -0
  10. data/ext/libsass/ast.hpp +152 -55
  11. data/ext/libsass/ast_factory.hpp +2 -0
  12. data/ext/libsass/ast_fwd_decl.hpp +1 -0
  13. data/ext/libsass/backtrace.hpp +2 -2
  14. data/ext/libsass/bind.cpp +15 -13
  15. data/ext/libsass/configure.ac +17 -5
  16. data/ext/libsass/constants.cpp +22 -2
  17. data/ext/libsass/constants.hpp +21 -2
  18. data/ext/libsass/context.cpp +79 -57
  19. data/ext/libsass/context.hpp +23 -9
  20. data/ext/libsass/contextualize.cpp +2 -28
  21. data/ext/libsass/contextualize.hpp +6 -10
  22. data/ext/libsass/contextualize_eval.cpp +93 -0
  23. data/ext/libsass/contextualize_eval.hpp +44 -0
  24. data/ext/libsass/contrib/plugin.cpp +57 -0
  25. data/ext/libsass/cssize.cpp +3 -1
  26. data/ext/libsass/debugger.hpp +242 -83
  27. data/ext/libsass/emitter.cpp +1 -1
  28. data/ext/libsass/emitter.hpp +1 -1
  29. data/ext/libsass/environment.hpp +109 -25
  30. data/ext/libsass/error_handling.cpp +3 -3
  31. data/ext/libsass/error_handling.hpp +0 -1
  32. data/ext/libsass/eval.cpp +145 -61
  33. data/ext/libsass/eval.hpp +9 -1
  34. data/ext/libsass/expand.cpp +134 -60
  35. data/ext/libsass/expand.hpp +5 -2
  36. data/ext/libsass/extend.cpp +7 -5
  37. data/ext/libsass/file.cpp +176 -123
  38. data/ext/libsass/file.hpp +44 -7
  39. data/ext/libsass/functions.cpp +36 -17
  40. data/ext/libsass/functions.hpp +2 -2
  41. data/ext/libsass/inspect.cpp +23 -14
  42. data/ext/libsass/inspect.hpp +1 -0
  43. data/ext/libsass/json.cpp +132 -135
  44. data/ext/libsass/lexer.cpp +133 -0
  45. data/ext/libsass/lexer.hpp +239 -0
  46. data/ext/libsass/listize.cpp +83 -0
  47. data/ext/libsass/listize.hpp +41 -0
  48. data/ext/libsass/operation.hpp +2 -0
  49. data/ext/libsass/output.cpp +5 -6
  50. data/ext/libsass/parser.cpp +426 -388
  51. data/ext/libsass/parser.hpp +97 -109
  52. data/ext/libsass/plugins.cpp +15 -2
  53. data/ext/libsass/plugins.hpp +6 -4
  54. data/ext/libsass/position.cpp +52 -17
  55. data/ext/libsass/position.hpp +19 -17
  56. data/ext/libsass/prelexer.cpp +202 -235
  57. data/ext/libsass/prelexer.hpp +73 -333
  58. data/ext/libsass/sass.cpp +21 -11
  59. data/ext/libsass/sass.h +6 -6
  60. data/ext/libsass/sass_context.cpp +167 -81
  61. data/ext/libsass/sass_context.h +26 -6
  62. data/ext/libsass/sass_functions.cpp +49 -40
  63. data/ext/libsass/sass_functions.h +55 -43
  64. data/ext/libsass/sass_interface.cpp +9 -8
  65. data/ext/libsass/sass_interface.h +3 -3
  66. data/ext/libsass/sass_version.h +8 -0
  67. data/ext/libsass/sass_version.h.in +8 -0
  68. data/ext/libsass/script/ci-build-libsass +3 -3
  69. data/ext/libsass/script/ci-report-coverage +2 -1
  70. data/ext/libsass/source_map.cpp +2 -2
  71. data/ext/libsass/util.cpp +60 -11
  72. data/ext/libsass/util.hpp +6 -1
  73. data/ext/libsass/win/libsass.filters +12 -0
  74. data/ext/libsass/win/libsass.vcxproj +10 -0
  75. data/lib/sassc.rb +3 -1
  76. data/lib/sassc/cache_stores/base.rb +2 -0
  77. data/lib/sassc/dependency.rb +3 -1
  78. data/lib/sassc/engine.rb +31 -16
  79. data/lib/sassc/error.rb +3 -2
  80. data/lib/sassc/functions_handler.rb +54 -0
  81. data/lib/sassc/import_handler.rb +41 -0
  82. data/lib/sassc/importer.rb +4 -31
  83. data/lib/sassc/native.rb +1 -1
  84. data/lib/sassc/native/native_context_api.rb +3 -2
  85. data/lib/sassc/script.rb +0 -51
  86. data/lib/sassc/version.rb +1 -1
  87. data/sassc.gemspec +1 -0
  88. data/test/custom_importer_test.rb +72 -69
  89. data/test/engine_test.rb +53 -54
  90. data/test/functions_test.rb +40 -39
  91. data/test/native_test.rb +145 -149
  92. data/test/output_style_test.rb +98 -0
  93. data/test/test_helper.rb +21 -7
  94. metadata +28 -2
@@ -0,0 +1,133 @@
1
+ #include <cctype>
2
+ #include <cstddef>
3
+ #include <iostream>
4
+ #include <iomanip>
5
+ #include "lexer.hpp"
6
+ #include "constants.hpp"
7
+
8
+
9
+ namespace Sass {
10
+ using namespace Constants;
11
+
12
+ namespace Prelexer {
13
+
14
+ //####################################
15
+ // BASIC CHARACTER MATCHERS
16
+ //####################################
17
+
18
+ // Match standard control chars
19
+ const char* kwd_at(const char* src) { return exactly<'@'>(src); }
20
+ const char* kwd_dot(const char* src) { return exactly<'.'>(src); }
21
+ const char* kwd_comma(const char* src) { return exactly<','>(src); };
22
+ const char* kwd_colon(const char* src) { return exactly<':'>(src); };
23
+ const char* kwd_star(const char* src) { return exactly<'*'>(src); };
24
+ const char* kwd_plus(const char* src) { return exactly<'+'>(src); };
25
+ const char* kwd_minus(const char* src) { return exactly<'-'>(src); };
26
+ const char* kwd_slash(const char* src) { return exactly<'/'>(src); };
27
+
28
+ //####################################
29
+ // implement some function that do exist in the standard
30
+ // but those are locale aware which brought some trouble
31
+ // this even seems to improve performance by quite a bit
32
+ //####################################
33
+
34
+ const bool is_alpha(const char& chr)
35
+ {
36
+ return unsigned(chr - 'A') <= 'Z' - 'A' ||
37
+ unsigned(chr - 'a') <= 'z' - 'a';
38
+ }
39
+
40
+ const bool is_space(const char& chr)
41
+ {
42
+ // adapted the technique from is_alpha
43
+ return chr == ' ' || unsigned(chr - '\t') <= '\r' - '\t';
44
+ }
45
+
46
+ const bool is_digit(const char& chr)
47
+ {
48
+ // adapted the technique from is_alpha
49
+ return unsigned(chr - '0') <= '9' - '0';
50
+ }
51
+
52
+ const bool is_xdigit(const char& chr)
53
+ {
54
+ // adapted the technique from is_alpha
55
+ return unsigned(chr - '0') <= '9' - '0' ||
56
+ unsigned(chr - 'a') <= 'f' - 'a' ||
57
+ unsigned(chr - 'A') <= 'F' - 'A';
58
+ }
59
+
60
+ const bool is_punct(const char& chr)
61
+ {
62
+ // locale independent
63
+ return chr == '.';
64
+ }
65
+
66
+ const bool is_alnum(const char& chr)
67
+ {
68
+ return is_alpha(chr) || is_digit(chr);
69
+ }
70
+
71
+ // check if char is outside ascii range
72
+ const bool is_unicode(const char& chr)
73
+ {
74
+ // check for unicode range
75
+ return unsigned(chr) > 127;
76
+ }
77
+
78
+ // Match word character (look ahead)
79
+ const bool is_character(const char& chr)
80
+ {
81
+ // valid alpha, numeric or unicode char (plus hyphen)
82
+ return is_alnum(chr) || is_unicode(chr) || chr == '-';
83
+ }
84
+
85
+ //####################################
86
+ // BASIC CLASS MATCHERS
87
+ //####################################
88
+
89
+ // create matchers that advance the position
90
+ const char* space(const char* src) { return is_space(*src) ? src + 1 : 0; }
91
+ const char* alpha(const char* src) { return is_alpha(*src) ? src + 1 : 0; }
92
+ const char* unicode(const char* src) { return is_unicode(*src) ? src + 1 : 0; }
93
+ const char* digit(const char* src) { return is_digit(*src) ? src + 1 : 0; }
94
+ const char* xdigit(const char* src) { return is_xdigit(*src) ? src + 1 : 0; }
95
+ const char* alnum(const char* src) { return is_alnum(*src) ? src + 1 : 0; }
96
+ const char* punct(const char* src) { return is_punct(*src) ? src + 1 : 0; }
97
+ const char* character(const char* src) { return is_character(*src) ? src + 1 : 0; }
98
+
99
+ // Match multiple ctype characters.
100
+ const char* spaces(const char* src) { return one_plus<space>(src); }
101
+ const char* digits(const char* src) { return one_plus<digit>(src); }
102
+
103
+ // Whitespace handling.
104
+ const char* no_spaces(const char* src) { return negate< space >(src); }
105
+ const char* optional_spaces(const char* src) { return zero_plus< space >(src); }
106
+
107
+ // Match any single character.
108
+ const char* any_char(const char* src) { return *src ? src + 1 : src; }
109
+
110
+ // Match word boundary (zero-width lookahead).
111
+ const char* word_boundary(const char* src) { return is_character(*src) ? 0 : src; }
112
+
113
+ // Match linefeed /(?:\n|\r\n?)/
114
+ const char* re_linebreak(const char* src)
115
+ {
116
+ // end of file or unix linefeed return here
117
+ if (*src == 0 || *src == '\n') return src + 1;
118
+ // a carriage return may optionally be followed by a linefeed
119
+ if (*src == '\r') return *(src + 1) == '\n' ? src + 2 : src + 1;
120
+ // no linefeed
121
+ return 0;
122
+ }
123
+
124
+ // Assert string boundaries (/\Z|\z|\A/)
125
+ // This is a zero-width positive lookahead
126
+ const char* end_of_line(const char* src)
127
+ {
128
+ // end of file or unix linefeed return here
129
+ return *src == 0 || *src == '\n' || *src == '\r' ? src : 0;
130
+ }
131
+
132
+ }
133
+ }
@@ -0,0 +1,239 @@
1
+ #ifndef SASS_LEXER_H
2
+ #define SASS_LEXER_H
3
+
4
+ #include <cstring>
5
+
6
+ namespace Sass {
7
+ namespace Prelexer {
8
+
9
+ //####################################
10
+ // BASIC CHARACTER MATCHERS
11
+ //####################################
12
+
13
+ // Match standard control chars
14
+ const char* kwd_at(const char* src);
15
+ const char* kwd_dot(const char* src);
16
+ const char* kwd_comma(const char* src);
17
+ const char* kwd_colon(const char* src);
18
+ const char* kwd_star(const char* src);
19
+ const char* kwd_plus(const char* src);
20
+ const char* kwd_minus(const char* src);
21
+ const char* kwd_slash(const char* src);
22
+
23
+ //####################################
24
+ // BASIC CLASS MATCHERS
25
+ //####################################
26
+
27
+ // These are locale independant
28
+ const bool is_space(const char& src);
29
+ const bool is_alpha(const char& src);
30
+ const bool is_punct(const char& src);
31
+ const bool is_digit(const char& src);
32
+ const bool is_alnum(const char& src);
33
+ const bool is_xdigit(const char& src);
34
+ const bool is_unicode(const char& src);
35
+ const bool is_character(const char& src);
36
+
37
+ // Match a single ctype predicate.
38
+ const char* space(const char* src);
39
+ const char* alpha(const char* src);
40
+ const char* digit(const char* src);
41
+ const char* xdigit(const char* src);
42
+ const char* alnum(const char* src);
43
+ const char* punct(const char* src);
44
+ const char* unicode(const char* src);
45
+ const char* character(const char* src);
46
+
47
+ // Match multiple ctype characters.
48
+ const char* spaces(const char* src);
49
+ const char* digits(const char* src);
50
+
51
+ // Whitespace handling.
52
+ const char* no_spaces(const char* src);
53
+ const char* optional_spaces(const char* src);
54
+
55
+ // Match any single character (/./).
56
+ const char* any_char(const char* src);
57
+
58
+ // Assert word boundary (/\b/)
59
+ // Is a zero-width positive lookaheads
60
+ const char* word_boundary(const char* src);
61
+
62
+ // Match a single linebreak (/(?:\n|\r\n?)/).
63
+ const char* re_linebreak(const char* src);
64
+
65
+ // Assert string boundaries (/\Z|\z|\A/)
66
+ // There are zero-width positive lookaheads
67
+ const char* end_of_line(const char* src);
68
+ // const char* end_of_string(const char* src);
69
+ // const char* start_of_string(const char* src);
70
+
71
+ // Type definition for prelexer functions
72
+ typedef const char* (*prelexer)(const char*);
73
+
74
+ //####################################
75
+ // BASIC "REGEX" CONSTRUCTORS
76
+ //####################################
77
+
78
+ // Match a single character literal.
79
+ // Regex equivalent: /(?:literal)/
80
+ template <char chr>
81
+ const char* exactly(const char* src) {
82
+ return *src == chr ? src + 1 : 0;
83
+ }
84
+
85
+ // Match a string constant.
86
+ // Regex equivalent: /[axy]/
87
+ template <const char* str>
88
+ const char* exactly(const char* src) {
89
+ if (str == 0) return 0;
90
+ const char* pre = str;
91
+ if (src == 0) return 0;
92
+ // there is a small chance that the search string
93
+ // is longer than the rest of the string to look at
94
+ while (*pre && *src == *pre) {
95
+ ++src, ++pre;
96
+ }
97
+ return *pre ? 0 : src;
98
+ }
99
+
100
+ // Match for members of char class.
101
+ // Regex equivalent: /[axy]/
102
+ template <const char* char_class>
103
+ const char* class_char(const char* src) {
104
+ const char* cc = char_class;
105
+ while (*cc && *src != *cc) ++cc;
106
+ return *cc ? src + 1 : 0;
107
+ }
108
+
109
+ // Match for members of char class.
110
+ // Regex equivalent: /[axy]/
111
+ template <const char* char_class>
112
+ const char* class_chars(const char* src) {
113
+ const char* p = src;
114
+ while (class_char<char_class>(p)) ++p;
115
+ return p == src ? 0 : p;
116
+ }
117
+
118
+ // Match all except the supplied one.
119
+ // Regex equivalent: /[^x]/
120
+ template <const char chr>
121
+ const char* any_char_but(const char* src) {
122
+ return (*src && *src != chr) ? src + 1 : 0;
123
+ }
124
+
125
+ // Succeeds if the matcher fails.
126
+ // Aka. zero-width negative lookahead.
127
+ // Regex equivalent: /(?!literal)/
128
+ template <prelexer mx>
129
+ const char* negate(const char* src) {
130
+ return mx(src) ? 0 : src;
131
+ }
132
+
133
+ // Succeeds if the matcher succeeds.
134
+ // Aka. zero-width positive lookahead.
135
+ // Regex equivalent: /(?=literal)/
136
+ // just hangs around until we need it
137
+ template <prelexer mx>
138
+ const char* lookahead(const char* src) {
139
+ return mx(src) ? src : 0;
140
+ }
141
+
142
+ // Tries supplied matchers in order.
143
+ // Succeeds if one of them succeeds.
144
+ // Regex equivalent: /(?:FOO|BAR)/
145
+ template <prelexer... mxs>
146
+ const char* alternatives(const char* src) {
147
+ const char* rslt;
148
+ for (prelexer mx : { mxs... }) {
149
+ if ((rslt = mx(src))) return rslt;
150
+ }
151
+ return 0;
152
+ }
153
+
154
+ // Tries supplied matchers in order.
155
+ // Succeeds if all of them succeeds.
156
+ // Regex equivalent: /(?:FOO)(?:BAR)/
157
+ template <prelexer... mxs>
158
+ const char* sequence(const char* src) {
159
+ const char* rslt = src;
160
+ for (prelexer mx : { mxs... }) {
161
+ if (!(rslt = mx(rslt))) return 0;
162
+ }
163
+ return rslt;
164
+ }
165
+
166
+ // Match a pattern or not. Always succeeds.
167
+ // Regex equivalent: /(?:literal)?/
168
+ template <prelexer mx>
169
+ const char* optional(const char* src) {
170
+ const char* p = mx(src);
171
+ return p ? p : src;
172
+ }
173
+
174
+ // Match zero or more of the patterns.
175
+ // Regex equivalent: /(?:literal)*/
176
+ template <prelexer mx>
177
+ const char* zero_plus(const char* src) {
178
+ const char* p = mx(src);
179
+ while (p) src = p, p = mx(src);
180
+ return src;
181
+ }
182
+
183
+ // Match one or more of the patterns.
184
+ // Regex equivalent: /(?:literal)+/
185
+ template <prelexer mx>
186
+ const char* one_plus(const char* src) {
187
+ const char* p = mx(src);
188
+ if (!p) return 0;
189
+ while (p) src = p, p = mx(src);
190
+ return src;
191
+ }
192
+
193
+ // Match mx non-greedy until delimiter.
194
+ // Other prelexers are greedy by default.
195
+ // Regex equivalent: /(?:$mx)*?(?=$delim)\b/
196
+ template <prelexer mx, prelexer delim>
197
+ const char* non_greedy(const char* src) {
198
+ while (!delim(src)) {
199
+ const char* p = mx(src);
200
+ if (p == src) return 0;
201
+ if (p == 0) return 0;
202
+ src = p;
203
+ }
204
+ return src;
205
+ }
206
+
207
+ //####################################
208
+ // ADVANCED "REGEX" CONSTRUCTORS
209
+ //####################################
210
+
211
+ // Match with word boundary rule.
212
+ // Regex equivalent: /(?:$mx)\b/
213
+ template <const char* str>
214
+ const char* word(const char* src) {
215
+ return sequence <
216
+ exactly < str >,
217
+ word_boundary
218
+ >(src);
219
+ }
220
+
221
+ template <char chr>
222
+ const char* loosely(const char* src) {
223
+ return sequence <
224
+ optional_spaces,
225
+ exactly < chr >
226
+ >(src);
227
+ }
228
+ template <const char* str>
229
+ const char* loosely(const char* src) {
230
+ return sequence <
231
+ optional_spaces,
232
+ exactly < str >
233
+ >(src);
234
+ }
235
+
236
+ }
237
+ }
238
+
239
+ #endif
@@ -0,0 +1,83 @@
1
+ #include <iostream>
2
+ #include <typeinfo>
3
+
4
+ #include "listize.hpp"
5
+ #include "to_string.hpp"
6
+ #include "context.hpp"
7
+ #include "backtrace.hpp"
8
+ #include "error_handling.hpp"
9
+
10
+ namespace Sass {
11
+
12
+ Listize::Listize(Context& ctx)
13
+ : ctx(ctx)
14
+ { }
15
+
16
+ Expression* Listize::operator()(Selector_List* sel)
17
+ {
18
+ List* l = new (ctx.mem) List(sel->pstate(), sel->length(), List::COMMA);
19
+ for (size_t i = 0, L = sel->length(); i < L; ++i) {
20
+ *l << (*sel)[i]->perform(this);
21
+ }
22
+ return l;
23
+ }
24
+
25
+ Expression* Listize::operator()(Compound_Selector* sel)
26
+ {
27
+ To_String to_string;
28
+ string str;
29
+ for (size_t i = 0, L = sel->length(); i < L; ++i) {
30
+ Expression* e = (*sel)[i]->perform(this);
31
+ if (e) str += e->perform(&to_string);
32
+ }
33
+ return new (ctx.mem) String_Constant(sel->pstate(), str);
34
+ }
35
+
36
+ Expression* Listize::operator()(Complex_Selector* sel)
37
+ {
38
+ List* l = new (ctx.mem) List(sel->pstate(), 2);
39
+
40
+ Compound_Selector* head = sel->head();
41
+ if (head && !head->is_empty_reference())
42
+ {
43
+ Expression* hh = head->perform(this);
44
+ if (hh) *l << hh;
45
+ }
46
+
47
+ switch(sel->combinator())
48
+ {
49
+ case Complex_Selector::PARENT_OF:
50
+ *l << new (ctx.mem) String_Constant(sel->pstate(), ">");
51
+ break;
52
+ case Complex_Selector::ADJACENT_TO:
53
+ *l << new (ctx.mem) String_Constant(sel->pstate(), "+");
54
+ break;
55
+ case Complex_Selector::PRECEDES:
56
+ *l << new (ctx.mem) String_Constant(sel->pstate(), "~");
57
+ break;
58
+ case Complex_Selector::ANCESTOR_OF:
59
+ break;
60
+ }
61
+
62
+ Complex_Selector* tail = sel->tail();
63
+ if (tail)
64
+ {
65
+ Expression* tt = tail->perform(this);
66
+ if (tt && tt->concrete_type() == Expression::LIST)
67
+ { *l += static_cast<List*>(tt); }
68
+ else if (tt) *l << static_cast<List*>(tt);
69
+ }
70
+ if (l->length() == 0) return 0;
71
+ return l;
72
+ }
73
+
74
+ Expression* Listize::operator()(Selector_Reference* sel)
75
+ {
76
+ return 0;
77
+ }
78
+
79
+ Expression* Listize::fallback_impl(AST_Node* n)
80
+ {
81
+ return static_cast<Expression*>(n);
82
+ }
83
+ }