sassc4 2.4.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 (216) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +16 -0
  5. data/CHANGELOG.md +97 -0
  6. data/CODE_OF_CONDUCT.md +10 -0
  7. data/Gemfile +2 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +80 -0
  10. data/Rakefile +51 -0
  11. data/ext/depend +4 -0
  12. data/ext/extconf.rb +92 -0
  13. data/ext/libsass/VERSION +1 -0
  14. data/ext/libsass/contrib/plugin.cpp +60 -0
  15. data/ext/libsass/include/sass/base.h +97 -0
  16. data/ext/libsass/include/sass/context.h +174 -0
  17. data/ext/libsass/include/sass/functions.h +139 -0
  18. data/ext/libsass/include/sass/values.h +145 -0
  19. data/ext/libsass/include/sass/version.h +12 -0
  20. data/ext/libsass/include/sass.h +15 -0
  21. data/ext/libsass/include/sass2scss.h +120 -0
  22. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  23. data/ext/libsass/src/ast.cpp +953 -0
  24. data/ext/libsass/src/ast.hpp +1064 -0
  25. data/ext/libsass/src/ast2c.cpp +80 -0
  26. data/ext/libsass/src/ast2c.hpp +39 -0
  27. data/ext/libsass/src/ast_def_macros.hpp +140 -0
  28. data/ext/libsass/src/ast_fwd_decl.cpp +31 -0
  29. data/ext/libsass/src/ast_fwd_decl.hpp +274 -0
  30. data/ext/libsass/src/ast_helpers.hpp +316 -0
  31. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  32. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  33. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  34. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  35. data/ext/libsass/src/ast_selectors.cpp +1070 -0
  36. data/ext/libsass/src/ast_selectors.hpp +523 -0
  37. data/ext/libsass/src/ast_supports.cpp +114 -0
  38. data/ext/libsass/src/ast_supports.hpp +121 -0
  39. data/ext/libsass/src/ast_values.cpp +1154 -0
  40. data/ext/libsass/src/ast_values.hpp +498 -0
  41. data/ext/libsass/src/b64/cencode.h +32 -0
  42. data/ext/libsass/src/b64/encode.h +79 -0
  43. data/ext/libsass/src/backtrace.cpp +50 -0
  44. data/ext/libsass/src/backtrace.hpp +29 -0
  45. data/ext/libsass/src/base64vlq.cpp +47 -0
  46. data/ext/libsass/src/base64vlq.hpp +30 -0
  47. data/ext/libsass/src/bind.cpp +312 -0
  48. data/ext/libsass/src/bind.hpp +15 -0
  49. data/ext/libsass/src/c2ast.cpp +64 -0
  50. data/ext/libsass/src/c2ast.hpp +14 -0
  51. data/ext/libsass/src/c99func.c +54 -0
  52. data/ext/libsass/src/cencode.c +106 -0
  53. data/ext/libsass/src/check_nesting.cpp +393 -0
  54. data/ext/libsass/src/check_nesting.hpp +70 -0
  55. data/ext/libsass/src/color_maps.cpp +652 -0
  56. data/ext/libsass/src/color_maps.hpp +323 -0
  57. data/ext/libsass/src/color_spaces.cpp +241 -0
  58. data/ext/libsass/src/color_spaces.hpp +227 -0
  59. data/ext/libsass/src/constants.cpp +199 -0
  60. data/ext/libsass/src/constants.hpp +200 -0
  61. data/ext/libsass/src/context.cpp +870 -0
  62. data/ext/libsass/src/context.hpp +140 -0
  63. data/ext/libsass/src/cssize.cpp +521 -0
  64. data/ext/libsass/src/cssize.hpp +71 -0
  65. data/ext/libsass/src/dart_helpers.hpp +199 -0
  66. data/ext/libsass/src/debug.hpp +43 -0
  67. data/ext/libsass/src/debugger.hpp +964 -0
  68. data/ext/libsass/src/emitter.cpp +297 -0
  69. data/ext/libsass/src/emitter.hpp +101 -0
  70. data/ext/libsass/src/environment.cpp +260 -0
  71. data/ext/libsass/src/environment.hpp +124 -0
  72. data/ext/libsass/src/error_handling.cpp +239 -0
  73. data/ext/libsass/src/error_handling.hpp +248 -0
  74. data/ext/libsass/src/eval.cpp +1543 -0
  75. data/ext/libsass/src/eval.hpp +110 -0
  76. data/ext/libsass/src/eval_selectors.cpp +75 -0
  77. data/ext/libsass/src/expand.cpp +875 -0
  78. data/ext/libsass/src/expand.hpp +98 -0
  79. data/ext/libsass/src/extender.cpp +1226 -0
  80. data/ext/libsass/src/extender.hpp +399 -0
  81. data/ext/libsass/src/extension.cpp +43 -0
  82. data/ext/libsass/src/extension.hpp +89 -0
  83. data/ext/libsass/src/file.cpp +531 -0
  84. data/ext/libsass/src/file.hpp +124 -0
  85. data/ext/libsass/src/fn_colors.cpp +836 -0
  86. data/ext/libsass/src/fn_colors.hpp +99 -0
  87. data/ext/libsass/src/fn_lists.cpp +285 -0
  88. data/ext/libsass/src/fn_lists.hpp +34 -0
  89. data/ext/libsass/src/fn_maps.cpp +94 -0
  90. data/ext/libsass/src/fn_maps.hpp +30 -0
  91. data/ext/libsass/src/fn_miscs.cpp +248 -0
  92. data/ext/libsass/src/fn_miscs.hpp +40 -0
  93. data/ext/libsass/src/fn_numbers.cpp +246 -0
  94. data/ext/libsass/src/fn_numbers.hpp +45 -0
  95. data/ext/libsass/src/fn_selectors.cpp +205 -0
  96. data/ext/libsass/src/fn_selectors.hpp +35 -0
  97. data/ext/libsass/src/fn_strings.cpp +268 -0
  98. data/ext/libsass/src/fn_strings.hpp +34 -0
  99. data/ext/libsass/src/fn_utils.cpp +159 -0
  100. data/ext/libsass/src/fn_utils.hpp +62 -0
  101. data/ext/libsass/src/inspect.cpp +1126 -0
  102. data/ext/libsass/src/inspect.hpp +101 -0
  103. data/ext/libsass/src/json.cpp +1436 -0
  104. data/ext/libsass/src/json.hpp +117 -0
  105. data/ext/libsass/src/kwd_arg_macros.hpp +28 -0
  106. data/ext/libsass/src/lexer.cpp +122 -0
  107. data/ext/libsass/src/lexer.hpp +304 -0
  108. data/ext/libsass/src/listize.cpp +70 -0
  109. data/ext/libsass/src/listize.hpp +37 -0
  110. data/ext/libsass/src/mapping.hpp +19 -0
  111. data/ext/libsass/src/memory/allocator.cpp +48 -0
  112. data/ext/libsass/src/memory/allocator.hpp +138 -0
  113. data/ext/libsass/src/memory/config.hpp +20 -0
  114. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  115. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  116. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  117. data/ext/libsass/src/memory.hpp +12 -0
  118. data/ext/libsass/src/operation.hpp +223 -0
  119. data/ext/libsass/src/operators.cpp +267 -0
  120. data/ext/libsass/src/operators.hpp +30 -0
  121. data/ext/libsass/src/ordered_map.hpp +112 -0
  122. data/ext/libsass/src/output.cpp +320 -0
  123. data/ext/libsass/src/output.hpp +47 -0
  124. data/ext/libsass/src/parser.cpp +3059 -0
  125. data/ext/libsass/src/parser.hpp +395 -0
  126. data/ext/libsass/src/parser_selectors.cpp +189 -0
  127. data/ext/libsass/src/permutate.hpp +164 -0
  128. data/ext/libsass/src/plugins.cpp +188 -0
  129. data/ext/libsass/src/plugins.hpp +57 -0
  130. data/ext/libsass/src/position.cpp +163 -0
  131. data/ext/libsass/src/position.hpp +147 -0
  132. data/ext/libsass/src/prelexer.cpp +1780 -0
  133. data/ext/libsass/src/prelexer.hpp +484 -0
  134. data/ext/libsass/src/remove_placeholders.cpp +86 -0
  135. data/ext/libsass/src/remove_placeholders.hpp +37 -0
  136. data/ext/libsass/src/sass.cpp +156 -0
  137. data/ext/libsass/src/sass.hpp +147 -0
  138. data/ext/libsass/src/sass2scss.cpp +895 -0
  139. data/ext/libsass/src/sass_context.cpp +742 -0
  140. data/ext/libsass/src/sass_context.hpp +129 -0
  141. data/ext/libsass/src/sass_functions.cpp +210 -0
  142. data/ext/libsass/src/sass_functions.hpp +50 -0
  143. data/ext/libsass/src/sass_values.cpp +362 -0
  144. data/ext/libsass/src/sass_values.hpp +82 -0
  145. data/ext/libsass/src/settings.hpp +19 -0
  146. data/ext/libsass/src/source.cpp +69 -0
  147. data/ext/libsass/src/source.hpp +95 -0
  148. data/ext/libsass/src/source_data.hpp +32 -0
  149. data/ext/libsass/src/source_map.cpp +202 -0
  150. data/ext/libsass/src/source_map.hpp +65 -0
  151. data/ext/libsass/src/stylesheet.cpp +22 -0
  152. data/ext/libsass/src/stylesheet.hpp +57 -0
  153. data/ext/libsass/src/to_value.cpp +114 -0
  154. data/ext/libsass/src/to_value.hpp +46 -0
  155. data/ext/libsass/src/units.cpp +507 -0
  156. data/ext/libsass/src/units.hpp +110 -0
  157. data/ext/libsass/src/utf8/checked.h +336 -0
  158. data/ext/libsass/src/utf8/core.h +332 -0
  159. data/ext/libsass/src/utf8/unchecked.h +235 -0
  160. data/ext/libsass/src/utf8.h +34 -0
  161. data/ext/libsass/src/utf8_string.cpp +104 -0
  162. data/ext/libsass/src/utf8_string.hpp +38 -0
  163. data/ext/libsass/src/util.cpp +723 -0
  164. data/ext/libsass/src/util.hpp +105 -0
  165. data/ext/libsass/src/util_string.cpp +125 -0
  166. data/ext/libsass/src/util_string.hpp +73 -0
  167. data/ext/libsass/src/values.cpp +140 -0
  168. data/ext/libsass/src/values.hpp +12 -0
  169. data/lib/sassc/dependency.rb +17 -0
  170. data/lib/sassc/engine.rb +141 -0
  171. data/lib/sassc/error.rb +37 -0
  172. data/lib/sassc/functions_handler.rb +73 -0
  173. data/lib/sassc/import_handler.rb +50 -0
  174. data/lib/sassc/importer.rb +31 -0
  175. data/lib/sassc/native/native_context_api.rb +147 -0
  176. data/lib/sassc/native/native_functions_api.rb +159 -0
  177. data/lib/sassc/native/sass2scss_api.rb +10 -0
  178. data/lib/sassc/native/sass_input_style.rb +13 -0
  179. data/lib/sassc/native/sass_output_style.rb +12 -0
  180. data/lib/sassc/native/sass_value.rb +97 -0
  181. data/lib/sassc/native/string_list.rb +10 -0
  182. data/lib/sassc/native.rb +64 -0
  183. data/lib/sassc/sass_2_scss.rb +9 -0
  184. data/lib/sassc/script/functions.rb +8 -0
  185. data/lib/sassc/script/value/bool.rb +32 -0
  186. data/lib/sassc/script/value/color.rb +95 -0
  187. data/lib/sassc/script/value/list.rb +136 -0
  188. data/lib/sassc/script/value/map.rb +69 -0
  189. data/lib/sassc/script/value/number.rb +389 -0
  190. data/lib/sassc/script/value/string.rb +96 -0
  191. data/lib/sassc/script/value.rb +137 -0
  192. data/lib/sassc/script/value_conversion/base.rb +13 -0
  193. data/lib/sassc/script/value_conversion/bool.rb +13 -0
  194. data/lib/sassc/script/value_conversion/color.rb +18 -0
  195. data/lib/sassc/script/value_conversion/list.rb +25 -0
  196. data/lib/sassc/script/value_conversion/map.rb +21 -0
  197. data/lib/sassc/script/value_conversion/number.rb +13 -0
  198. data/lib/sassc/script/value_conversion/string.rb +17 -0
  199. data/lib/sassc/script/value_conversion.rb +69 -0
  200. data/lib/sassc/script.rb +17 -0
  201. data/lib/sassc/util/normalized_map.rb +117 -0
  202. data/lib/sassc/util.rb +231 -0
  203. data/lib/sassc/version.rb +5 -0
  204. data/lib/sassc.rb +57 -0
  205. data/sassc.gemspec +69 -0
  206. data/test/css_color_level4_test.rb +168 -0
  207. data/test/custom_importer_test.rb +127 -0
  208. data/test/engine_test.rb +314 -0
  209. data/test/error_test.rb +29 -0
  210. data/test/fixtures/paths.scss +10 -0
  211. data/test/functions_test.rb +340 -0
  212. data/test/native_test.rb +213 -0
  213. data/test/output_style_test.rb +107 -0
  214. data/test/sass_2_scss_test.rb +14 -0
  215. data/test/test_helper.rb +45 -0
  216. metadata +396 -0
@@ -0,0 +1,393 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+ #include "ast.hpp"
5
+ #include "check_nesting.hpp"
6
+
7
+ namespace Sass {
8
+
9
+ CheckNesting::CheckNesting()
10
+ : parents(sass::vector<Statement*>()),
11
+ traces(sass::vector<Backtrace>()),
12
+ parent(0), current_mixin_definition(0)
13
+ { }
14
+
15
+ void error(AST_Node* node, Backtraces traces, sass::string msg) {
16
+ traces.push_back(Backtrace(node->pstate()));
17
+ throw Exception::InvalidSass(node->pstate(), traces, msg);
18
+ }
19
+
20
+ Statement* CheckNesting::visit_children(Statement* parent)
21
+ {
22
+ Statement* old_parent = this->parent;
23
+
24
+ if (AtRootRule* root = Cast<AtRootRule>(parent)) {
25
+ sass::vector<Statement*> old_parents = this->parents;
26
+ sass::vector<Statement*> new_parents;
27
+
28
+ for (size_t i = 0, L = this->parents.size(); i < L; i++) {
29
+ Statement* p = this->parents.at(i);
30
+ if (!root->exclude_node(p)) {
31
+ new_parents.push_back(p);
32
+ }
33
+ }
34
+ this->parents = new_parents;
35
+
36
+ for (size_t i = this->parents.size(); i > 0; i--) {
37
+ Statement* p = 0;
38
+ Statement* gp = 0;
39
+ if (i > 0) p = this->parents.at(i - 1);
40
+ if (i > 1) gp = this->parents.at(i - 2);
41
+
42
+ if (!this->is_transparent_parent(p, gp)) {
43
+ this->parent = p;
44
+ break;
45
+ }
46
+ }
47
+
48
+ AtRootRule* ar = Cast<AtRootRule>(parent);
49
+ Block* ret = ar->block();
50
+
51
+ if (ret != NULL) {
52
+ for (auto n : ret->elements()) {
53
+ n->perform(this);
54
+ }
55
+ }
56
+
57
+ this->parent = old_parent;
58
+ this->parents = old_parents;
59
+
60
+ return ret;
61
+ }
62
+
63
+ if (!this->is_transparent_parent(parent, old_parent)) {
64
+ this->parent = parent;
65
+ }
66
+
67
+ this->parents.push_back(parent);
68
+
69
+ Block* b = Cast<Block>(parent);
70
+
71
+ if (Trace* trace = Cast<Trace>(parent)) {
72
+ if (trace->type() == 'i') {
73
+ this->traces.push_back(Backtrace(trace->pstate()));
74
+ }
75
+ }
76
+
77
+ if (!b) {
78
+ if (ParentStatement* bb = Cast<ParentStatement>(parent)) {
79
+ b = bb->block();
80
+ }
81
+ }
82
+
83
+ if (b) {
84
+ for (auto n : b->elements()) {
85
+ n->perform(this);
86
+ }
87
+ }
88
+
89
+ this->parent = old_parent;
90
+ this->parents.pop_back();
91
+
92
+ if (Trace* trace = Cast<Trace>(parent)) {
93
+ if (trace->type() == 'i') {
94
+ this->traces.pop_back();
95
+ }
96
+ }
97
+
98
+ return b;
99
+ }
100
+
101
+
102
+ Statement* CheckNesting::operator()(Block* b)
103
+ {
104
+ return this->visit_children(b);
105
+ }
106
+
107
+ Statement* CheckNesting::operator()(Definition* n)
108
+ {
109
+ if (!this->should_visit(n)) return NULL;
110
+ if (!is_mixin(n)) {
111
+ visit_children(n);
112
+ return n;
113
+ }
114
+
115
+ Definition* old_mixin_definition = this->current_mixin_definition;
116
+ this->current_mixin_definition = n;
117
+
118
+ visit_children(n);
119
+
120
+ this->current_mixin_definition = old_mixin_definition;
121
+
122
+ return n;
123
+ }
124
+
125
+ Statement* CheckNesting::operator()(If* i)
126
+ {
127
+ this->visit_children(i);
128
+
129
+ if (Block* b = Cast<Block>(i->alternative())) {
130
+ for (auto n : b->elements()) n->perform(this);
131
+ }
132
+
133
+ return i;
134
+ }
135
+
136
+ bool CheckNesting::should_visit(Statement* node)
137
+ {
138
+ if (!this->parent) return true;
139
+
140
+ if (Cast<Content>(node))
141
+ { this->invalid_content_parent(this->parent, node); }
142
+
143
+ if (is_charset(node))
144
+ { this->invalid_charset_parent(this->parent, node); }
145
+
146
+ if (Cast<ExtendRule>(node))
147
+ { this->invalid_extend_parent(this->parent, node); }
148
+
149
+ // if (Cast<Import>(node))
150
+ // { this->invalid_import_parent(this->parent); }
151
+
152
+ if (this->is_mixin(node))
153
+ { this->invalid_mixin_definition_parent(this->parent, node); }
154
+
155
+ if (this->is_function(node))
156
+ { this->invalid_function_parent(this->parent, node); }
157
+
158
+ if (this->is_function(this->parent))
159
+ { this->invalid_function_child(node); }
160
+
161
+ if (Declaration* d = Cast<Declaration>(node))
162
+ {
163
+ this->invalid_prop_parent(this->parent, node);
164
+ this->invalid_value_child(d->value());
165
+ }
166
+
167
+ if (Cast<Declaration>(this->parent))
168
+ { this->invalid_prop_child(node); }
169
+
170
+ if (Cast<Return>(node))
171
+ { this->invalid_return_parent(this->parent, node); }
172
+
173
+ return true;
174
+ }
175
+
176
+ void CheckNesting::invalid_content_parent(Statement* parent, AST_Node* node)
177
+ {
178
+ if (!this->current_mixin_definition) {
179
+ error(node, traces, "@content may only be used within a mixin.");
180
+ }
181
+ }
182
+
183
+ void CheckNesting::invalid_charset_parent(Statement* parent, AST_Node* node)
184
+ {
185
+ if (!(
186
+ is_root_node(parent)
187
+ )) {
188
+ error(node, traces, "@charset may only be used at the root of a document.");
189
+ }
190
+ }
191
+
192
+ void CheckNesting::invalid_extend_parent(Statement* parent, AST_Node* node)
193
+ {
194
+ if (!(
195
+ Cast<StyleRule>(parent) ||
196
+ Cast<Mixin_Call>(parent) ||
197
+ is_mixin(parent)
198
+ )) {
199
+ error(node, traces, "Extend directives may only be used within rules.");
200
+ }
201
+ }
202
+
203
+ // void CheckNesting::invalid_import_parent(Statement* parent, AST_Node* node)
204
+ // {
205
+ // for (auto pp : this->parents) {
206
+ // if (
207
+ // Cast<EachRule>(pp) ||
208
+ // Cast<ForRule>(pp) ||
209
+ // Cast<If>(pp) ||
210
+ // Cast<WhileRule>(pp) ||
211
+ // Cast<Trace>(pp) ||
212
+ // Cast<Mixin_Call>(pp) ||
213
+ // is_mixin(pp)
214
+ // ) {
215
+ // error(node, traces, "Import directives may not be defined within control directives or other mixins.");
216
+ // }
217
+ // }
218
+
219
+ // if (this->is_root_node(parent)) {
220
+ // return;
221
+ // }
222
+
223
+ // if (false/*n.css_import?*/) {
224
+ // error(node, traces, "CSS import directives may only be used at the root of a document.");
225
+ // }
226
+ // }
227
+
228
+ void CheckNesting::invalid_mixin_definition_parent(Statement* parent, AST_Node* node)
229
+ {
230
+ for (Statement* pp : this->parents) {
231
+ if (
232
+ Cast<EachRule>(pp) ||
233
+ Cast<ForRule>(pp) ||
234
+ Cast<If>(pp) ||
235
+ Cast<WhileRule>(pp) ||
236
+ Cast<Trace>(pp) ||
237
+ Cast<Mixin_Call>(pp) ||
238
+ is_mixin(pp)
239
+ ) {
240
+ error(node, traces, "Mixins may not be defined within control directives or other mixins.");
241
+ }
242
+ }
243
+ }
244
+
245
+ void CheckNesting::invalid_function_parent(Statement* parent, AST_Node* node)
246
+ {
247
+ for (Statement* pp : this->parents) {
248
+ if (
249
+ Cast<EachRule>(pp) ||
250
+ Cast<ForRule>(pp) ||
251
+ Cast<If>(pp) ||
252
+ Cast<WhileRule>(pp) ||
253
+ Cast<Trace>(pp) ||
254
+ Cast<Mixin_Call>(pp) ||
255
+ is_mixin(pp)
256
+ ) {
257
+ error(node, traces, "Functions may not be defined within control directives or other mixins.");
258
+ }
259
+ }
260
+ }
261
+
262
+ void CheckNesting::invalid_function_child(Statement* child)
263
+ {
264
+ if (!(
265
+ Cast<EachRule>(child) ||
266
+ Cast<ForRule>(child) ||
267
+ Cast<If>(child) ||
268
+ Cast<WhileRule>(child) ||
269
+ Cast<Trace>(child) ||
270
+ Cast<Comment>(child) ||
271
+ Cast<DebugRule>(child) ||
272
+ Cast<Return>(child) ||
273
+ Cast<Variable>(child) ||
274
+ // Ruby Sass doesn't distinguish variables and assignments
275
+ Cast<Assignment>(child) ||
276
+ Cast<WarningRule>(child) ||
277
+ Cast<ErrorRule>(child)
278
+ )) {
279
+ error(child, traces, "Functions can only contain variable declarations and control directives.");
280
+ }
281
+ }
282
+
283
+ void CheckNesting::invalid_prop_child(Statement* child)
284
+ {
285
+ if (!(
286
+ Cast<EachRule>(child) ||
287
+ Cast<ForRule>(child) ||
288
+ Cast<If>(child) ||
289
+ Cast<WhileRule>(child) ||
290
+ Cast<Trace>(child) ||
291
+ Cast<Comment>(child) ||
292
+ Cast<Declaration>(child) ||
293
+ Cast<Mixin_Call>(child)
294
+ )) {
295
+ error(child, traces, "Illegal nesting: Only properties may be nested beneath properties.");
296
+ }
297
+ }
298
+
299
+ void CheckNesting::invalid_prop_parent(Statement* parent, AST_Node* node)
300
+ {
301
+ if (!(
302
+ is_mixin(parent) ||
303
+ is_directive_node(parent) ||
304
+ Cast<StyleRule>(parent) ||
305
+ Cast<Keyframe_Rule>(parent) ||
306
+ Cast<Declaration>(parent) ||
307
+ Cast<Mixin_Call>(parent)
308
+ )) {
309
+ error(node, traces, "Properties are only allowed within rules, directives, mixin includes, or other properties.");
310
+ }
311
+ }
312
+
313
+ void CheckNesting::invalid_value_child(AST_Node* d)
314
+ {
315
+ if (Map* m = Cast<Map>(d)) {
316
+ traces.push_back(Backtrace(m->pstate()));
317
+ throw Exception::InvalidValue(traces, *m);
318
+ }
319
+ if (Number* n = Cast<Number>(d)) {
320
+ if (!n->is_valid_css_unit()) {
321
+ traces.push_back(Backtrace(n->pstate()));
322
+ throw Exception::InvalidValue(traces, *n);
323
+ }
324
+ }
325
+
326
+ // error(dbg + " isn't a valid CSS value.", m->pstate(),);
327
+
328
+ }
329
+
330
+ void CheckNesting::invalid_return_parent(Statement* parent, AST_Node* node)
331
+ {
332
+ if (!this->is_function(parent)) {
333
+ error(node, traces, "@return may only be used within a function.");
334
+ }
335
+ }
336
+
337
+ bool CheckNesting::is_transparent_parent(Statement* parent, Statement* grandparent)
338
+ {
339
+ bool parent_bubbles = parent && parent->bubbles();
340
+
341
+ bool valid_bubble_node = parent_bubbles &&
342
+ !is_root_node(grandparent) &&
343
+ !is_at_root_node(grandparent);
344
+
345
+ return Cast<Import>(parent) ||
346
+ Cast<EachRule>(parent) ||
347
+ Cast<ForRule>(parent) ||
348
+ Cast<If>(parent) ||
349
+ Cast<WhileRule>(parent) ||
350
+ Cast<Trace>(parent) ||
351
+ valid_bubble_node;
352
+ }
353
+
354
+ bool CheckNesting::is_charset(Statement* n)
355
+ {
356
+ AtRule* d = Cast<AtRule>(n);
357
+ return d && d->keyword() == "charset";
358
+ }
359
+
360
+ bool CheckNesting::is_mixin(Statement* n)
361
+ {
362
+ Definition* def = Cast<Definition>(n);
363
+ return def && def->type() == Definition::MIXIN;
364
+ }
365
+
366
+ bool CheckNesting::is_function(Statement* n)
367
+ {
368
+ Definition* def = Cast<Definition>(n);
369
+ return def && def->type() == Definition::FUNCTION;
370
+ }
371
+
372
+ bool CheckNesting::is_root_node(Statement* n)
373
+ {
374
+ if (Cast<StyleRule>(n)) return false;
375
+
376
+ Block* b = Cast<Block>(n);
377
+ return b && b->is_root();
378
+ }
379
+
380
+ bool CheckNesting::is_at_root_node(Statement* n)
381
+ {
382
+ return Cast<AtRootRule>(n) != NULL;
383
+ }
384
+
385
+ bool CheckNesting::is_directive_node(Statement* n)
386
+ {
387
+ return Cast<AtRule>(n) ||
388
+ Cast<Import>(n) ||
389
+ Cast<MediaRule>(n) ||
390
+ Cast<CssMediaRule>(n) ||
391
+ Cast<SupportsRule>(n);
392
+ }
393
+ }
@@ -0,0 +1,70 @@
1
+ #ifndef SASS_CHECK_NESTING_H
2
+ #define SASS_CHECK_NESTING_H
3
+
4
+ // sass.hpp must go before all system headers to get the
5
+ // __EXTENSIONS__ fix on Solaris.
6
+ #include "sass.hpp"
7
+ #include "ast.hpp"
8
+ #include "operation.hpp"
9
+ #include <vector>
10
+
11
+ namespace Sass {
12
+
13
+ class CheckNesting : public Operation_CRTP<Statement*, CheckNesting> {
14
+
15
+ sass::vector<Statement*> parents;
16
+ Backtraces traces;
17
+ Statement* parent;
18
+ Definition* current_mixin_definition;
19
+
20
+ Statement* before(Statement*);
21
+ Statement* visit_children(Statement*);
22
+
23
+ public:
24
+ CheckNesting();
25
+ ~CheckNesting() { }
26
+
27
+ Statement* operator()(Block*);
28
+ Statement* operator()(Definition*);
29
+ Statement* operator()(If*);
30
+
31
+ template <typename U>
32
+ Statement* fallback(U x) {
33
+ Statement* s = Cast<Statement>(x);
34
+ if (s && this->should_visit(s)) {
35
+ Block* b1 = Cast<Block>(s);
36
+ ParentStatement* b2 = Cast<ParentStatement>(s);
37
+ if (b1 || b2) return visit_children(s);
38
+ }
39
+ return s;
40
+ }
41
+
42
+ private:
43
+ void invalid_content_parent(Statement*, AST_Node*);
44
+ void invalid_charset_parent(Statement*, AST_Node*);
45
+ void invalid_extend_parent(Statement*, AST_Node*);
46
+ // void invalid_import_parent(Statement*);
47
+ void invalid_mixin_definition_parent(Statement*, AST_Node*);
48
+ void invalid_function_parent(Statement*, AST_Node*);
49
+
50
+ void invalid_function_child(Statement*);
51
+ void invalid_prop_child(Statement*);
52
+ void invalid_prop_parent(Statement*, AST_Node*);
53
+ void invalid_return_parent(Statement*, AST_Node*);
54
+ void invalid_value_child(AST_Node*);
55
+
56
+ bool is_transparent_parent(Statement*, Statement*);
57
+
58
+ bool should_visit(Statement*);
59
+
60
+ bool is_charset(Statement*);
61
+ bool is_mixin(Statement*);
62
+ bool is_function(Statement*);
63
+ bool is_root_node(Statement*);
64
+ bool is_at_root_node(Statement*);
65
+ bool is_directive_node(Statement*);
66
+ };
67
+
68
+ }
69
+
70
+ #endif