sassc 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/ext/libsass/.gitignore +13 -6
  4. data/ext/libsass/Makefile +42 -26
  5. data/ext/libsass/Makefile.am +43 -30
  6. data/ext/libsass/Readme.md +4 -2
  7. data/ext/libsass/appveyor.yml +10 -14
  8. data/ext/libsass/ast.cpp +54 -44
  9. data/ext/libsass/ast.hpp +404 -236
  10. data/ext/libsass/ast_def_macros.hpp +5 -0
  11. data/ext/libsass/ast_factory.hpp +6 -3
  12. data/ext/libsass/ast_fwd_decl.hpp +12 -0
  13. data/ext/libsass/b64/encode.h +2 -2
  14. data/ext/libsass/backtrace.hpp +13 -17
  15. data/ext/libsass/base64vlq.hpp +4 -1
  16. data/ext/libsass/bind.cpp +12 -15
  17. data/ext/libsass/bind.hpp +6 -6
  18. data/ext/libsass/color_names.hpp +4 -1
  19. data/ext/libsass/configure.ac +7 -21
  20. data/ext/libsass/constants.cpp +6 -4
  21. data/ext/libsass/constants.hpp +10 -4
  22. data/ext/libsass/context.cpp +89 -58
  23. data/ext/libsass/context.hpp +28 -35
  24. data/ext/libsass/contextualize.cpp +20 -10
  25. data/ext/libsass/contextualize.hpp +8 -23
  26. data/ext/libsass/contrib/libsass.spec +66 -0
  27. data/ext/libsass/cssize.cpp +547 -0
  28. data/ext/libsass/cssize.hpp +82 -0
  29. data/ext/libsass/debug.hpp +3 -3
  30. data/ext/libsass/debugger.hpp +358 -0
  31. data/ext/libsass/emitter.cpp +255 -0
  32. data/ext/libsass/emitter.hpp +83 -0
  33. data/ext/libsass/environment.hpp +7 -3
  34. data/ext/libsass/error_handling.cpp +11 -14
  35. data/ext/libsass/error_handling.hpp +9 -7
  36. data/ext/libsass/eval.cpp +253 -161
  37. data/ext/libsass/eval.hpp +13 -13
  38. data/ext/libsass/expand.cpp +135 -64
  39. data/ext/libsass/expand.hpp +11 -13
  40. data/ext/libsass/extend.cpp +66 -20
  41. data/ext/libsass/extend.hpp +6 -11
  42. data/ext/libsass/file.cpp +31 -26
  43. data/ext/libsass/file.hpp +6 -1
  44. data/ext/libsass/functions.cpp +270 -287
  45. data/ext/libsass/functions.hpp +8 -11
  46. data/ext/libsass/inspect.cpp +385 -255
  47. data/ext/libsass/inspect.hpp +15 -26
  48. data/ext/libsass/kwd_arg_macros.hpp +5 -0
  49. data/ext/libsass/mapping.hpp +4 -3
  50. data/ext/libsass/memory_manager.hpp +5 -2
  51. data/ext/libsass/node.cpp +50 -50
  52. data/ext/libsass/node.hpp +26 -27
  53. data/ext/libsass/operation.hpp +15 -4
  54. data/ext/libsass/output.cpp +401 -0
  55. data/ext/libsass/output.hpp +56 -0
  56. data/ext/libsass/parser.cpp +573 -399
  57. data/ext/libsass/parser.hpp +122 -88
  58. data/ext/libsass/paths.hpp +7 -2
  59. data/ext/libsass/plugins.cpp +155 -0
  60. data/ext/libsass/plugins.hpp +56 -0
  61. data/ext/libsass/position.cpp +128 -0
  62. data/ext/libsass/position.hpp +108 -11
  63. data/ext/libsass/prelexer.cpp +184 -110
  64. data/ext/libsass/prelexer.hpp +131 -24
  65. data/ext/libsass/remove_placeholders.cpp +1 -1
  66. data/ext/libsass/remove_placeholders.hpp +6 -6
  67. data/ext/libsass/sass.cpp +3 -3
  68. data/ext/libsass/sass.h +12 -4
  69. data/ext/libsass/sass2scss.cpp +3 -2
  70. data/ext/libsass/sass2scss.h +5 -0
  71. data/ext/libsass/sass_context.cpp +136 -37
  72. data/ext/libsass/sass_context.h +19 -10
  73. data/ext/libsass/sass_functions.cpp +29 -2
  74. data/ext/libsass/sass_functions.h +8 -2
  75. data/ext/libsass/sass_interface.cpp +32 -23
  76. data/ext/libsass/sass_interface.h +9 -4
  77. data/ext/libsass/sass_util.cpp +19 -23
  78. data/ext/libsass/sass_util.hpp +28 -27
  79. data/ext/libsass/sass_values.cpp +6 -4
  80. data/ext/libsass/sass_values.h +3 -3
  81. data/ext/libsass/script/ci-build-libsass +13 -1
  82. data/ext/libsass/script/ci-report-coverage +2 -1
  83. data/ext/libsass/source_map.cpp +79 -28
  84. data/ext/libsass/source_map.hpp +35 -16
  85. data/ext/libsass/subset_map.hpp +6 -4
  86. data/ext/libsass/to_c.hpp +4 -4
  87. data/ext/libsass/to_string.cpp +13 -8
  88. data/ext/libsass/to_string.hpp +6 -4
  89. data/ext/libsass/units.cpp +2 -1
  90. data/ext/libsass/units.hpp +6 -1
  91. data/ext/libsass/utf8_string.cpp +0 -5
  92. data/ext/libsass/utf8_string.hpp +3 -2
  93. data/ext/libsass/util.cpp +461 -49
  94. data/ext/libsass/util.hpp +34 -13
  95. data/ext/libsass/version.sh +10 -0
  96. data/ext/libsass/win/libsass.filters +20 -11
  97. data/ext/libsass/win/libsass.vcxproj +11 -8
  98. data/lib/sassc/importer.rb +1 -8
  99. data/lib/sassc/native.rb +7 -0
  100. data/lib/sassc/native/native_context_api.rb +5 -5
  101. data/lib/sassc/version.rb +1 -1
  102. data/test/native_test.rb +1 -1
  103. metadata +14 -10
  104. data/ext/libsass/copy_c_str.cpp +0 -13
  105. data/ext/libsass/copy_c_str.hpp +0 -5
  106. data/ext/libsass/output_compressed.cpp +0 -401
  107. data/ext/libsass/output_compressed.hpp +0 -95
  108. data/ext/libsass/output_nested.cpp +0 -364
  109. data/ext/libsass/output_nested.hpp +0 -108
  110. data/ext/libsass/test-driver +0 -127
  111. data/ext/libsass/token.hpp +0 -32
