sassc 1.10.1 → 1.11.0

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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -2
  3. data/ext/libsass/.github/CONTRIBUTING.md +65 -0
  4. data/ext/libsass/.github/ISSUE_TEMPLATE.md +29 -0
  5. data/ext/libsass/Makefile +8 -3
  6. data/ext/libsass/Makefile.conf +28 -22
  7. data/ext/libsass/Readme.md +14 -7
  8. data/ext/libsass/configure.ac +5 -8
  9. data/ext/libsass/docs/api-context-internal.md +3 -0
  10. data/ext/libsass/docs/api-context.md +7 -0
  11. data/ext/libsass/docs/api-doc.md +4 -0
  12. data/ext/libsass/docs/api-importer.md +2 -0
  13. data/ext/libsass/docs/api-value-example.md +55 -0
  14. data/ext/libsass/docs/api-value.md +49 -22
  15. data/ext/libsass/docs/implementations.md +4 -0
  16. data/ext/libsass/include/sass/base.h +5 -4
  17. data/ext/libsass/include/sass/context.h +3 -0
  18. data/ext/libsass/include/sass/values.h +28 -27
  19. data/ext/libsass/include/sass/version.h +1 -1
  20. data/ext/libsass/include/sass2scss.h +1 -1
  21. data/ext/libsass/script/ci-build-libsass +3 -3
  22. data/ext/libsass/script/ci-install-deps +12 -3
  23. data/ext/libsass/src/ast.cpp +321 -212
  24. data/ext/libsass/src/ast.hpp +273 -165
  25. data/ext/libsass/src/ast_factory.hpp +4 -5
  26. data/ext/libsass/src/ast_fwd_decl.hpp +8 -7
  27. data/ext/libsass/src/bind.cpp +2 -7
  28. data/ext/libsass/src/bind.hpp +0 -1
  29. data/ext/libsass/src/check_nesting.cpp +379 -0
  30. data/ext/libsass/src/check_nesting.hpp +60 -0
  31. data/ext/libsass/src/constants.cpp +7 -6
  32. data/ext/libsass/src/constants.hpp +2 -1
  33. data/ext/libsass/src/context.cpp +7 -1
  34. data/ext/libsass/src/context.hpp +1 -1
  35. data/ext/libsass/src/cssize.cpp +76 -32
  36. data/ext/libsass/src/cssize.hpp +7 -8
  37. data/ext/libsass/src/debugger.hpp +70 -40
  38. data/ext/libsass/src/error_handling.cpp +15 -2
  39. data/ext/libsass/src/error_handling.hpp +19 -0
  40. data/ext/libsass/src/eval.cpp +107 -161
  41. data/ext/libsass/src/eval.hpp +12 -8
  42. data/ext/libsass/src/expand.cpp +81 -74
  43. data/ext/libsass/src/expand.hpp +13 -12
  44. data/ext/libsass/src/extend.cpp +149 -142
  45. data/ext/libsass/src/extend.hpp +10 -3
  46. data/ext/libsass/src/file.cpp +2 -1
  47. data/ext/libsass/src/functions.cpp +96 -59
  48. data/ext/libsass/src/functions.hpp +2 -2
  49. data/ext/libsass/src/inspect.cpp +33 -45
  50. data/ext/libsass/src/inspect.hpp +7 -7
  51. data/ext/libsass/src/json.cpp +17 -5
  52. data/ext/libsass/src/lexer.cpp +3 -3
  53. data/ext/libsass/src/listize.cpp +10 -10
  54. data/ext/libsass/src/listize.hpp +3 -3
  55. data/ext/libsass/src/node.cpp +30 -30
  56. data/ext/libsass/src/node.hpp +13 -13
  57. data/ext/libsass/src/operation.hpp +21 -19
  58. data/ext/libsass/src/output.cpp +48 -103
  59. data/ext/libsass/src/output.hpp +0 -1
  60. data/ext/libsass/src/parser.cpp +161 -133
  61. data/ext/libsass/src/parser.hpp +10 -7
  62. data/ext/libsass/src/remove_placeholders.cpp +6 -6
  63. data/ext/libsass/src/remove_placeholders.hpp +1 -1
  64. data/ext/libsass/src/sass.cpp +21 -0
  65. data/ext/libsass/src/sass.hpp +8 -1
  66. data/ext/libsass/src/sass2scss.cpp +14 -3
  67. data/ext/libsass/src/sass_context.cpp +69 -24
  68. data/ext/libsass/src/sass_context.hpp +3 -0
  69. data/ext/libsass/src/source_map.cpp +22 -10
  70. data/ext/libsass/src/to_value.cpp +2 -2
  71. data/ext/libsass/src/to_value.hpp +1 -1
  72. data/ext/libsass/src/units.hpp +3 -1
  73. data/ext/libsass/src/util.cpp +20 -16
  74. data/ext/libsass/src/util.hpp +2 -1
  75. data/ext/libsass/win/libsass.targets +2 -0
  76. data/ext/libsass/win/libsass.vcxproj.filters +6 -0
  77. data/lib/sassc/engine.rb +5 -0
  78. data/lib/sassc/native/native_functions_api.rb +13 -1
  79. data/lib/sassc/script/value_conversion.rb +11 -1
  80. data/lib/sassc/script/value_conversion/list.rb +23 -0
  81. data/lib/sassc/version.rb +1 -1
  82. data/test/engine_test.rb +18 -2
  83. data/test/functions_test.rb +30 -0
  84. data/test/native_test.rb +1 -1
  85. metadata +8 -3
