sassc 1.10.1 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }