sassc 1.7.1 → 1.8.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/ext/libsass/.gitignore +10 -6
  4. data/ext/libsass/.travis.yml +4 -1
  5. data/ext/libsass/GNUmakefile.am +88 -0
  6. data/ext/libsass/Makefile +157 -76
  7. data/ext/libsass/Makefile.conf +47 -0
  8. data/ext/libsass/Readme.md +13 -14
  9. data/ext/libsass/appveyor.yml +25 -41
  10. data/ext/libsass/configure.ac +20 -7
  11. data/ext/libsass/contrib/plugin.cpp +1 -1
  12. data/ext/libsass/include/sass.h +15 -0
  13. data/ext/libsass/{sass.h → include/sass/base.h} +17 -9
  14. data/ext/libsass/{sass_context.h → include/sass/context.h} +3 -1
  15. data/ext/libsass/{sass_functions.h → include/sass/functions.h} +4 -4
  16. data/ext/libsass/{sass_interface.h → include/sass/interface.h} +5 -2
  17. data/ext/libsass/{sass_values.h → include/sass/values.h} +15 -1
  18. data/ext/libsass/{sass_version.h → include/sass/version.h} +0 -0
  19. data/ext/libsass/{sass_version.h.in → include/sass/version.h.in} +0 -0
  20. data/ext/libsass/{sass2scss.h → include/sass2scss.h} +6 -7
  21. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +167 -0
  22. data/ext/libsass/script/ci-build-libsass +67 -23
  23. data/ext/libsass/src/GNUmakefile.am +54 -0
  24. data/ext/libsass/src/ast.cpp +2029 -0
  25. data/ext/libsass/{ast.hpp → src/ast.hpp} +832 -660
  26. data/ext/libsass/src/ast_def_macros.hpp +47 -0
  27. data/ext/libsass/src/ast_factory.hpp +93 -0
  28. data/ext/libsass/{ast_fwd_decl.hpp → src/ast_fwd_decl.hpp} +9 -4
  29. data/ext/libsass/{b64 → src/b64}/cencode.h +1 -1
  30. data/ext/libsass/{b64 → src/b64}/encode.h +0 -0
  31. data/ext/libsass/{backtrace.hpp → src/backtrace.hpp} +9 -10
  32. data/ext/libsass/{base64vlq.cpp → src/base64vlq.cpp} +2 -2
  33. data/ext/libsass/{base64vlq.hpp → src/base64vlq.hpp} +1 -2
  34. data/ext/libsass/{bind.cpp → src/bind.cpp} +96 -59
  35. data/ext/libsass/{bind.hpp → src/bind.hpp} +1 -1
  36. data/ext/libsass/src/c99func.c +54 -0
  37. data/ext/libsass/{cencode.c → src/cencode.c} +5 -5
  38. data/ext/libsass/src/color_maps.cpp +643 -0
  39. data/ext/libsass/src/color_maps.hpp +333 -0
  40. data/ext/libsass/{constants.cpp → src/constants.cpp} +10 -1
  41. data/ext/libsass/{constants.hpp → src/constants.hpp} +7 -0
  42. data/ext/libsass/{context.cpp → src/context.cpp} +152 -122
  43. data/ext/libsass/src/context.hpp +150 -0
  44. data/ext/libsass/{cssize.cpp → src/cssize.cpp} +123 -109
  45. data/ext/libsass/{cssize.hpp → src/cssize.hpp} +9 -13
  46. data/ext/libsass/{debug.hpp → src/debug.hpp} +9 -9
  47. data/ext/libsass/src/debugger.hpp +683 -0
  48. data/ext/libsass/{emitter.cpp → src/emitter.cpp} +13 -13
  49. data/ext/libsass/{emitter.hpp → src/emitter.hpp} +10 -11
  50. data/ext/libsass/src/environment.cpp +184 -0
  51. data/ext/libsass/src/environment.hpp +92 -0
  52. data/ext/libsass/src/error_handling.cpp +46 -0
  53. data/ext/libsass/src/error_handling.hpp +34 -0
  54. data/ext/libsass/src/eval.cpp +1462 -0
  55. data/ext/libsass/src/eval.hpp +107 -0
  56. data/ext/libsass/src/expand.cpp +653 -0
  57. data/ext/libsass/{expand.hpp → src/expand.hpp} +17 -16
  58. data/ext/libsass/{extend.cpp → src/extend.cpp} +198 -139
  59. data/ext/libsass/{extend.hpp → src/extend.hpp} +7 -8
  60. data/ext/libsass/{file.cpp → src/file.cpp} +103 -57
  61. data/ext/libsass/{file.hpp → src/file.hpp} +23 -14
  62. data/ext/libsass/{functions.cpp → src/functions.cpp} +642 -333
  63. data/ext/libsass/{functions.hpp → src/functions.hpp} +17 -4
  64. data/ext/libsass/{inspect.cpp → src/inspect.cpp} +147 -260
  65. data/ext/libsass/{inspect.hpp → src/inspect.hpp} +7 -7
  66. data/ext/libsass/{json.cpp → src/json.cpp} +33 -43
  67. data/ext/libsass/{json.hpp → src/json.hpp} +1 -1
  68. data/ext/libsass/{kwd_arg_macros.hpp → src/kwd_arg_macros.hpp} +0 -0
  69. data/ext/libsass/{lexer.cpp → src/lexer.cpp} +28 -0
  70. data/ext/libsass/{lexer.hpp → src/lexer.hpp} +25 -10
  71. data/ext/libsass/{listize.cpp → src/listize.cpp} +17 -13
  72. data/ext/libsass/{listize.hpp → src/listize.hpp} +0 -2
  73. data/ext/libsass/{mapping.hpp → src/mapping.hpp} +0 -0
  74. data/ext/libsass/src/memory_manager.cpp +76 -0
  75. data/ext/libsass/src/memory_manager.hpp +48 -0
  76. data/ext/libsass/{node.cpp → src/node.cpp} +89 -18
  77. data/ext/libsass/{node.hpp → src/node.hpp} +5 -6
  78. data/ext/libsass/{operation.hpp → src/operation.hpp} +18 -12
  79. data/ext/libsass/{output.cpp → src/output.cpp} +47 -55
  80. data/ext/libsass/{output.hpp → src/output.hpp} +5 -4
  81. data/ext/libsass/src/parser.cpp +2529 -0
  82. data/ext/libsass/{parser.hpp → src/parser.hpp} +84 -60
  83. data/ext/libsass/{paths.hpp → src/paths.hpp} +10 -13
  84. data/ext/libsass/{plugins.cpp → src/plugins.cpp} +14 -17
  85. data/ext/libsass/{plugins.hpp → src/plugins.hpp} +10 -11
  86. data/ext/libsass/{position.cpp → src/position.cpp} +5 -6
  87. data/ext/libsass/{position.hpp → src/position.hpp} +19 -22
  88. data/ext/libsass/{prelexer.cpp → src/prelexer.cpp} +401 -53
  89. data/ext/libsass/{prelexer.hpp → src/prelexer.hpp} +50 -10
  90. data/ext/libsass/{remove_placeholders.cpp → src/remove_placeholders.cpp} +12 -16
  91. data/ext/libsass/{remove_placeholders.hpp → src/remove_placeholders.hpp} +1 -7
  92. data/ext/libsass/{sass.cpp → src/sass.cpp} +3 -5
  93. data/ext/libsass/{sass2scss.cpp → src/sass2scss.cpp} +51 -46
  94. data/ext/libsass/{sass_context.cpp → src/sass_context.cpp} +114 -112
  95. data/ext/libsass/{sass_functions.cpp → src/sass_functions.cpp} +11 -18
  96. data/ext/libsass/{sass_interface.cpp → src/sass_interface.cpp} +44 -81
  97. data/ext/libsass/{sass_util.cpp → src/sass_util.cpp} +26 -8
  98. data/ext/libsass/{sass_util.hpp → src/sass_util.hpp} +14 -18
  99. data/ext/libsass/{sass_values.cpp → src/sass_values.cpp} +91 -20
  100. data/ext/libsass/{source_map.cpp → src/source_map.cpp} +13 -13
  101. data/ext/libsass/{source_map.hpp → src/source_map.hpp} +9 -9
  102. data/ext/libsass/{subset_map.hpp → src/subset_map.hpp} +29 -31
  103. data/ext/libsass/{support → src/support}/libsass.pc.in +0 -0
  104. data/ext/libsass/src/to_c.cpp +73 -0
  105. data/ext/libsass/src/to_c.hpp +41 -0
  106. data/ext/libsass/src/to_string.cpp +47 -0
  107. data/ext/libsass/{to_string.hpp → src/to_string.hpp} +9 -7
  108. data/ext/libsass/src/to_value.cpp +109 -0
  109. data/ext/libsass/src/to_value.hpp +50 -0
  110. data/ext/libsass/{units.cpp → src/units.cpp} +56 -51
  111. data/ext/libsass/{units.hpp → src/units.hpp} +8 -9
  112. data/ext/libsass/{utf8.h → src/utf8.h} +0 -0
  113. data/ext/libsass/{utf8 → src/utf8}/checked.h +0 -0
  114. data/ext/libsass/{utf8 → src/utf8}/core.h +12 -12
  115. data/ext/libsass/{utf8 → src/utf8}/unchecked.h +0 -0
  116. data/ext/libsass/{utf8_string.cpp → src/utf8_string.cpp} +0 -0
  117. data/ext/libsass/{utf8_string.hpp → src/utf8_string.hpp} +6 -6
  118. data/ext/libsass/{util.cpp → src/util.cpp} +144 -86
  119. data/ext/libsass/src/util.hpp +59 -0
  120. data/ext/libsass/src/values.cpp +137 -0
  121. data/ext/libsass/src/values.hpp +12 -0
  122. data/ext/libsass/test/test_node.cpp +33 -33
  123. data/ext/libsass/test/test_paths.cpp +5 -6
  124. data/ext/libsass/test/test_selector_difference.cpp +4 -5
  125. data/ext/libsass/test/test_specificity.cpp +4 -5
  126. data/ext/libsass/test/test_subset_map.cpp +91 -91
  127. data/ext/libsass/test/test_superselector.cpp +11 -11
  128. data/ext/libsass/test/test_unification.cpp +4 -4
  129. data/ext/libsass/win/libsass.targets +101 -0
  130. data/ext/libsass/win/libsass.vcxproj +45 -127
  131. data/ext/libsass/win/libsass.vcxproj.filters +303 -0
  132. data/lib/sassc/import_handler.rb +1 -1
  133. data/lib/sassc/native/native_functions_api.rb +3 -3
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/custom_importer_test.rb +1 -4
  136. data/test/functions_test.rb +3 -2
  137. data/test/native_test.rb +4 -3
  138. metadata +117 -110
  139. data/ext/libsass/Makefile.am +0 -146
  140. data/ext/libsass/ast.cpp +0 -945
  141. data/ext/libsass/ast_def_macros.hpp +0 -21
  142. data/ext/libsass/ast_factory.hpp +0 -92
  143. data/ext/libsass/color_names.hpp +0 -327
  144. data/ext/libsass/context.hpp +0 -157
  145. data/ext/libsass/contextualize.cpp +0 -148
  146. data/ext/libsass/contextualize.hpp +0 -46
  147. data/ext/libsass/contextualize_eval.cpp +0 -93
  148. data/ext/libsass/contextualize_eval.hpp +0 -44
  149. data/ext/libsass/debugger.hpp +0 -558
  150. data/ext/libsass/environment.hpp +0 -163
  151. data/ext/libsass/error_handling.cpp +0 -35
  152. data/ext/libsass/error_handling.hpp +0 -32
  153. data/ext/libsass/eval.cpp +0 -1392
  154. data/ext/libsass/eval.hpp +0 -88
  155. data/ext/libsass/expand.cpp +0 -575
  156. data/ext/libsass/memory_manager.hpp +0 -57
  157. data/ext/libsass/parser.cpp +0 -2403
  158. data/ext/libsass/posix/getopt.c +0 -562
  159. data/ext/libsass/posix/getopt.h +0 -95
  160. data/ext/libsass/to_c.cpp +0 -61
  161. data/ext/libsass/to_c.hpp +0 -44
  162. data/ext/libsass/to_string.cpp +0 -34
  163. data/ext/libsass/util.hpp +0 -54
  164. data/ext/libsass/win/libsass.filters +0 -312
