sassc 0.0.9 → 0.0.10

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 (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)