@@ -1,25 +1,17 @@
1
- #define SASS_EVAL
1
+ #ifndef SASS_EVAL_H
2
+ #define SASS_EVAL_H
2
3
 
3
4
  #include <iostream>
4
5
 
5
- #ifndef SASS_OPERATION
6
+ #include "context.hpp"
7
+ #include "position.hpp"
6
8
  #include "operation.hpp"
7
- #endif
8
-
9
- #ifndef SASS_ENVIRONMENT
10
9
  #include "environment.hpp"
11
- #endif
12
-
13
- #ifndef SASS_POSITION
14
- #include "position.hpp"
15
- #endif
16
-
17
10
  #include "sass_values.h"
18
11
 
19
12
  namespace Sass {
20
13
  using namespace std;
21
14
 
22
- struct Context;
23
15
  typedef Environment<AST_Node*> Env;
24
16
  struct Backtrace;
25
17
 
@@ -63,18 +55,26 @@ namespace Sass {
63
55
  Expression* operator()(String_Constant*);
64
56
  Expression* operator()(Media_Query*);
65
57
  Expression* operator()(Media_Query_Expression*);
58
+ Expression* operator()(At_Root_Expression*);
66
59
  Expression* operator()(Feature_Query*);
67
60
  Expression* operator()(Feature_Query_Condition*);
68
61
  Expression* operator()(Null*);
69
62
  Expression* operator()(Argument*);
70
63
  Expression* operator()(Arguments*);
64
+ Expression* operator()(Comment*);
71
65
 
72
66
  template <typename U>
73
67
  Expression* fallback(U x) { return fallback_impl(x); }
68
+
69
+ private:
70
+ string interpolation(Expression* s);
71
+
74
72
  };
75
73
 
76
- Expression* cval_to_astnode(Sass_Value* v, Context& ctx, Backtrace* backtrace, string path = "", Position position = Position());
74
+ Expression* cval_to_astnode(Sass_Value* v, Context& ctx, Backtrace* backtrace, ParserState pstate = ParserState("[AST]"));
77
75
 
78
76
  bool eq(Expression*, Expression*, Context&);
79
77
  bool lt(Expression*, Expression*, Context&);
80
78
  }