@@ -1,88 +0,0 @@
1
- #ifndef SASS_EVAL_H
2
- #define SASS_EVAL_H
3
-
4
- #include <iostream>
5
-
6
- #include "context.hpp"
7
- #include "position.hpp"
8
- #include "operation.hpp"
9
- #include "environment.hpp"
10
- #include "contextualize.hpp"
11
- #include "listize.hpp"
12
- #include "sass_values.h"
13
-
14
- namespace Sass {
15
- using namespace std;
16
-
17
- typedef Environment<AST_Node*> Env;
18
- struct Backtrace;
19
- class Contextualize;
20
- class Listize;
21
-
22
- class Eval : public Operation_CRTP<Expression*, Eval> {
23
-
24
- Context& ctx;
25
-
26
- Expression* fallback_impl(AST_Node* n);
27
-
28
- public:
29
- Contextualize* contextualize;
30
- Listize* listize;
31
- Env* env;
32
- Backtrace* backtrace;
33
- Eval(Context&, Contextualize*, Listize*, Env*, Backtrace*);
34
- virtual ~Eval();
35
- Eval* with(Env* e, Backtrace* bt); // for setting the env before eval'ing an expression
36
- Eval* with(Selector* c, Env* e, Backtrace* bt, Selector* placeholder = 0, Selector* extender = 0); // for setting the env before eval'ing an expression
37
- using Operation<Expression*>::operator();
38
-
39
- // for evaluating function bodies
40
- Expression* operator()(Block*);
41
- Expression* operator()(Assignment*);
42
- Expression* operator()(If*);
43
- Expression* operator()(For*);
44
- Expression* operator()(Each*);
45
- Expression* operator()(While*);
46
- Expression* operator()(Return*);
47
- Expression* operator()(Warning*);
48
- Expression* operator()(Error*);
49
- Expression* operator()(Debug*);
50
-
51
- Expression* operator()(List*);
52
- Expression* operator()(Map*);
53
- Expression* operator()(Binary_Expression*);
54
- Expression* operator()(Unary_Expression*);
55
- Expression* operator()(Function_Call*);
56
- Expression* operator()(Function_Call_Schema*);
57
- Expression* operator()(Variable*);
58
- Expression* operator()(Textual*);
59
- Expression* operator()(Number*);
60
- Expression* operator()(Boolean*);
61
- Expression* operator()(String_Schema*);
62
- Expression* operator()(String_Constant*);
63
- Expression* operator()(Media_Query*);
64
- Expression* operator()(Media_Query_Expression*);
65
- Expression* operator()(At_Root_Expression*);
66
- Expression* operator()(Feature_Query*);
67
- Expression* operator()(Feature_Query_Condition*);
68
- Expression* operator()(Null*);
69
- Expression* operator()(Argument*);
70
- Expression* operator()(Arguments*);
71
- Expression* operator()(Comment*);
72
- Expression* operator()(Parent_Selector* p);
73
-
74
- template <typename U>
75
- Expression* fallback(U x) { return fallback_impl(x); }
76
-
77
- private:
78
- string interpolation(Expression* s);
79
-
80
- };
81
-
82
- Expression* cval_to_astnode(Sass_Value* v, Context& ctx, Backtrace* backtrace, ParserState pstate = ParserState("[AST]"));
83
-
84
- bool eq(Expression*, Expression*, Context&);
85
- bool lt(Expression*, Expression*, Context&);
86
- }
87
-
88
- #endif
@@ -1,575 +0,0 @@
1
- #include <iostream>
2
- #include <typeinfo>
3
-
4
- #include "expand.hpp"
5
- #include "bind.hpp"
6
- #include "eval.hpp"
7
- #include "contextualize_eval.hpp"
8
- #include "to_string.hpp"
9
- #include "backtrace.hpp"
10
- #include "context.hpp"
11
- #include "parser.hpp"
12
-
13
- namespace Sass {
14
-
15
- Expand::Expand(Context& ctx, Eval* eval, Contextualize_Eval* contextualize_eval, Env* env, Backtrace* bt)
16
- : ctx(ctx),
17
- eval(eval),
18
- contextualize_eval(contextualize_eval),
19
- env(env),
20
- block_stack(vector<Block*>()),
21
- property_stack(vector<String*>()),
22
- selector_stack(vector<Selector*>()),
23
- at_root_selector_stack(vector<Selector*>()),
24
- in_at_root(false),
25
- in_keyframes(false),
26
- backtrace(bt)
27
- { selector_stack.push_back(0); }
28
-
29
- Statement* Expand::operator()(Block* b)
30
- {
31
- Env new_env;
32
- new_env.link(*env);
33
- env = &new_env;
34
- Block* bb = new (ctx.mem) Block(b->pstate(), b->length(), b->is_root());
35
- block_stack.push_back(bb);
36
- append_block(b);
37
- block_stack.pop_back();
38
- env = env->parent();
39
- return bb;
40
- }
41
-
42
- Statement* Expand::operator()(Ruleset* r)
43
- {
44
- bool old_in_at_root = in_at_root;
45
- in_at_root = false;
46
-
47
- if (in_keyframes) {
48
- To_String to_string;
49
- Keyframe_Rule* k = new (ctx.mem) Keyframe_Rule(r->pstate(), r->block()->perform(this)->block());
50
- if (r->selector()) k->selector(r->selector()->perform(contextualize_eval->with(0, env, backtrace)));
51
- in_at_root = old_in_at_root;
52
- old_in_at_root = false;
53
- return k;
54
- }
55
-
56
- Contextualize_Eval* contextual = contextualize_eval->with(selector_stack.back(), env, backtrace);
57
- // if (old_in_at_root && !r->selector()->has_reference())
58
- // contextual = contextualize_eval->with(selector_stack.back(), env, backtrace);
59
-
60
- Selector* sel_ctx = r->selector()->perform(contextual);
61
- if (sel_ctx == 0) throw "Cannot expand null selector";
62
-
63
- Emitter emitter(&ctx);
64
- Inspect isp(emitter);
65
- sel_ctx->perform(&isp);
66
- string str = isp.get_buffer();
67
- str += ";";
68
-
69
- Parser p(ctx, r->pstate());
70
- p.block_stack.push_back(r->selector() ? r->selector()->last_block() : 0);
71
- p.last_media_block = r->selector() ? r->selector()->media_block() : 0;
72
- p.source = str.c_str();
73
- p.position = str.c_str();
74
- p.end = str.c_str() + strlen(str.c_str());
75
- Selector_List* sel_lst = p.parse_selector_group();
76
- // sel_lst->pstate(isp.remap(sel_lst->pstate()));
77
-
78
- for(size_t i = 0; i < sel_lst->length(); i++) {
79
-
80
- Complex_Selector* pIter = (*sel_lst)[i];
81
- while (pIter) {
82
- Compound_Selector* pHead = pIter->head();
83
- // pIter->pstate(isp.remap(pIter->pstate()));
84
- if (pHead) {
85
- // pHead->pstate(isp.remap(pHead->pstate()));
86
- // (*pHead)[0]->pstate(isp.remap((*pHead)[0]->pstate()));
87
- }
88
- pIter = pIter->tail();
89
- }
90
- }
91
- sel_ctx = sel_lst;
92
-
93
- selector_stack.push_back(sel_ctx);
94
- Block* blk = r->block()->perform(this)->block();
95
- Ruleset* rr = new (ctx.mem) Ruleset(r->pstate(),
96
- sel_ctx,
97
- blk);
98
- rr->tabs(r->tabs());
99
- selector_stack.pop_back();
100
- in_at_root = old_in_at_root;
101
- old_in_at_root = false;
102
- return rr;
103
- }
104
-
105
- Statement* Expand::operator()(Propset* p)
106
- {
107
- property_stack.push_back(p->property_fragment());
108
- Block* expanded_block = p->block()->perform(this)->block();
109
-
110
- Block* current_block = block_stack.back();
111
- for (size_t i = 0, L = expanded_block->length(); i < L; ++i) {
112
- Statement* stm = (*expanded_block)[i];
113
- if (typeid(*stm) == typeid(Declaration)) {
114
- Declaration* dec = static_cast<Declaration*>(stm);
115
- String_Schema* combined_prop = new (ctx.mem) String_Schema(p->pstate());
116
- if (!property_stack.empty()) {
117
- *combined_prop << property_stack.back()
118
- << new (ctx.mem) String_Constant(p->pstate(), "-")
119
- << dec->property(); // TODO: eval the prop into a string constant
120
- }
121
- else {
122
- *combined_prop << dec->property();
123
- }
124
- dec->property(combined_prop);
125
- *current_block << dec;
126
- }
127
- else if (typeid(*stm) == typeid(Comment)) {
128
- // drop comments in propsets
129
- }
130
- else {
131
- error("contents of namespaced properties must result in style declarations only", stm->pstate(), backtrace);
132
- }
133
- }
134
-
135
- property_stack.pop_back();
136
-
137
- return 0;
138
- }
139
-
140
- Statement* Expand::operator()(Feature_Block* f)
141
- {
142
- Expression* feature_queries = f->feature_queries()->perform(eval->with(env, backtrace));
143
- Feature_Block* ff = new (ctx.mem) Feature_Block(f->pstate(),
144
- static_cast<Feature_Query*>(feature_queries),
145
- f->block()->perform(this)->block());
146
- ff->selector(selector_stack.back());
147
- return ff;
148
- }
149
-
150
- Statement* Expand::operator()(Media_Block* m)
151
- {
152
- To_String to_string(&ctx);
153
- Expression* mq = m->media_queries()->perform(eval->with(env, backtrace));
154
- mq = Parser::from_c_str(mq->perform(&to_string).c_str(), ctx, mq->pstate()).parse_media_queries();
155
- Media_Block* mm = new (ctx.mem) Media_Block(m->pstate(),
156
- static_cast<List*>(mq),
157
- m->block()->perform(this)->block(),
158
- selector_stack.back());
159
- mm->tabs(m->tabs());
160
- return mm;
161
- }
162
-
163
- Statement* Expand::operator()(At_Root_Block* a)
164
- {
165
- in_at_root = true;
166
- at_root_selector_stack.push_back(0);
167
- Block* ab = a->block();
168
- Expression* ae = a->expression();
169
- if (ae) ae = ae->perform(eval->with(env, backtrace));
170
- else ae = new (ctx.mem) At_Root_Expression(a->pstate());
171
- Block* bb = ab ? ab->perform(this)->block() : 0;
172
- At_Root_Block* aa = new (ctx.mem) At_Root_Block(a->pstate(),
173
- bb,
174
- static_cast<At_Root_Expression*>(ae));
175
- at_root_selector_stack.pop_back();
176
- in_at_root = false;
177
- return aa;
178
- }
179
-
180
- Statement* Expand::operator()(At_Rule* a)
181
- {
182
- bool old_in_keyframes = in_keyframes;
183
- in_keyframes = a->is_keyframes();
184
- Block* ab = a->block();
185
- Selector* as = a->selector();
186
- Expression* av = a->value();
187
- if (as) as = as->perform(contextualize_eval->with(0, env, backtrace));
188
- else if (av) av = av->perform(eval->with(env, backtrace));
189
- Block* bb = ab ? ab->perform(this)->block() : 0;
190
- At_Rule* aa = new (ctx.mem) At_Rule(a->pstate(),
191
- a->keyword(),
192
- as,
193
- bb);
194
- if (av) aa->value(av);
195
- in_keyframes = old_in_keyframes;
196
- return aa;
197
- }
198
-
199
- Statement* Expand::operator()(Declaration* d)
200
- {
201
- String* old_p = d->property();
202
- String* new_p = static_cast<String*>(old_p->perform(eval->with(env, backtrace)));
203
- Selector* p = selector_stack.size() <= 1 ? 0 : selector_stack.back();
204
- Expression* value = d->value()->perform(eval->with(p, env, backtrace));
205
- if (value->is_invisible() && !d->is_important()) return 0;
206
- Declaration* decl = new (ctx.mem) Declaration(d->pstate(),
207
- new_p,
208
- value,
209
- d->is_important());
210
- decl->tabs(d->tabs());
211
- return decl;
212
- }
213
-
214
- Statement* Expand::operator()(Assignment* a)
215
- {
216
- string var(a->variable());
217
- Selector* p = selector_stack.size() <= 1 ? 0 : selector_stack.back();
218
- if (a->is_global()) {
219
- if (a->is_default()) {
220
- if (env->has_global(var)) {
221
- Expression* e = dynamic_cast<Expression*>(env->get_global(var));
222
- if (!e || e->concrete_type() == Expression::NULL_VAL) {
223
- env->set_global(var, a->value()->perform(eval->with(p, env, backtrace)));
224
- }
225
- }
226
- else {
227
- env->set_global(var, a->value()->perform(eval->with(p, env, backtrace)));
228
- }
229
- }
230
- else {
231
- env->set_global(var, a->value()->perform(eval->with(p, env, backtrace)));
232
- }
233
- }
234
- else if (a->is_default()) {
235
- if (env->has_lexical(var)) {
236
- auto cur = env;
237
- while (cur && cur->is_lexical()) {
238
- if (cur->has_local(var)) {
239
- if (AST_Node* node = cur->get_local(var)) {
240
- Expression* e = dynamic_cast<Expression*>(node);
241
- if (!e || e->concrete_type() == Expression::NULL_VAL) {
242
- cur->set_local(var, a->value()->perform(eval->with(p, env, backtrace)));
243
- }
244
- }
245
- else {
246
- throw runtime_error("Env not in sync");
247
- }
248
- return 0;
249
- }
250
- cur = cur->parent();
251
- }
252
- throw runtime_error("Env not in sync");
253
- }
254
- else if (env->has_global(var)) {
255
- if (AST_Node* node = env->get_global(var)) {
256
- Expression* e = dynamic_cast<Expression*>(node);
257
- if (!e || e->concrete_type() == Expression::NULL_VAL) {
258
- env->set_global(var, a->value()->perform(eval->with(p, env, backtrace)));
259
- }
260
- }
261
- }
262
- else if (env->is_lexical()) {
263
- env->set_local(var, a->value()->perform(eval->with(p, env, backtrace)));
264
- }
265
- else {
266
- env->set_local(var, a->value()->perform(eval->with(p, env, backtrace)));
267
- }
268
- }
269
- else {
270
- env->set_lexical(var, a->value()->perform(eval->with(p, env, backtrace)));
271
- }
272
- return 0;
273
- }
274
-
275
- Statement* Expand::operator()(Import* imp)
276
- {
277
- Import* result = new (ctx.mem) Import(imp->pstate());
278
- for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {
279
- result->urls().push_back(imp->urls()[i]->perform(eval->with(env, backtrace)));
280
- }
281
- return result;
282
- }
283
-
284
- Statement* Expand::operator()(Import_Stub* i)
285
- {
286
- append_block(ctx.style_sheets[i->file_name()]);
287
- return 0;
288
- }
289
-
290
- Statement* Expand::operator()(Warning* w)
291
- {
292
- // eval handles this too, because warnings may occur in functions
293
- w->perform(eval->with(env, backtrace));
294
- return 0;
295
- }
296
-
297
- Statement* Expand::operator()(Error* e)
298
- {
299
- // eval handles this too, because errors may occur in functions
300
- e->perform(eval->with(env, backtrace));
301
- return 0;
302
- }
303
-
304
- Statement* Expand::operator()(Debug* d)
305
- {
306
- // eval handles this too, because warnings may occur in functions
307
- d->perform(eval->with(env, backtrace));
308
- return 0;
309
- }
310
-
311
- Statement* Expand::operator()(Comment* c)
312
- {
313
- // TODO: eval the text, once we're parsing/storing it as a String_Schema
314
- return new (ctx.mem) Comment(c->pstate(), static_cast<String*>(c->text()->perform(eval->with(env, backtrace))), c->is_important());
315
- }
316
-
317
- Statement* Expand::operator()(If* i)
318
- {
319
- if (*i->predicate()->perform(eval->with(env, backtrace))) {
320
- append_block(i->consequent());
321
- }
322
- else {
323
- Block* alt = i->alternative();
324
- if (alt) append_block(alt);
325
- }
326
- return 0;
327
- }
328
-
329
- // For does not create a new env scope
330
- // But iteration vars are reset afterwards
331
- Statement* Expand::operator()(For* f)
332
- {
333
- string variable(f->variable());
334
- Expression* low = f->lower_bound()->perform(eval->with(env, backtrace));
335
- if (low->concrete_type() != Expression::NUMBER) {
336
- error("lower bound of `@for` directive must be numeric", low->pstate(), backtrace);
337
- }
338
- Expression* high = f->upper_bound()->perform(eval->with(env, backtrace));
339
- if (high->concrete_type() != Expression::NUMBER) {
340
- error("upper bound of `@for` directive must be numeric", high->pstate(), backtrace);
341
- }
342
- Number* sass_start = static_cast<Number*>(low);
343
- Number* sass_end = static_cast<Number*>(high);
344
- // check if units are valid for sequence
345
- if (sass_start->unit() != sass_end->unit()) {
346
- stringstream msg; msg << "Incompatible units: '"
347
- << sass_start->unit() << "' and '"
348
- << sass_end->unit() << "'.";
349
- error(msg.str(), low->pstate(), backtrace);
350
- }
351
- double start = sass_start->value();
352
- double end = sass_end->value();
353
- // only create iterator once in this environment
354
- Number* it = new (env->mem) Number(low->pstate(), start, sass_end->unit());
355
- AST_Node* old_var = env->has_local(variable) ? env->get_local(variable) : 0;
356
- env->set_local(variable, it);
357
- Block* body = f->block();
358
- if (start < end) {
359
- if (f->is_inclusive()) ++end;
360
- for (double i = start;
361
- i < end;
362
- ++i) {
363
- it->value(i);
364
- env->set_local(variable, it);
365
- append_block(body);
366
- }
367
- } else {
368
- if (f->is_inclusive()) --end;
369
- for (double i = start;
370
- i > end;
371
- --i) {
372
- it->value(i);
373
- env->set_local(variable, it);
374
- append_block(body);
375
- }
376
- }
377
- // restore original environment
378
- if (!old_var) env->del_local(variable);
379
- else env->set_local(variable, old_var);
380
- return 0;
381
- }
382
-
383
- // Eval does not create a new env scope
384
- // But iteration vars are reset afterwards
385
- Statement* Expand::operator()(Each* e)
386
- {
387
- vector<string> variables(e->variables());
388
- Expression* expr = e->list()->perform(eval->with(env, backtrace));
389
- List* list = 0;
390
- Map* map = 0;
391
- if (expr->concrete_type() == Expression::MAP) {
392
- map = static_cast<Map*>(expr);
393
- }
394
- else if (expr->concrete_type() != Expression::LIST) {
395
- list = new (ctx.mem) List(expr->pstate(), 1, List::COMMA);
396
- *list << expr;
397
- }
398
- else {
399
- list = static_cast<List*>(expr);
400
- }
401
- // remember variables and then reset them
402
- vector<AST_Node*> old_vars(variables.size());
403
- for (size_t i = 0, L = variables.size(); i < L; ++i) {
404
- old_vars[i] = env->has_local(variables[i]) ? env->get_local(variables[i]) : 0;
405
- env->set_local(variables[i], 0);
406
- }
407
- Block* body = e->block();
408
-
409
- if (map) {
410
- for (auto key : map->keys()) {
411
- Expression* k = key->perform(eval->with(env, backtrace));
412
- Expression* v = map->at(key)->perform(eval->with(env, backtrace));
413
-
414
- if (variables.size() == 1) {
415
- List* variable = new (ctx.mem) List(map->pstate(), 2, List::SPACE);
416
- *variable << k;
417
- *variable << v;
418
- env->set_local(variables[0], variable);
419
- } else {
420
- env->set_local(variables[0], k);
421
- env->set_local(variables[1], v);
422
- }
423
- append_block(body);
424
- }
425
- }
426
- else {
427
- for (size_t i = 0, L = list->length(); i < L; ++i) {
428
- List* variable = 0;
429
- if ((*list)[i]->concrete_type() != Expression::LIST || variables.size() == 1) {
430
- variable = new (ctx.mem) List((*list)[i]->pstate(), 1, List::COMMA);
431
- *variable << (*list)[i];
432
- }
433
- else {
434
- variable = static_cast<List*>((*list)[i]);
435
- }
436
- for (size_t j = 0, K = variables.size(); j < K; ++j) {
437
- if (j < variable->length()) {
438
- env->set_local(variables[j], (*variable)[j]->perform(eval->with(env, backtrace)));
439
- }
440
- else {
441
- env->set_local(variables[j], new (ctx.mem) Null(expr->pstate()));
442
- }
443
- }
444
- append_block(body);
445
- }
446
- }
447
- // restore original environment
448
- for (size_t j = 0, K = variables.size(); j < K; ++j) {
449
- if(!old_vars[j]) env->del_local(variables[j]);
450
- else env->set_local(variables[j], old_vars[j]);
451
- }
452
- return 0;
453
- }
454
-
455
- Statement* Expand::operator()(While* w)
456
- {
457
- Expression* pred = w->predicate();
458
- Block* body = w->block();
459
- while (*pred->perform(eval->with(env, backtrace))) {
460
- append_block(body);
461
- }
462
- return 0;
463
- }
464
-
465
- Statement* Expand::operator()(Return* r)
466
- {
467
- error("@return may only be used within a function", r->pstate(), backtrace);
468
- return 0;
469
- }
470
-
471
- Statement* Expand::operator()(Extension* e)
472
- {
473
- To_String to_string(&ctx);
474
- Selector_List* extender = static_cast<Selector_List*>(selector_stack.back());
475
- if (!extender) return 0;
476
- Contextualize_Eval* eval = contextualize_eval->with(0, env, backtrace);
477
- Selector_List* selector_list = static_cast<Selector_List*>(e->selector());
478
- Selector_List* contextualized = static_cast<Selector_List*>(selector_list->perform(eval));
479
- // ToDo: remove once feature proves stable!
480
- // if (contextualized->length() != 1) {
481
- // error("selector groups may not be extended", extendee->pstate(), backtrace);
482
- // }
483
- for (auto complex_sel : contextualized->elements()) {
484
- Complex_Selector* c = complex_sel;
485
- if (!c->head() || c->tail()) {
486
- error("nested selectors may not be extended", c->pstate(), backtrace);
487
- }
488
- Compound_Selector* compound_sel = c->head();
489
- compound_sel->is_optional(selector_list->is_optional());
490
- // // need to convert the compound selector into a by-value data structure
491
- // vector<string> target_vec;
492
- // for (size_t i = 0, L = compound_sel->length(); i < L; ++i)
493
- // { target_vec.push_back((*compound_sel)[i]->perform(&to_string)); }
494
- for (size_t i = 0, L = extender->length(); i < L; ++i) {
495
- // let's test this out
496
- // cerr << "REGISTERING EXTENSION REQUEST: " << (*extender)[i]->perform(&to_string) << " <- " << compound_sel->perform(&to_string) << endl;
497
- ctx.subset_map.put(compound_sel->to_str_vec(), make_pair((*extender)[i], compound_sel));
498
- }
499
- }
500
- return 0;
501
- }
502
-
503
- Statement* Expand::operator()(Definition* d)
504
- {
505
- Definition* dd = new (ctx.mem) Definition(*d);
506
- env->local_frame()[d->name() +
507
- (d->type() == Definition::MIXIN ? "[m]" : "[f]")] = dd;
508
- // set the static link so we can have lexical scoping
509
- dd->environment(env);
510
- return 0;
511
- }
512
-
513
- Statement* Expand::operator()(Mixin_Call* c)
514
- {
515
- string full_name(c->name() + "[m]");
516
- if (!env->has(full_name)) {
517
- error("no mixin named " + c->name(), c->pstate(), backtrace);
518
- }
519
- Definition* def = static_cast<Definition*>((*env)[full_name]);
520
- Block* body = def->block();
521
- Parameters* params = def->parameters();
522
- Selector* p = selector_stack.size() <= 1 ? 0 : selector_stack.back();
523
-
524
- Arguments* args = static_cast<Arguments*>(c->arguments()
525
- ->perform(eval->with(p, env, backtrace)));
526
- Backtrace here(backtrace, c->pstate(), ", in mixin `" + c->name() + "`");
527
- backtrace = &here;
528
- Env new_env;
529
- new_env.link(def->environment());
530
- if (c->block()) {
531
- // represent mixin content blocks as thunks/closures
532
- Definition* thunk = new (ctx.mem) Definition(c->pstate(),
533
- "@content",
534
- new (ctx.mem) Parameters(c->pstate()),
535
- c->block(),
536
- &ctx,
537
- Definition::MIXIN);
538
- thunk->environment(env);
539
- new_env.local_frame()["@content[m]"] = thunk;
540
- }
541
- bind("mixin " + c->name(), params, args, ctx, &new_env, eval);
542
- Env* old_env = env;
543
- env = &new_env;
544
- append_block(body);
545
- env = old_env;
546
- backtrace = here.parent;
547
- return 0;
548
- }
549
-
550
- Statement* Expand::operator()(Content* c)
551
- {
552
- // convert @content directives into mixin calls to the underlying thunk
553
- if (!env->has("@content[m]")) return 0;
554
- Mixin_Call* call = new (ctx.mem) Mixin_Call(c->pstate(),
555
- "@content",
556
- new (ctx.mem) Arguments(c->pstate()));
557
- return call->perform(this);
558
- }
559
-
560
- inline Statement* Expand::fallback_impl(AST_Node* n)
561
- {
562
- error("unknown internal error; please contact the LibSass maintainers", n->pstate(), backtrace);
563
- String_Constant* msg = new (ctx.mem) String_Constant(ParserState("[WARN]"), string("`Expand` doesn't handle ") + typeid(*n).name());
564
- return new (ctx.mem) Warning(ParserState("[WARN]"), msg);
565
- }
566
-
567
- inline void Expand::append_block(Block* b)
568
- {
569
- Block* current_block = block_stack.back();
570
- for (size_t i = 0, L = b->length(); i < L; ++i) {
571
- Statement* ith = (*b)[i]->perform(this);
572
- if (ith) *current_block << ith;
573
- }
574
- }
575
- }