@@ -13,13 +13,12 @@ namespace Sass {
13
13
  // statements
14
14
  Block* new_Block(std::string p, size_t l, size_t s = 0, bool r = false);
15
15
  Ruleset* new_Ruleset(std::string p, size_t l, Selector* s, Block* b);
16
- Propset* new_Propset(std::string p, size_t l, String* pf, Block* b);
17
16
  Supports_Query* new_Supports_Query(std::string p, size_t l, Supports_Query* f, Block* b);
18
17
  Media_Query* new_Media_Query(std::string p, size_t l, List* q, Block* b);
19
18
  At_Root_Block* new_At_Root_Block(std::string p, size_t l, Selector* sel, Block* b);
20
19
  Directive* new_At_Rule(std::string p, size_t l, std::string kwd, Selector* sel, Block* b);
21
20
  Keyframe_Rule* new_Keyframe_Rule(std::string p, size_t l, Block* b);
22
- Declaration* new_Declaration(std::string p, size_t l, String* prop, List* vals);
21
+ Declaration* new_Declaration(std::string p, size_t l, String* prop, List* vals, Block* b);
23
22
  Assignment* new_Assignment(std::string p, size_t l, std::string var, Expression* val, bool guarded = false);
24
23
  Import<Function_Call*>* new_CSS_Import(std::string p, size_t l, Function_Call* loc);
25
24
  Import<String*>* new_SASS_Import(std::string p, size_t l, String* loc);
@@ -84,9 +83,9 @@ namespace Sass {
84
83
  Placeholder_Selector* new_Placeholder_Selector(std::string p, size_t l, std::string n);
85
84
  Pseudo_Selector* new_Pseudo_Selector(std::string p, size_t l, std::string n, Expression* expr = 0);
86
85
  Wrapped_Selector* new_Wrapped_Selector(std::string p, size_t l, std::string n, Simple_Base* sel);
87
- Compound_Selector* new_Compound_Selector(std::string p, size_t l, size_t s = 0);
88
- Complex_Selector* new_Complex_Selector(std::string p, size_t l, Complex_Selector::Combinator c, Complex_Selector* ctx, Compound_Selector* sel);
89
- Selector_List* new_Selector_List(std::string p, size_t l, size_t s = 0);
86
+ SimpleSequence_Selector* new_SimpleSequence_Selector(std::string p, size_t l, size_t s = 0);
87
+ Sequence_Selector* new_Sequence_Selector(std::string p, size_t l, Sequence_Selector::Combinator c, Sequence_Selector* ctx, SimpleSequence_Selector* sel);
88
+ CommaSequence_Selector* new_CommaSequence_Selector(std::string p, size_t l, size_t s = 0);
90
89
  };
91
90
  }
92
91
 