79
+
80
+ #endif
@@ -1,17 +1,13 @@
1
+ #include <iostream>
2
+ #include <typeinfo>
3
+
1
4
  #include "expand.hpp"
2
5
  #include "bind.hpp"
3
6
  #include "eval.hpp"
4
7
  #include "contextualize.hpp"
5
8
  #include "to_string.hpp"
6
9
  #include "backtrace.hpp"
7
-
8
- #include <iostream>
9
- #include <typeinfo>
10
-
11
- #ifndef SASS_CONTEXT
12
10
  #include "context.hpp"
13
- #endif
14
-
15
11
  #include "parser.hpp"
16
12
 
17
13
  namespace Sass {
@@ -24,6 +20,9 @@ namespace Sass {
24
20
  block_stack(vector<Block*>()),
25
21
  property_stack(vector<String*>()),
26
22
  selector_stack(vector<Selector*>()),
23
+ at_root_selector_stack(vector<Selector*>()),
24
+ in_at_root(false),
25
+ in_keyframes(false),
27
26
  backtrace(bt)
28
27
  { selector_stack.push_back(0); }
29
28
 
@@ -32,7 +31,7 @@ namespace Sass {
32
31
  Env new_env;
33
32
  new_env.link(*env);
34
33
  env = &new_env;
35
- Block* bb = new (ctx.mem) Block(b->path(), b->position(), b->length(), b->is_root());
34
+ Block* bb = new (ctx.mem) Block(b->pstate(), b->length(), b->is_root());
36
35
  block_stack.push_back(bb);
37
36
  append_block(b);
38
37
  block_stack.pop_back();
@@ -42,17 +41,68 @@ namespace Sass {
42
41
 
43
42
  Statement* Expand::operator()(Ruleset* r)
44
43
  {
45
- To_String to_string;
46
- // if (selector_stack.back()) cerr << "expanding " << selector_stack.back()->perform(&to_string) << " and " << r->selector()->perform(&to_string) << endl;
47
- Selector* sel_ctx = r->selector()->perform(contextualize->with(selector_stack.back(), env, backtrace));
48
- // re-parse in order to restructure parent nodes correctly
49
- sel_ctx = Parser::from_c_str((sel_ctx->perform(&to_string) + ";").c_str(), ctx, r->selector()->path(), r->selector()->position()).parse_selector_group();
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()) {
51
+ string s(r->selector()->perform(eval->with(env, backtrace))->perform(&to_string));
52
+ String_Constant* ss = new (ctx.mem) String_Constant(r->selector()->pstate(), s);
53
+ k->rules(ss);
54
+ }
55
+ in_at_root = old_in_at_root;
56
+ old_in_at_root = false;
57
+ return k;
58
+ }
59
+
60
+ Contextualize* contextual = contextualize->with(selector_stack.back(), env, backtrace);
61
+ if (old_in_at_root && !r->selector()->has_reference())
62
+ contextual = contextualize->with(at_root_selector_stack.back(), env, backtrace);
63
+
64
+ Selector* sel_ctx = r->selector()->perform(contextual);
65
+ if (sel_ctx == 0) throw "Cannot expand null selector";
66
+
67
+ Emitter emitter(&ctx);
68
+ Inspect isp(emitter);
69
+ sel_ctx->perform(&isp);
70
+ string str = isp.get_buffer();
71
+ str += ";";
72
+
73
+ Parser p(ctx, r->pstate());
74
+ p.block_stack.push_back(r->selector() ? r->selector()->last_block() : 0);
75
+ p.last_media_block = r->selector() ? r->selector()->media_block() : 0;
76
+ p.source = str.c_str();
77
+ p.position = str.c_str();
78
+ p.end = str.c_str() + strlen(str.c_str());
79
+ Selector_List* sel_lst = p.parse_selector_group();
80
+ // sel_lst->pstate(isp.remap(sel_lst->pstate()));
81
+
82
+ for(size_t i = 0; i < sel_lst->length(); i++) {
83
+
84
+ Complex_Selector* pIter = (*sel_lst)[i];
85
+ while (pIter) {
86
+ Compound_Selector* pHead = pIter->head();
87
+ // pIter->pstate(isp.remap(pIter->pstate()));
88
+ if (pHead) {
89
+ // pHead->pstate(isp.remap(pHead->pstate()));
90
+ // (*pHead)[0]->pstate(isp.remap((*pHead)[0]->pstate()));
91
+ }
92
+ pIter = pIter->tail();
93
+ }
94
+ }
95
+ sel_ctx = sel_lst;
96
+
50
97
  selector_stack.push_back(sel_ctx);
51
- Ruleset* rr = new (ctx.mem) Ruleset(r->path(),
52
- r->position(),
98
+ Block* blk = r->block()->perform(this)->block();
99
+ Ruleset* rr = new (ctx.mem) Ruleset(r->pstate(),
53
100
  sel_ctx,
54
- r->block()->perform(this)->block());
101
+ blk);
102
+ rr->tabs(r->tabs());
55
103
  selector_stack.pop_back();
104
+ in_at_root = old_in_at_root;
105
+ old_in_at_root = false;
56
106
  return rr;
57
107
  }
58
108
 
@@ -66,10 +116,10 @@ namespace Sass {
66
116
  Statement* stm = (*expanded_block)[i];
67
117
  if (typeid(*stm) == typeid(Declaration)) {
68
118
  Declaration* dec = static_cast<Declaration*>(stm);
69
- String_Schema* combined_prop = new (ctx.mem) String_Schema(p->path(), p->position());
119
+ String_Schema* combined_prop = new (ctx.mem) String_Schema(p->pstate());
70
120
  if (!property_stack.empty()) {
71
121
  *combined_prop << property_stack.back()
72
- << new (ctx.mem) String_Constant(p->path(), p->position(), "-")
122
+ << new (ctx.mem) String_Constant(p->pstate(), "-")
73
123
  << dec->property(); // TODO: eval the prop into a string constant
74
124
  }
75
125
  else {
@@ -78,8 +128,11 @@ namespace Sass {
78
128
  dec->property(combined_prop);
79
129
  *current_block << dec;
80
130
  }
131
+ else if (typeid(*stm) == typeid(Comment)) {
132
+ // drop comments in propsets
133
+ }
81
134
  else {
82
- error("contents of namespaced properties must result in style declarations only", stm->path(), stm->position(), backtrace);
135
+ error("contents of namespaced properties must result in style declarations only", stm->pstate(), backtrace);
83
136
  }
84
137
  }
85
138
 
@@ -91,8 +144,7 @@ namespace Sass {
91
144
  Statement* Expand::operator()(Feature_Block* f)
92
145
  {
93
146
  Expression* feature_queries = f->feature_queries()->perform(eval->with(env, backtrace));
94
- Feature_Block* ff = new (ctx.mem) Feature_Block(f->path(),
95
- f->position(),
147
+ Feature_Block* ff = new (ctx.mem) Feature_Block(f->pstate(),
96
148
  static_cast<Feature_Query*>(feature_queries),
97
149
  f->block()->perform(this)->block());
98
150
  ff->selector(selector_stack.back());
@@ -101,31 +153,50 @@ namespace Sass {
101
153
 
102
154
  Statement* Expand::operator()(Media_Block* m)
103
155
  {
104
- Expression* media_queries = m->media_queries()->perform(eval->with(env, backtrace));
105
- Media_Block* mm = new (ctx.mem) Media_Block(m->path(),
106
- m->position(),
107
- static_cast<List*>(media_queries),
108
- m->block()->perform(this)->block());
109
- mm->selector(selector_stack.back());
156
+ To_String to_string(&ctx);
157
+ Expression* mq = m->media_queries()->perform(eval->with(env, backtrace));
158
+ mq = Parser::from_c_str(mq->perform(&to_string).c_str(), ctx, mq->pstate()).parse_media_queries();
159
+ Media_Block* mm = new (ctx.mem) Media_Block(m->pstate(),
160
+ static_cast<List*>(mq),
161
+ m->block()->perform(this)->block(),
162
+ selector_stack.back());
163
+ mm->tabs(m->tabs());
110
164
  return mm;
111
165
  }
112
166
 
167
+ Statement* Expand::operator()(At_Root_Block* a)
168
+ {
169
+ in_at_root = true;
170
+ at_root_selector_stack.push_back(0);
171
+ Block* ab = a->block();
172
+ Expression* ae = a->expression();
173
+ if (ae) ae = ae->perform(eval->with(env, backtrace));
174
+ else ae = new (ctx.mem) At_Root_Expression(a->pstate());
175
+ Block* bb = ab ? ab->perform(this)->block() : 0;
176
+ At_Root_Block* aa = new (ctx.mem) At_Root_Block(a->pstate(),
177
+ bb,
178
+ static_cast<At_Root_Expression*>(ae));
179
+ at_root_selector_stack.pop_back();
180
+ in_at_root = false;
181
+ return aa;
182
+ }
183
+
113
184
  Statement* Expand::operator()(At_Rule* a)
114
185
  {
186
+ bool old_in_keyframes = in_keyframes;
187
+ in_keyframes = a->is_keyframes();
115
188
  Block* ab = a->block();
116
- selector_stack.push_back(0);
117
189
  Selector* as = a->selector();
118
190
  Expression* av = a->value();
119
191
  if (as) as = as->perform(contextualize->with(0, env, backtrace));
120
192
  else if (av) av = av->perform(eval->with(env, backtrace));
121
193
  Block* bb = ab ? ab->perform(this)->block() : 0;
122
- At_Rule* aa = new (ctx.mem) At_Rule(a->path(),
123
- a->position(),
194
+ At_Rule* aa = new (ctx.mem) At_Rule(a->pstate(),
124
195
  a->keyword(),
125
196
  as,
126
197
  bb);
127
198
  if (av) aa->value(av);
128
- selector_stack.pop_back();
199
+ in_keyframes = old_in_keyframes;
129
200
  return aa;
130
201
  }
131
202
 
@@ -137,11 +208,12 @@ namespace Sass {
137
208
 
138
209
  if (value->is_invisible() && !d->is_important()) return 0;
139
210
 
140
- return new (ctx.mem) Declaration(d->path(),
141
- d->position(),
142
- new_p,
143
- value,
144
- d->is_important());
211
+ Declaration* decl = new (ctx.mem) Declaration(d->pstate(),
212
+ new_p,
213
+ value,
214
+ d->is_important());
215
+ decl->tabs(d->tabs());
216
+ return decl;
145
217
  }
146
218
 
147
219
  Statement* Expand::operator()(Assignment* a)
@@ -159,7 +231,7 @@ namespace Sass {
159
231
 
160
232
  Statement* Expand::operator()(Import* imp)
161
233
  {
162
- Import* result = new (ctx.mem) Import(imp->path(), imp->position());
234
+ Import* result = new (ctx.mem) Import(imp->pstate());
163
235
  for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {
164
236
  result->urls().push_back(imp->urls()[i]->perform(eval->with(env, backtrace)));
165
237
  }
@@ -196,7 +268,7 @@ namespace Sass {
196
268
  Statement* Expand::operator()(Comment* c)
197
269
  {
198
270
  // TODO: eval the text, once we're parsing/storing it as a String_Schema
199
- return new (ctx.mem) Comment(c->path(), c->position(), static_cast<String*>(c->text()->perform(eval->with(env, backtrace))));
271
+ return new (ctx.mem) Comment(c->pstate(), static_cast<String*>(c->text()->perform(eval->with(env, backtrace))), c->is_important());
200
272
  }
201
273
 
202
274
  Statement* Expand::operator()(If* i)
@@ -216,16 +288,16 @@ namespace Sass {
216
288
  string variable(f->variable());
217
289
  Expression* low = f->lower_bound()->perform(eval->with(env, backtrace));
218
290
  if (low->concrete_type() != Expression::NUMBER) {
219
- error("lower bound of `@for` directive must be numeric", low->path(), low->position(), backtrace);
291
+ error("lower bound of `@for` directive must be numeric", low->pstate(), backtrace);
220
292
  }
221
293
  Expression* high = f->upper_bound()->perform(eval->with(env, backtrace));
222
294
  if (high->concrete_type() != Expression::NUMBER) {
223
- error("upper bound of `@for` directive must be numeric", high->path(), high->position(), backtrace);
295
+ error("upper bound of `@for` directive must be numeric", high->pstate(), backtrace);
224
296
  }
225
297
  double start = static_cast<Number*>(low)->value();
226
298
  double end = static_cast<Number*>(high)->value();
227
299
  Env new_env;
228
- new_env[variable] = new (ctx.mem) Number(low->path(), low->position(), start);
300
+ new_env[variable] = new (ctx.mem) Number(low->pstate(), start);
229
301
  new_env.link(env);
230
302
  env = &new_env;
231
303
  Block* body = f->block();
@@ -233,14 +305,14 @@ namespace Sass {
233
305
  if (f->is_inclusive()) ++end;
234
306
  for (double i = start;
235
307
  i < end;
236
- (*env)[variable] = new (ctx.mem) Number(low->path(), low->position(), ++i)) {
308
+ (*env)[variable] = new (ctx.mem) Number(low->pstate(), ++i)) {
237
309
  append_block(body);
238
310
  }
239
311
  } else {
240
312
  if (f->is_inclusive()) --end;
241
313
  for (double i = start;
242
314
  i > end;
243
- (*env)[variable] = new (ctx.mem) Number(low->path(), low->position(), --i)) {
315
+ (*env)[variable] = new (ctx.mem) Number(low->pstate(), --i)) {
244
316
  append_block(body);
245
317
  }
246
318
  }
@@ -258,7 +330,7 @@ namespace Sass {
258
330
  map = static_cast<Map*>(expr);
259
331
  }
260
332
  else if (expr->concrete_type() != Expression::LIST) {
261
- list = new (ctx.mem) List(expr->path(), expr->position(), 1, List::COMMA);
333
+ list = new (ctx.mem) List(expr->pstate(), 1, List::COMMA);
262
334
  *list << expr;
263
335
  }
264
336
  else {
@@ -276,7 +348,7 @@ namespace Sass {
276
348
  Expression* v = map->at(key)->perform(eval->with(env, backtrace));
277
349
 
278
350
  if (variables.size() == 1) {
279
- List* variable = new (ctx.mem) List(map->path(), map->position(), 2, List::SPACE);
351
+ List* variable = new (ctx.mem) List(map->pstate(), 2, List::SPACE);
280
352
  *variable << k;
281
353
  *variable << v;
282
354
  (*env)[variables[0]] = variable;
@@ -291,7 +363,7 @@ namespace Sass {
291
363
  for (size_t i = 0, L = list->length(); i < L; ++i) {
292
364
  List* variable = 0;
293
365
  if ((*list)[i]->concrete_type() != Expression::LIST || variables.size() == 1) {
294
- variable = new (ctx.mem) List((*list)[i]->path(), (*list)[i]->position(), 1, List::COMMA);
366
+ variable = new (ctx.mem) List((*list)[i]->pstate(), 1, List::COMMA);
295
367
  *variable << (*list)[i];
296
368
  }
297
369
  else {
@@ -302,7 +374,7 @@ namespace Sass {
302
374
  (*env)[variables[j]] = (*variable)[j]->perform(eval->with(env, backtrace));
303
375
  }
304
376
  else {
305
- (*env)[variables[j]] = new (ctx.mem) Null(expr->path(), expr->position());
377
+ (*env)[variables[j]] = new (ctx.mem) Null(expr->pstate());
306
378
  }
307
379
  }
308
380
  append_block(body);
@@ -324,25 +396,26 @@ namespace Sass {
324
396
 
325
397
  Statement* Expand::operator()(Return* r)
326
398
  {
327
- error("@return may only be used within a function", r->path(), r->position(), backtrace);
399
+ error("@return may only be used within a function", r->pstate(), backtrace);
328
400
  return 0;
329
401
  }
330
402
 
331
403
  Statement* Expand::operator()(Extension* e)
332
404
  {
333
- To_String to_string;
405
+ To_String to_string(&ctx);
334
406
  Selector_List* extender = static_cast<Selector_List*>(selector_stack.back());
335
407
  if (!extender) return 0;
336
- Selector_List* extendee = static_cast<Selector_List*>(e->selector()->perform(contextualize->with(0, env, backtrace)));
408
+ Selector_List* org_extendee = static_cast<Selector_List*>(e->selector());
409
+ Selector_List* extendee = static_cast<Selector_List*>(org_extendee->perform(contextualize->with(0, env, backtrace)));
337
410
  if (extendee->length() != 1) {
338
- error("selector groups may not be extended", extendee->path(), extendee->position(), backtrace);
411
+ error("selector groups may not be extended", extendee->pstate(), backtrace);
339
412
  }
340
413
  Complex_Selector* c = (*extendee)[0];
341
414
  if (!c->head() || c->tail()) {
342
- error("nested selectors may not be extended", c->path(), c->position(), backtrace);
415
+ error("nested selectors may not be extended", c->pstate(), backtrace);
343
416
  }
344
417
  Compound_Selector* s = c->head();
345
-
418
+ s->is_optional(org_extendee->is_optional());
346
419
  // // need to convert the compound selector into a by-value data structure
347
420
  // vector<string> target_vec;
348
421
  // for (size_t i = 0, L = s->length(); i < L; ++i)
@@ -370,23 +443,22 @@ namespace Sass {
370
443
  {
371
444
  string full_name(c->name() + "[m]");
372
445
  if (!env->has(full_name)) {
373
- error("no mixin named " + c->name(), c->path(), c->position(), backtrace);
446
+ error("no mixin named " + c->name(), c->pstate(), backtrace);
374
447
  }
375
448
  Definition* def = static_cast<Definition*>((*env)[full_name]);
376
449
  Block* body = def->block();
377
450
  Parameters* params = def->parameters();
378
451
  Arguments* args = static_cast<Arguments*>(c->arguments()
379
452
  ->perform(eval->with(env, backtrace)));
380
- Backtrace here(backtrace, c->path(), c->position(), ", in mixin `" + c->name() + "`");
453
+ Backtrace here(backtrace, c->pstate(), ", in mixin `" + c->name() + "`");
381
454
  backtrace = &here;
382
455
  Env new_env;
383
456
  new_env.link(def->environment());
384
457
  if (c->block()) {
385
458
  // represent mixin content blocks as thunks/closures
386
- Definition* thunk = new (ctx.mem) Definition(c->path(),
387
- c->position(),
459
+ Definition* thunk = new (ctx.mem) Definition(c->pstate(),
388
460
  "@content",
389
- new (ctx.mem) Parameters(c->path(), c->position()),
461
+ new (ctx.mem) Parameters(c->pstate()),
390
462
  c->block(),
391
463
  Definition::MIXIN);
392
464
  thunk->environment(env);
@@ -405,18 +477,17 @@ namespace Sass {
405
477
  {
406
478
  // convert @content directives into mixin calls to the underlying thunk
407
479
  if (!env->has("@content[m]")) return 0;
408
- Mixin_Call* call = new (ctx.mem) Mixin_Call(c->path(),
409
- c->position(),
480
+ Mixin_Call* call = new (ctx.mem) Mixin_Call(c->pstate(),
410
481
  "@content",
411
- new (ctx.mem) Arguments(c->path(), c->position()));
482
+ new (ctx.mem) Arguments(c->pstate()));
412
483
  return call->perform(this);
413
484
  }
414
485
 
415
486
  inline Statement* Expand::fallback_impl(AST_Node* n)
416
487
  {
417
- error("unknown internal error; please contact the LibSass maintainers", n->path(), n->position(), backtrace);
418
- String_Constant* msg = new (ctx.mem) String_Constant("", Position(), string("`Expand` doesn't handle ") + typeid(*n).name());
419
- return new (ctx.mem) Warning("", Position(), msg);
488
+ error("unknown internal error; please contact the LibSass maintainers", n->pstate(), backtrace);
489
+ String_Constant* msg = new (ctx.mem) String_Constant(ParserState("[WARN]"), string("`Expand` doesn't handle ") + typeid(*n).name());
490
+ return new (ctx.mem) Warning(ParserState("[WARN]"), msg);
420
491
  }
421
492
 
422
493
  inline void Expand::append_block(Block* b)