@@ -11,8 +11,8 @@ namespace Sass {
11
11
  class Statement;
12
12
  class Block;
13
13
  class Ruleset;
14
- class Propset;
15
14
  class Bubble;
15
+ class Trace;
16
16
  class Media_Block;
17
17
  class Supports_Block;
18
18
  class Directive;
@@ -73,15 +73,16 @@ namespace Sass {
73
73
  // selectors
74
74
  class Selector;
75
75
  class Selector_Schema;
76
- class Selector_Placeholder;
77
- class Type_Selector;
78
- class Selector_Qualifier;
76
+ class Placeholder_Selector;
77
+ class Element_Selector;
78
+ class Class_Selector;
79
+ class Id_Selector;
79
80
  class Attribute_Selector;
80
81
  class Pseudo_Selector;
81
82
  class Wrapped_Selector;
82
- class Compound_Selector;
83
- class Complex_Selector;
84
- class Selector_List;
83
+ class SimpleSequence_Selector;
84
+ class Sequence_Selector;
85
+ class CommaSequence_Selector;
85
86
 
86
87
  // common classes
87
88
  class Context;
@@ -13,7 +13,6 @@ namespace Sass {
13
13
  {
14
14
  std::string callee(type + " " + name);
15
15
 
16
- Listize listize(ctx->mem);
17
16
  std::map<std::string, Parameter*> param_map;
18
17
 
19
18
  for (size_t i = 0, L = as->length(); i < L; ++i) {
@@ -21,7 +20,6 @@ namespace Sass {
21
20
  // force optional quotes (only if needed)
22
21
  if (str->quote_mark()) {
23
22
  str->quote_mark('*');
24
- str->is_delayed(true);
25
23
  }
26
24
  }
27
25
  }
@@ -172,7 +170,7 @@ namespace Sass {
172
170
  break;
173
171
  } else {
174
172
  if (arglist->length() > LP - ip && !ps->has_rest_parameter()) {
175
- int arg_count = (arglist->length() + LA - 1);
173
+ size_t arg_count = (arglist->length() + LA - 1);
176
174
  std::stringstream msg;
177
175
  msg << callee << " takes " << LP;
178
176
  msg << (LP == 1 ? " argument" : " arguments");
@@ -276,10 +274,7 @@ namespace Sass {
276
274
  }
277
275
  else {
278
276
  // param is unbound and has no default value -- error
279
- std::stringstream msg;
280
- msg << "required parameter " << leftover->name()
281
- << " is missing in call to " << callee;
282
- error(msg.str(), as->pstate());
277
+ throw Exception::MissingArgument(as->pstate(), name, leftover->name(), type);
283
278
  }
284
279
  }
285
280
  }
@@ -2,7 +2,6 @@
2
2
  #define SASS_BIND_H
3
3
 
4
4
  #include <string>
5
- #include "listize.hpp"
6
5
  #include "environment.hpp"
7
6
 
8
7
  namespace Sass {
@@ -0,0 +1,379 @@
1
+ #include "sass.hpp"
2
+ #include <vector>
3
+
4
+ #include "check_nesting.hpp"
5
+
6
+ namespace Sass {
7
+
8
+ CheckNesting::CheckNesting()
9
+ : parents(std::vector<Statement*>()),
10
+ parent(0),
11
+ current_mixin_definition(0)
12
+ { }
13
+
14
+ Statement* CheckNesting::before(Statement* s) {
15
+ if (this->should_visit(s)) return s;
16
+ return 0;
17
+ }
18
+
19
+ Statement* CheckNesting::visit_children(Statement* parent) {
20
+
21
+ Statement* old_parent = this->parent;
22
+
23
+ if (dynamic_cast<At_Root_Block*>(parent)) {
24
+ std::vector<Statement*> old_parents = this->parents;
25
+ std::vector<Statement*> new_parents;
26
+
27
+ for (size_t i = 0, L = this->parents.size(); i < L; i++) {
28
+ Statement* p = this->parents.at(i);
29
+ if (!dynamic_cast<At_Root_Block*>(parent)->exclude_node(p)) {
30
+ new_parents.push_back(p);
31
+ }
32
+ }
33
+ this->parents = new_parents;
34
+
35
+ for (size_t i = this->parents.size(); i > 0; i--) {
36
+ Statement* p = 0;
37
+ Statement* gp = 0;
38
+ if (i > 0) p = this->parents.at(i - 1);
39
+ if (i > 1) gp = this->parents.at(i - 2);
40
+
41
+ if (!this->is_transparent_parent(p, gp)) {
42
+ this->parent = p;
43
+ break;
44
+ }
45
+ }
46
+
47
+ At_Root_Block* ar = dynamic_cast<At_Root_Block*>(parent);
48
+ Statement* ret = this->visit_children(ar->block());
49
+
50
+ this->parent = old_parent;
51
+ this->parents = old_parents;
52
+
53
+ return ret;
54
+ }
55
+
56
+
57
+ if (!this->is_transparent_parent(parent, old_parent)) {
58
+ this->parent = parent;
59
+ }
60
+
61
+ this->parents.push_back(parent);
62
+
63
+ Block* b = dynamic_cast<Block*>(parent);
64
+
65
+ if (!b) {
66
+ if (Has_Block* bb = dynamic_cast<Has_Block*>(parent)) {
67
+ b = bb->block();
68
+ }
69
+ }
70
+
71
+ if (b) {
72
+ for (auto n : *b) {
73
+ n->perform(this);
74
+ }
75
+ }
76
+
77
+ this->parent = old_parent;
78
+ this->parents.pop_back();
79
+
80
+ return b;
81
+ }
82
+
83
+
84
+ Statement* CheckNesting::operator()(Block* b)
85
+ {
86
+ return this->visit_children(b);
87
+ }
88
+
89
+ Statement* CheckNesting::operator()(Definition* n)
90
+ {
91
+ if (!is_mixin(n)) return n;
92
+
93
+ Definition* old_mixin_definition = this->current_mixin_definition;
94
+ this->current_mixin_definition = n;
95
+
96
+ visit_children(n);
97
+
98
+ this->current_mixin_definition = old_mixin_definition;
99
+
100
+ return n;
101
+ }
102
+
103
+ Statement* CheckNesting::fallback_impl(Statement* s)
104
+ {
105
+ if (dynamic_cast<Block*>(s) || dynamic_cast<Has_Block*>(s)) {
106
+ return visit_children(s);
107
+ }
108
+ return s;
109
+ }
110
+
111
+ bool CheckNesting::should_visit(Statement* node)
112
+ {
113
+ if (!this->parent) return true;
114
+
115
+ if (dynamic_cast<Content*>(node))
116
+ { this->invalid_content_parent(this->parent); }
117
+
118
+ if (is_charset(node))
119
+ { this->invalid_charset_parent(this->parent); }
120
+
121
+ if (dynamic_cast<Extension*>(node))
122
+ { this->invalid_extend_parent(this->parent); }
123
+
124
+ // if (dynamic_cast<Import*>(node))
125
+ // { this->invalid_import_parent(this->parent); }
126
+
127
+ if (this->is_mixin(node))
128
+ { this->invalid_mixin_definition_parent(this->parent); }
129
+
130
+ if (this->is_function(node))
131
+ { this->invalid_function_parent(this->parent); }
132
+
133
+ if (this->is_function(this->parent))
134
+ { this->invalid_function_child(node); }
135
+
136
+ if (dynamic_cast<Declaration*>(node))
137
+ { this->invalid_prop_parent(this->parent); }
138
+
139
+ if (
140
+ dynamic_cast<Declaration*>(this->parent)
141
+ ) { this->invalid_prop_child(node); }
142
+
143
+ if (dynamic_cast<Return*>(node))
144
+ { this->invalid_return_parent(this->parent); }
145
+
146
+ return true;
147
+ }
148
+
149
+ void CheckNesting::invalid_content_parent(Statement* parent)
150
+ {
151
+ if (!this->current_mixin_definition) {
152
+ throw Exception::InvalidSass(
153
+ parent->pstate(),
154
+ "@content may only be used within a mixin."
155
+ );
156
+ }
157
+ }
158
+
159
+ void CheckNesting::invalid_charset_parent(Statement* parent)
160
+ {
161
+ if (!(
162
+ is_root_node(parent)
163
+ )) {
164
+ throw Exception::InvalidSass(
165
+ parent->pstate(),
166
+ "@charset may only be used at the root of a document."
167
+ );
168
+ }
169
+ }
170
+
171
+ void CheckNesting::invalid_extend_parent(Statement* parent)
172
+ {
173
+ if (!(
174
+ dynamic_cast<Ruleset*>(parent) ||
175
+ dynamic_cast<Mixin_Call*>(parent) ||
176
+ is_mixin(parent)
177
+ )) {
178
+ throw Exception::InvalidSass(
179
+ parent->pstate(),
180
+ "Extend directives may only be used within rules."
181
+ );
182
+ }
183
+ }
184
+
185
+ // void CheckNesting::invalid_import_parent(Statement* parent)
186
+ // {
187
+ // for (auto pp : this->parents) {
188
+ // if (
189
+ // dynamic_cast<Each*>(pp) ||
190
+ // dynamic_cast<For*>(pp) ||
191
+ // dynamic_cast<If*>(pp) ||
192
+ // dynamic_cast<While*>(pp) ||
193
+ // dynamic_cast<Trace*>(pp) ||
194
+ // dynamic_cast<Mixin_Call*>(pp) ||
195
+ // is_mixin(pp)
196
+ // ) {
197
+ // throw Exception::InvalidSass(
198
+ // parent->pstate(),
199
+ // "Import directives may not be defined within control directives or other mixins."
200
+ // );
201
+ // }
202
+ // }
203
+
204
+ // if (this->is_root_node(parent)) {
205
+ // return;
206
+ // }
207
+
208
+ // if (false/*n.css_import?*/) {
209
+ // throw Exception::InvalidSass(
210
+ // parent->pstate(),
211
+ // "CSS import directives may only be used at the root of a document."
212
+ // );
213
+ // }
214
+ // }
215
+
216
+ void CheckNesting::invalid_mixin_definition_parent(Statement* parent)
217
+ {
218
+ for (auto pp : this->parents) {
219
+ if (
220
+ dynamic_cast<Each*>(pp) ||
221
+ dynamic_cast<For*>(pp) ||
222
+ dynamic_cast<If*>(pp) ||
223
+ dynamic_cast<While*>(pp) ||
224
+ dynamic_cast<Trace*>(pp) ||
225
+ dynamic_cast<Mixin_Call*>(pp) ||
226
+ is_mixin(pp)
227
+ ) {
228
+ throw Exception::InvalidSass(
229
+ parent->pstate(),
230
+ "Mixins may not be defined within control directives or other mixins."
231
+ );
232
+ }
233
+ }
234
+ }
235
+
236
+ void CheckNesting::invalid_function_parent(Statement* parent)
237
+ {
238
+ for (auto pp : this->parents) {
239
+ if (
240
+ dynamic_cast<Each*>(pp) ||
241
+ dynamic_cast<For*>(pp) ||
242
+ dynamic_cast<If*>(pp) ||
243
+ dynamic_cast<While*>(pp) ||
244
+ dynamic_cast<Trace*>(pp) ||
245
+ dynamic_cast<Mixin_Call*>(pp) ||
246
+ is_mixin(pp)
247
+ ) {
248
+ throw Exception::InvalidSass(
249
+ parent->pstate(),
250
+ "Functions may not be defined within control directives or other mixins."
251
+ );
252
+ }
253
+ }
254
+ }
255
+
256
+ void CheckNesting::invalid_function_child(Statement* child)
257
+ {
258
+ if (!(
259
+ dynamic_cast<Each*>(child) ||
260
+ dynamic_cast<For*>(child) ||
261
+ dynamic_cast<If*>(child) ||
262
+ dynamic_cast<While*>(child) ||
263
+ dynamic_cast<Trace*>(child) ||
264
+ dynamic_cast<Comment*>(child) ||
265
+ dynamic_cast<Debug*>(child) ||
266
+ dynamic_cast<Return*>(child) ||
267
+ dynamic_cast<Variable*>(child) ||
268
+ dynamic_cast<Warning*>(child) ||
269
+ dynamic_cast<Error*>(child)
270
+ )) {
271
+ throw Exception::InvalidSass(
272
+ child->pstate(),
273
+ "Functions can only contain variable declarations and control directives."
274
+ );
275
+ }
276
+ }
277
+
278
+ void CheckNesting::invalid_prop_child(Statement* child)
279
+ {
280
+ if (!(
281
+ dynamic_cast<Each*>(child) ||
282
+ dynamic_cast<For*>(child) ||
283
+ dynamic_cast<If*>(child) ||
284
+ dynamic_cast<While*>(child) ||
285
+ dynamic_cast<Trace*>(child) ||
286
+ dynamic_cast<Comment*>(child) ||
287
+ dynamic_cast<Declaration*>(child) ||
288
+ dynamic_cast<Mixin_Call*>(child)
289
+ )) {
290
+ throw Exception::InvalidSass(
291
+ child->pstate(),
292
+ "Illegal nesting: Only properties may be nested beneath properties."
293
+ );
294
+ }
295
+ }
296
+
297
+ void CheckNesting::invalid_prop_parent(Statement* parent)
298
+ {
299
+ if (!(
300
+ is_mixin(parent) ||
301
+ is_directive_node(parent) ||
302
+ dynamic_cast<Ruleset*>(parent) ||
303
+ dynamic_cast<Keyframe_Rule*>(parent) ||
304
+ dynamic_cast<Declaration*>(parent) ||
305
+ dynamic_cast<Mixin_Call*>(parent)
306
+ )) {
307
+ throw Exception::InvalidSass(
308
+ parent->pstate(),
309
+ "Properties are only allowed within rules, directives, mixin includes, or other properties."
310
+ );
311
+ }
312
+ }
313
+
314
+ void CheckNesting::invalid_return_parent(Statement* parent)
315
+ {
316
+ if (!this->is_function(parent)) {
317
+ throw Exception::InvalidSass(
318
+ parent->pstate(),
319
+ "@return may only be used within a function."
320
+ );
321
+ }
322
+ }
323
+
324
+ bool CheckNesting::is_transparent_parent(Statement* parent, Statement* grandparent)
325
+ {
326
+ bool parent_bubbles = parent && parent->bubbles();
327
+
328
+ bool valid_bubble_node = parent_bubbles &&
329
+ !is_root_node(grandparent) &&
330
+ !is_at_root_node(grandparent);
331
+
332
+ return dynamic_cast<Import*>(parent) ||
333
+ dynamic_cast<Each*>(parent) ||
334
+ dynamic_cast<For*>(parent) ||
335
+ dynamic_cast<If*>(parent) ||
336
+ dynamic_cast<While*>(parent) ||
337
+ dynamic_cast<Trace*>(parent) ||
338
+ valid_bubble_node;
339
+ }
340
+
341
+ bool CheckNesting::is_charset(Statement* n)
342
+ {
343
+ Directive* d = dynamic_cast<Directive*>(n);
344
+ return d && d->keyword() == "charset";
345
+ }
346
+
347
+ bool CheckNesting::is_mixin(Statement* n)
348
+ {
349
+ Definition* def = dynamic_cast<Definition*>(n);
350
+ return def && def->type() == Definition::MIXIN;
351
+ }
352
+
353
+ bool CheckNesting::is_function(Statement* n)
354
+ {
355
+ Definition* def = dynamic_cast<Definition*>(n);
356
+ return def && def->type() == Definition::FUNCTION;
357
+ }
358
+
359
+ bool CheckNesting::is_root_node(Statement* n)
360
+ {
361
+ if (dynamic_cast<Ruleset*>(n)) return false;
362
+
363
+ Block* b = dynamic_cast<Block*>(n);
364
+ return b && b->is_root();
365
+ }
366
+
367
+ bool CheckNesting::is_at_root_node(Statement* n)
368
+ {
369
+ return dynamic_cast<At_Root_Block*>(n) != NULL;
370
+ }
371
+
372
+ bool CheckNesting::is_directive_node(Statement* n)
373
+ {
374
+ return dynamic_cast<Directive*>(n) ||
375
+ dynamic_cast<Import*>(n) ||
376
+ dynamic_cast<Media_Block*>(n) ||
377
+ dynamic_cast<Supports_Block*>(n);
378
+ }
379
+ }