sassc 1.11.4 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +2 -2
  3. data/CODE_OF_CONDUCT.md +10 -0
  4. data/README.md +4 -1
  5. data/ext/libsass/.editorconfig +1 -1
  6. data/ext/libsass/.github/CONTRIBUTING.md +7 -7
  7. data/ext/libsass/.github/ISSUE_TEMPLATE.md +31 -6
  8. data/ext/libsass/.gitignore +3 -0
  9. data/ext/libsass/.travis.yml +37 -18
  10. data/ext/libsass/GNUmakefile.am +23 -37
  11. data/ext/libsass/Makefile +10 -6
  12. data/ext/libsass/Makefile.conf +3 -0
  13. data/ext/libsass/Readme.md +68 -63
  14. data/ext/libsass/appveyor.yml +7 -3
  15. data/ext/libsass/configure.ac +10 -14
  16. data/ext/libsass/docs/api-context-internal.md +29 -21
  17. data/ext/libsass/docs/api-context.md +26 -6
  18. data/ext/libsass/docs/api-doc.md +49 -16
  19. data/ext/libsass/docs/api-function-example.md +1 -1
  20. data/ext/libsass/docs/api-function.md +31 -7
  21. data/ext/libsass/docs/api-importer.md +19 -19
  22. data/ext/libsass/docs/api-value.md +4 -2
  23. data/ext/libsass/docs/build-on-windows.md +4 -4
  24. data/ext/libsass/docs/build-with-mingw.md +3 -3
  25. data/ext/libsass/docs/build.md +9 -9
  26. data/ext/libsass/docs/custom-functions-internal.md +10 -8
  27. data/ext/libsass/docs/implementations.md +20 -8
  28. data/ext/libsass/docs/unicode.md +16 -10
  29. data/ext/libsass/include/sass/base.h +0 -3
  30. data/ext/libsass/include/sass/context.h +20 -2
  31. data/ext/libsass/include/sass/functions.h +31 -0
  32. data/ext/libsass/include/sass/values.h +3 -1
  33. data/ext/libsass/include/sass/version.h +1 -1
  34. data/ext/libsass/include/sass/version.h.in +1 -1
  35. data/ext/libsass/include/sass2scss.h +1 -1
  36. data/ext/libsass/res/resource.rc +6 -6
  37. data/ext/libsass/script/ci-build-libsass +10 -5
  38. data/ext/libsass/script/ci-build-plugin +62 -0
  39. data/ext/libsass/script/ci-install-compiler +1 -1
  40. data/ext/libsass/script/ci-install-deps +4 -7
  41. data/ext/libsass/script/ci-report-coverage +13 -3
  42. data/ext/libsass/script/tap-driver +1 -1
  43. data/ext/libsass/script/tap-runner +1 -1
  44. data/ext/libsass/src/GNUmakefile.am +1 -1
  45. data/ext/libsass/src/ast.cpp +537 -762
  46. data/ext/libsass/src/ast.hpp +377 -419
  47. data/ext/libsass/src/ast_def_macros.hpp +26 -1
  48. data/ext/libsass/src/ast_fwd_decl.cpp +29 -0
  49. data/ext/libsass/src/ast_fwd_decl.hpp +94 -21
  50. data/ext/libsass/src/b64/encode.h +3 -1
  51. data/ext/libsass/src/backtrace.cpp +46 -0
  52. data/ext/libsass/src/backtrace.hpp +7 -54
  53. data/ext/libsass/src/bind.cpp +72 -50
  54. data/ext/libsass/src/bind.hpp +0 -1
  55. data/ext/libsass/src/cencode.c +6 -0
  56. data/ext/libsass/src/check_nesting.cpp +157 -135
  57. data/ext/libsass/src/check_nesting.hpp +11 -10
  58. data/ext/libsass/src/color_maps.cpp +10 -6
  59. data/ext/libsass/src/color_maps.hpp +6 -8
  60. data/ext/libsass/src/constants.cpp +4 -3
  61. data/ext/libsass/src/constants.hpp +4 -3
  62. data/ext/libsass/src/context.cpp +110 -47
  63. data/ext/libsass/src/context.hpp +11 -1
  64. data/ext/libsass/src/cssize.cpp +105 -94
  65. data/ext/libsass/src/cssize.hpp +4 -5
  66. data/ext/libsass/src/debugger.hpp +247 -244
  67. data/ext/libsass/src/emitter.cpp +30 -6
  68. data/ext/libsass/src/emitter.hpp +7 -0
  69. data/ext/libsass/src/environment.cpp +67 -16
  70. data/ext/libsass/src/environment.hpp +28 -7
  71. data/ext/libsass/src/error_handling.cpp +92 -64
  72. data/ext/libsass/src/error_handling.hpp +64 -43
  73. data/ext/libsass/src/eval.cpp +494 -544
  74. data/ext/libsass/src/eval.hpp +17 -23
  75. data/ext/libsass/src/expand.cpp +182 -154
  76. data/ext/libsass/src/expand.hpp +4 -5
  77. data/ext/libsass/src/extend.cpp +299 -291
  78. data/ext/libsass/src/extend.hpp +46 -11
  79. data/ext/libsass/src/file.cpp +103 -36
  80. data/ext/libsass/src/file.hpp +21 -4
  81. data/ext/libsass/src/functions.cpp +561 -312
  82. data/ext/libsass/src/functions.hpp +8 -5
  83. data/ext/libsass/src/inspect.cpp +108 -53
  84. data/ext/libsass/src/inspect.hpp +5 -2
  85. data/ext/libsass/src/lexer.cpp +15 -7
  86. data/ext/libsass/src/lexer.hpp +13 -4
  87. data/ext/libsass/src/listize.cpp +3 -2
  88. data/ext/libsass/src/listize.hpp +0 -1
  89. data/ext/libsass/src/memory/SharedPtr.cpp +16 -18
  90. data/ext/libsass/src/memory/SharedPtr.hpp +47 -43
  91. data/ext/libsass/src/node.cpp +34 -38
  92. data/ext/libsass/src/node.hpp +6 -8
  93. data/ext/libsass/src/operation.hpp +2 -2
  94. data/ext/libsass/src/operators.cpp +240 -0
  95. data/ext/libsass/src/operators.hpp +30 -0
  96. data/ext/libsass/src/output.cpp +22 -20
  97. data/ext/libsass/src/parser.cpp +719 -358
  98. data/ext/libsass/src/parser.hpp +57 -22
  99. data/ext/libsass/src/plugins.cpp +28 -10
  100. data/ext/libsass/src/position.cpp +21 -3
  101. data/ext/libsass/src/position.hpp +2 -1
  102. data/ext/libsass/src/prelexer.cpp +104 -19
  103. data/ext/libsass/src/prelexer.hpp +10 -3
  104. data/ext/libsass/src/remove_placeholders.cpp +9 -10
  105. data/ext/libsass/src/remove_placeholders.hpp +1 -5
  106. data/ext/libsass/src/sass.cpp +62 -4
  107. data/ext/libsass/src/sass.hpp +5 -2
  108. data/ext/libsass/src/sass_context.cpp +96 -58
  109. data/ext/libsass/src/sass_context.hpp +7 -5
  110. data/ext/libsass/src/sass_functions.cpp +63 -1
  111. data/ext/libsass/src/sass_functions.hpp +19 -1
  112. data/ext/libsass/src/sass_util.cpp +3 -3
  113. data/ext/libsass/src/sass_util.hpp +4 -4
  114. data/ext/libsass/src/sass_values.cpp +42 -39
  115. data/ext/libsass/src/sass_values.hpp +2 -1
  116. data/ext/libsass/src/source_map.cpp +16 -18
  117. data/ext/libsass/src/subset_map.cpp +6 -8
  118. data/ext/libsass/src/subset_map.hpp +6 -6
  119. data/ext/libsass/src/to_c.cpp +2 -2
  120. data/ext/libsass/src/to_value.cpp +8 -3
  121. data/ext/libsass/src/to_value.hpp +1 -0
  122. data/ext/libsass/src/units.cpp +349 -45
  123. data/ext/libsass/src/units.hpp +39 -22
  124. data/ext/libsass/src/utf8/checked.h +7 -0
  125. data/ext/libsass/src/utf8/unchecked.h +7 -0
  126. data/ext/libsass/src/utf8_string.cpp +1 -1
  127. data/ext/libsass/src/util.cpp +139 -45
  128. data/ext/libsass/src/util.hpp +4 -7
  129. data/ext/libsass/src/values.cpp +15 -23
  130. data/ext/libsass/win/libsass.sln +13 -2
  131. data/ext/libsass/win/libsass.sln.DotSettings +9 -0
  132. data/ext/libsass/win/libsass.targets +3 -0
  133. data/ext/libsass/win/libsass.vcxproj.filters +9 -0
  134. data/lib/sassc/version.rb +1 -1
  135. data/sassc.gemspec +1 -1
  136. data/test/native_test.rb +1 -1
  137. metadata +11 -4
@@ -18,16 +18,20 @@ namespace Sass {
18
18
  Expression_Ptr fallback_impl(AST_Node_Ptr n);
19
19
 
20
20
  public:
21
- Expand& exp;
21
+ Expand& exp;
22
22
  Context& ctx;
23
+ Backtraces& traces;
23
24
  Eval(Expand& exp);
24
25
  ~Eval();
25
26
 
26
27
  bool force;
27
28
  bool is_in_comment;
29
+ bool is_in_selector_schema;
30
+
31
+ Boolean_Obj bool_true;
32
+ Boolean_Obj bool_false;
28
33
 
29
34
  Env* environment();
30
- Backtrace* backtrace();
31
35
  Selector_List_Obj selector();
32
36
 
33
37
  // for evaluating function bodies
@@ -49,7 +53,6 @@ namespace Sass {
49
53
  Expression_Ptr operator()(Function_Call_Ptr);
50
54
  Expression_Ptr operator()(Function_Call_Schema_Ptr);
51
55
  Expression_Ptr operator()(Variable_Ptr);
52
- Expression_Ptr operator()(Textual_Ptr);
53
56
  Expression_Ptr operator()(Number_Ptr);
54
57
  Expression_Ptr operator()(Color_Ptr);
55
58
  Expression_Ptr operator()(Boolean_Ptr);
@@ -57,7 +60,7 @@ namespace Sass {
57
60
  Expression_Ptr operator()(String_Quoted_Ptr);
58
61
  Expression_Ptr operator()(String_Constant_Ptr);
59
62
  // Expression_Ptr operator()(Selector_List_Ptr);
60
- Expression_Ptr operator()(Media_Query_Ptr);
63
+ Media_Query_Ptr operator()(Media_Query_Ptr);
61
64
  Expression_Ptr operator()(Media_Query_Expression_Ptr);
62
65
  Expression_Ptr operator()(At_Root_Query_Ptr);
63
66
  Expression_Ptr operator()(Supports_Operator_Ptr);
@@ -72,14 +75,15 @@ namespace Sass {
72
75
  // these will return selectors
73
76
  Selector_List_Ptr operator()(Selector_List_Ptr);
74
77
  Selector_List_Ptr operator()(Complex_Selector_Ptr);
75
- Attribute_Selector_Ptr operator()(Attribute_Selector_Ptr);
76
- // they don't have any specific implementatio (yet)
77
- Element_Selector_Ptr operator()(Element_Selector_Ptr s) { return s; };
78
- Pseudo_Selector_Ptr operator()(Pseudo_Selector_Ptr s) { return s; };
79
- Wrapped_Selector_Ptr operator()(Wrapped_Selector_Ptr s) { return s; };
80
- Class_Selector_Ptr operator()(Class_Selector_Ptr s) { return s; };
81
- Id_Selector_Ptr operator()(Id_Selector_Ptr s) { return s; };
82
- Placeholder_Selector_Ptr operator()(Placeholder_Selector_Ptr s) { return s; };
78
+ Compound_Selector_Ptr operator()(Compound_Selector_Ptr);
79
+ Simple_Selector_Ptr operator()(Simple_Selector_Ptr s);
80
+ Wrapped_Selector_Ptr operator()(Wrapped_Selector_Ptr s);
81
+ // they don't have any specific implementation (yet)
82
+ // Element_Selector_Ptr operator()(Element_Selector_Ptr s) { return s; };
83
+ // Pseudo_Selector_Ptr operator()(Pseudo_Selector_Ptr s) { return s; };
84
+ // Class_Selector_Ptr operator()(Class_Selector_Ptr s) { return s; };
85
+ // Id_Selector_Ptr operator()(Id_Selector_Ptr s) { return s; };
86
+ // Placeholder_Selector_Ptr operator()(Placeholder_Selector_Ptr s) { return s; };
83
87
  // actual evaluated selectors
84
88
  Selector_List_Ptr operator()(Selector_Schema_Ptr);
85
89
  Expression_Ptr operator()(Parent_Selector_Ptr);
@@ -87,22 +91,12 @@ namespace Sass {
87
91
  template <typename U>
88
92
  Expression_Ptr fallback(U x) { return fallback_impl(x); }
89
93
 
90
- // -- only need to define two comparisons, and the rest can be implemented in terms of them
91
- static bool eq(Expression_Obj, Expression_Obj);
92
- static bool lt(Expression_Obj, Expression_Obj, std::string op);
93
- // -- arithmetic on the combinations that matter
94
- static Value_Ptr op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
95
- static Value_Ptr op_number_color(enum Sass_OP, const Number&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
96
- static Value_Ptr op_color_number(enum Sass_OP, const Color&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
97
- static Value_Ptr op_colors(enum Sass_OP, const Color&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
98
- static Value_Ptr op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, ParserState* pstate = 0, bool interpolant = false);
99
-
100
94
  private:
101
95
  void interpolation(Context& ctx, std::string& res, Expression_Obj ex, bool into_quotes, bool was_itpl = false);
102
96
 
103
97
  };
104
98
 
105
- Expression_Ptr cval_to_astnode(union Sass_Value* v, Backtrace* backtrace, ParserState pstate = ParserState("[AST]"));
99
+ Expression_Ptr cval_to_astnode(union Sass_Value* v, Backtraces traces, ParserState pstate = ParserState("[AST]"));
106
100
 
107
101
  }
108
102
 
@@ -9,14 +9,16 @@
9
9
  #include "backtrace.hpp"
10
10
  #include "context.hpp"
11
11
  #include "parser.hpp"
12
+ #include "sass_functions.hpp"
12
13
 
13
14
  namespace Sass {
14
15
 
15
16
  // simple endless recursion protection
16
17
  const size_t maxRecursion = 500;
17
18
 
18
- Expand::Expand(Context& ctx, Env* env, Backtrace* bt, std::vector<Selector_List_Obj>* stack)
19
+ Expand::Expand(Context& ctx, Env* env, std::vector<Selector_List_Obj>* stack)
19
20
  : ctx(ctx),
21
+ traces(ctx.traces),
20
22
  eval(Eval(*this)),
21
23
  recursions(0),
22
24
  in_keyframes(false),
@@ -26,8 +28,7 @@ namespace Sass {
26
28
  block_stack(std::vector<Block_Ptr>()),
27
29
  call_stack(std::vector<AST_Node_Obj>()),
28
30
  selector_stack(std::vector<Selector_List_Obj>()),
29
- media_block_stack(std::vector<Media_Block_Ptr>()),
30
- backtrace_stack(std::vector<Backtrace*>())
31
+ media_block_stack(std::vector<Media_Block_Ptr>())
31
32
  {
32
33
  env_stack.push_back(0);
33
34
  env_stack.push_back(env);
@@ -36,13 +37,6 @@ namespace Sass {
36
37
  if (stack == NULL) { selector_stack.push_back(0); }
37
38
  else { selector_stack.insert(selector_stack.end(), stack->begin(), stack->end()); }
38
39
  media_block_stack.push_back(0);
39
- backtrace_stack.push_back(0);
40
- backtrace_stack.push_back(bt);
41
- }
42
-
43
- Context& Expand::context()
44
- {
45
- return ctx;
46
40
  }
47
41
 
48
42
  Env* Expand::environment()
@@ -59,13 +53,6 @@ namespace Sass {
59
53
  return 0;
60
54
  }
61
55
 
62
- Backtrace* Expand::backtrace()
63
- {
64
- if (backtrace_stack.size() > 0)
65
- return backtrace_stack.back();
66
- return 0;
67
- }
68
-
69
56
  // blocks create new variable scopes
70
57
  Block_Ptr Expand::operator()(Block_Ptr b)
71
58
  {
@@ -78,7 +65,7 @@ namespace Sass {
78
65
  b->length(),
79
66
  b->is_root());
80
67
  // setup block and env stack
81
- this->block_stack.push_back(&bb);
68
+ this->block_stack.push_back(bb);
82
69
  this->env_stack.push_back(&env);
83
70
  // operate on block
84
71
  // this may throw up!
@@ -95,12 +82,14 @@ namespace Sass {
95
82
  LOCAL_FLAG(old_at_root_without_rule, at_root_without_rule);
96
83
 
97
84
  if (in_keyframes) {
98
- Block_Ptr bb = operator()(&r->block());
85
+ Block_Ptr bb = operator()(r->block());
99
86
  Keyframe_Rule_Obj k = SASS_MEMORY_NEW(Keyframe_Rule, r->pstate(), bb);
100
87
  if (r->selector()) {
101
- selector_stack.push_back(0);
102
- k->name(SASS_MEMORY_CAST_PTR(Selector_List, r->selector()->perform(&eval)));
103
- selector_stack.pop_back();
88
+ if (Selector_List_Ptr s = r->selector()) {
89
+ selector_stack.push_back(0);
90
+ k->name(s->eval(eval));
91
+ selector_stack.pop_back();
92
+ }
104
93
  }
105
94
  return k.detach();
106
95
  }
@@ -108,50 +97,54 @@ namespace Sass {
108
97
  // reset when leaving scope
109
98
  LOCAL_FLAG(at_root_without_rule, false);
110
99
 
111
- // do some special checks for the base level rules
112
- if (r->is_root()) {
113
- if (Selector_List_Ptr selector_list = SASS_MEMORY_CAST(Selector_List, r->selector())) {
100
+ // `&` is allowed in `@at-root`!
101
+ bool has_parent_selector = false;
102
+ for (size_t i = 0, L = selector_stack.size(); i < L && !has_parent_selector; i++) {
103
+ Selector_List_Obj ll = selector_stack.at(i);
104
+ has_parent_selector = ll != 0 && ll->length() > 0;
105
+ }
106
+
107
+ Selector_List_Obj sel = r->selector();
108
+ if (sel) sel = sel->eval(eval);
109
+
110
+ // check for parent selectors in base level rules
111
+ if (r->is_root() || (block_stack.back() && block_stack.back()->is_root())) {
112
+ if (Selector_List_Ptr selector_list = Cast<Selector_List>(r->selector())) {
114
113
  for (Complex_Selector_Obj complex_selector : selector_list->elements()) {
115
- Complex_Selector_Ptr tail = &complex_selector;
114
+ Complex_Selector_Ptr tail = complex_selector;
116
115
  while (tail) {
117
116
  if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) {
118
- if (SASS_MEMORY_CAST(Parent_Selector, header) == NULL) continue; // skip all others
117
+ Parent_Selector_Ptr ptr = Cast<Parent_Selector>(header);
118
+ if (ptr == NULL || (!ptr->real() || has_parent_selector)) continue;
119
119
  std::string sel_str(complex_selector->to_string(ctx.c_options));
120
- error("Base-level rules cannot contain the parent-selector-referencing character '&'.", header->pstate(), backtrace());
120
+ error("Base-level rules cannot contain the parent-selector-referencing character '&'.", header->pstate(), traces);
121
121
  }
122
- tail = &tail->tail();
122
+ tail = tail->tail();
123
123
  }
124
124
  }
125
125
  }
126
126
  }
127
-
128
- Expression_Obj ex = 0;
129
- if (r->selector()) ex = r->selector()->perform(&eval);
130
- Selector_List_Obj sel = SASS_MEMORY_CAST(Selector_List, ex);
131
- if (sel == 0) throw std::runtime_error("Expanded null selector");
132
-
133
- if (sel->length() == 0 || sel->has_parent_ref()) {
134
- bool has_parent_selector = false;
135
- for (size_t i = 0, L = selector_stack.size(); i < L && !has_parent_selector; i++) {
136
- Selector_List_Obj ll = selector_stack.at(i);
137
- has_parent_selector = ll != 0 && ll->length() > 0;
138
- }
139
- if (sel->has_real_parent_ref() && !has_parent_selector) {
140
- error("Base-level rules cannot contain the parent-selector-referencing character '&'.", sel->pstate(), backtrace());
127
+ else {
128
+ if (sel->length() == 0 || sel->has_parent_ref()) {
129
+ if (sel->has_real_parent_ref() && !has_parent_selector) {
130
+ error("Base-level rules cannot contain the parent-selector-referencing character '&'.", sel->pstate(), traces);
131
+ }
141
132
  }
142
133
  }
143
134
 
144
- selector_stack.push_back(&sel);
135
+ // do not connect parent again
136
+ sel->remove_parent_selectors();
137
+ selector_stack.push_back(sel);
145
138
  Env env(environment());
146
139
  if (block_stack.back()->is_root()) {
147
140
  env_stack.push_back(&env);
148
141
  }
149
142
  sel->set_media_block(media_block_stack.back());
150
143
  Block_Obj blk = 0;
151
- if (r->block()) blk = operator()(&r->block());
144
+ if (r->block()) blk = operator()(r->block());
152
145
  Ruleset_Ptr rr = SASS_MEMORY_NEW(Ruleset,
153
146
  r->pstate(),
154
- &sel,
147
+ sel,
155
148
  blk);
156
149
  selector_stack.pop_back();
157
150
  if (block_stack.back()->is_root()) {
@@ -169,27 +162,33 @@ namespace Sass {
169
162
  Expression_Obj condition = f->condition()->perform(&eval);
170
163
  Supports_Block_Obj ff = SASS_MEMORY_NEW(Supports_Block,
171
164
  f->pstate(),
172
- SASS_MEMORY_CAST(Supports_Condition, condition),
173
- operator()(&f->block()));
165
+ Cast<Supports_Condition>(condition),
166
+ operator()(f->block()));
174
167
  return ff.detach();
175
168
  }
176
169
 
177
170
  Statement_Ptr Expand::operator()(Media_Block_Ptr m)
178
171
  {
179
- media_block_stack.push_back(m);
180
- Expression_Obj mq = m->media_queries()->perform(&eval);
172
+ Media_Block_Obj cpy = SASS_MEMORY_COPY(m);
173
+ // Media_Blocks are prone to have circular references
174
+ // Copy could leak memory if it does not get picked up
175
+ // Looks like we are able to reset block reference for copy
176
+ // Good as it will ensure a low memory overhead for this fix
177
+ // So this is a cheap solution with a minimal price
178
+ ctx.ast_gc.push_back(cpy); cpy->block(0);
179
+ Expression_Obj mq = eval(m->media_queries());
181
180
  std::string str_mq(mq->to_string(ctx.c_options));
182
181
  char* str = sass_copy_c_string(str_mq.c_str());
183
182
  ctx.strings.push_back(str);
184
- Parser p(Parser::from_c_str(str, ctx, mq->pstate()));
185
- mq = &p.parse_media_queries(); // re-assign now
186
- List_Obj ls = SASS_MEMORY_CAST_PTR(List, mq->perform(&eval));
187
- Block_Obj blk = operator()(&m->block());
183
+ Parser p(Parser::from_c_str(str, ctx, traces, mq->pstate()));
184
+ mq = p.parse_media_queries(); // re-assign now
185
+ cpy->media_queries(mq);
186
+ media_block_stack.push_back(cpy);
187
+ Block_Obj blk = operator()(m->block());
188
188
  Media_Block_Ptr mm = SASS_MEMORY_NEW(Media_Block,
189
189
  m->pstate(),
190
- ls,
191
- blk,
192
- 0);
190
+ mq,
191
+ blk);
193
192
  media_block_stack.pop_back();
194
193
  mm->tabs(m->tabs());
195
194
  return mm;
@@ -198,7 +197,7 @@ namespace Sass {
198
197
  Statement_Ptr Expand::operator()(At_Root_Block_Ptr a)
199
198
  {
200
199
  Block_Obj ab = a->block();
201
- Expression_Obj ae = &a->expression();
200
+ Expression_Obj ae = a->expression();
202
201
 
203
202
  if (ae) ae = ae->perform(&eval);
204
203
  else ae = SASS_MEMORY_NEW(At_Root_Query, a->pstate());
@@ -208,23 +207,23 @@ namespace Sass {
208
207
 
209
208
  ;
210
209
 
211
- Block_Obj bb = ab ? operator()(&ab) : NULL;
210
+ Block_Obj bb = ab ? operator()(ab) : NULL;
212
211
  At_Root_Block_Obj aa = SASS_MEMORY_NEW(At_Root_Block,
213
212
  a->pstate(),
214
213
  bb,
215
- SASS_MEMORY_CAST(At_Root_Query, ae));
214
+ Cast<At_Root_Query>(ae));
216
215
  return aa.detach();
217
216
  }
218
217
 
219
218
  Statement_Ptr Expand::operator()(Directive_Ptr a)
220
219
  {
221
220
  LOCAL_FLAG(in_keyframes, a->is_keyframes());
222
- Block_Ptr ab = &a->block();
223
- Selector_Ptr as = &a->selector();
224
- Expression_Ptr av = &a->value();
221
+ Block_Ptr ab = a->block();
222
+ Selector_List_Ptr as = a->selector();
223
+ Expression_Ptr av = a->value();
225
224
  selector_stack.push_back(0);
226
225
  if (av) av = av->perform(&eval);
227
- if (as) as = SASS_MEMORY_CAST_PTR(Selector, as->perform(&eval));
226
+ if (as) as = eval(as);
228
227
  selector_stack.pop_back();
229
228
  Block_Ptr bb = ab ? operator()(ab) : NULL;
230
229
  Directive_Ptr aa = SASS_MEMORY_NEW(Directive,
@@ -241,14 +240,15 @@ namespace Sass {
241
240
  Block_Obj ab = d->block();
242
241
  String_Obj old_p = d->property();
243
242
  Expression_Obj prop = old_p->perform(&eval);
244
- String_Obj new_p = SASS_MEMORY_CAST(String, prop);
243
+ String_Obj new_p = Cast<String>(prop);
245
244
  // we might get a color back
246
245
  if (!new_p) {
247
246
  std::string str(prop->to_string(ctx.c_options));
248
247
  new_p = SASS_MEMORY_NEW(String_Constant, old_p->pstate(), str);
249
248
  }
250
- Expression_Obj value = d->value()->perform(&eval);
251
- Block_Obj bb = ab ? operator()(&ab) : NULL;
249
+ Expression_Obj value = d->value();
250
+ if (value) value = value->perform(&eval);
251
+ Block_Obj bb = ab ? operator()(ab) : NULL;
252
252
  if (!bb) {
253
253
  if (!value || (value->is_invisible() && !d->is_important())) return 0;
254
254
  }
@@ -257,6 +257,7 @@ namespace Sass {
257
257
  new_p,
258
258
  value,
259
259
  d->is_important(),
260
+ d->is_custom_property(),
260
261
  bb);
261
262
  decl->tabs(d->tabs());
262
263
  return decl;
@@ -265,11 +266,11 @@ namespace Sass {
265
266
  Statement_Ptr Expand::operator()(Assignment_Ptr a)
266
267
  {
267
268
  Env* env = environment();
268
- std::string var(a->variable());
269
+ const std::string& var(a->variable());
269
270
  if (a->is_global()) {
270
271
  if (a->is_default()) {
271
272
  if (env->has_global(var)) {
272
- Expression_Obj e = SASS_MEMORY_CAST(Expression, env->get_global(var));
273
+ Expression_Obj e = Cast<Expression>(env->get_global(var));
273
274
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
274
275
  env->set_global(var, a->value()->perform(&eval));
275
276
  }
@@ -288,7 +289,7 @@ namespace Sass {
288
289
  while (cur && cur->is_lexical()) {
289
290
  if (cur->has_local(var)) {
290
291
  if (AST_Node_Obj node = cur->get_local(var)) {
291
- Expression_Obj e = SASS_MEMORY_CAST(Expression, node);
292
+ Expression_Obj e = Cast<Expression>(node);
292
293
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
293
294
  cur->set_local(var, a->value()->perform(&eval));
294
295
  }
@@ -304,7 +305,7 @@ namespace Sass {
304
305
  }
305
306
  else if (env->has_global(var)) {
306
307
  if (AST_Node_Obj node = env->get_global(var)) {
307
- Expression_Obj e = SASS_MEMORY_CAST(Expression, node);
308
+ Expression_Obj e = Cast<Expression>(node);
308
309
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
309
310
  env->set_global(var, a->value()->perform(&eval));
310
311
  }
@@ -328,7 +329,7 @@ namespace Sass {
328
329
  Import_Obj result = SASS_MEMORY_NEW(Import, imp->pstate());
329
330
  if (imp->import_queries() && imp->import_queries()->size()) {
330
331
  Expression_Obj ex = imp->import_queries()->perform(&eval);
331
- result->import_queries(SASS_MEMORY_CAST(List, ex));
332
+ result->import_queries(Cast<List>(ex));
332
333
  }
333
334
  for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {
334
335
  result->urls().push_back(imp->urls()[i]->perform(&eval));
@@ -340,10 +341,11 @@ namespace Sass {
340
341
 
341
342
  Statement_Ptr Expand::operator()(Import_Stub_Ptr i)
342
343
  {
344
+ traces.push_back(Backtrace(i->pstate()));
343
345
  // get parent node from call stack
344
346
  AST_Node_Obj parent = call_stack.back();
345
- if (SASS_MEMORY_CAST(Block, parent) == NULL) {
346
- error("Import directives may not be used within control directives or mixins.", i->pstate());
347
+ if (Cast<Block>(parent) == NULL) {
348
+ error("Import directives may not be used within control directives or mixins.", i->pstate(), traces);
347
349
  }
348
350
  // we don't seem to need that actually afterall
349
351
  Sass_Import_Entry import = sass_make_import(
@@ -352,10 +354,18 @@ namespace Sass {
352
354
  0, 0
353
355
  );
354
356
  ctx.import_stack.push_back(import);
357
+
358
+ Block_Obj trace_block = SASS_MEMORY_NEW(Block, i->pstate());
359
+ Trace_Obj trace = SASS_MEMORY_NEW(Trace, i->pstate(), i->imp_path(), trace_block, 'i');
360
+ block_stack.back()->append(trace);
361
+ block_stack.push_back(trace_block);
362
+
355
363
  const std::string& abs_path(i->resource().abs_path);
356
- append_block(&ctx.sheets.at(abs_path).root);
364
+ append_block(ctx.sheets.at(abs_path).root);
357
365
  sass_delete_import(ctx.import_stack.back());
358
366
  ctx.import_stack.pop_back();
367
+ block_stack.pop_back();
368
+ traces.pop_back();
359
369
  return 0;
360
370
  }
361
371
 
@@ -382,8 +392,13 @@ namespace Sass {
382
392
 
383
393
  Statement_Ptr Expand::operator()(Comment_Ptr c)
384
394
  {
395
+ if (ctx.output_style() == COMPRESSED) {
396
+ // comments should not be evaluated in compact
397
+ // https://github.com/sass/libsass/issues/2359
398
+ if (!c->is_important()) return NULL;
399
+ }
385
400
  eval.is_in_comment = true;
386
- Comment_Ptr rv = SASS_MEMORY_NEW(Comment, c->pstate(), SASS_MEMORY_CAST_PTR(String, c->text()->perform(&eval)), c->is_important());
401
+ Comment_Ptr rv = SASS_MEMORY_NEW(Comment, c->pstate(), Cast<String>(c->text()->perform(&eval)), c->is_important());
387
402
  eval.is_in_comment = false;
388
403
  // TODO: eval the text, once we're parsing/storing it as a String_Schema
389
404
  return rv;
@@ -396,10 +411,10 @@ namespace Sass {
396
411
  call_stack.push_back(i);
397
412
  Expression_Obj rv = i->predicate()->perform(&eval);
398
413
  if (*rv) {
399
- append_block(&i->block());
414
+ append_block(i->block());
400
415
  }
401
416
  else {
402
- Block_Ptr alt = &i->alternative();
417
+ Block_Ptr alt = i->alternative();
403
418
  if (alt) append_block(alt);
404
419
  }
405
420
  call_stack.pop_back();
@@ -414,20 +429,22 @@ namespace Sass {
414
429
  std::string variable(f->variable());
415
430
  Expression_Obj low = f->lower_bound()->perform(&eval);
416
431
  if (low->concrete_type() != Expression::NUMBER) {
417
- throw Exception::TypeMismatch(*low, "integer");
432
+ traces.push_back(Backtrace(low->pstate()));
433
+ throw Exception::TypeMismatch(traces, *low, "integer");
418
434
  }
419
435
  Expression_Obj high = f->upper_bound()->perform(&eval);
420
436
  if (high->concrete_type() != Expression::NUMBER) {
421
- throw Exception::TypeMismatch(*high, "integer");
437
+ traces.push_back(Backtrace(high->pstate()));
438
+ throw Exception::TypeMismatch(traces, *high, "integer");
422
439
  }
423
- Number_Obj sass_start = SASS_MEMORY_CAST(Number, low);
424
- Number_Obj sass_end = SASS_MEMORY_CAST(Number, high);
440
+ Number_Obj sass_start = Cast<Number>(low);
441
+ Number_Obj sass_end = Cast<Number>(high);
425
442
  // check if units are valid for sequence
426
443
  if (sass_start->unit() != sass_end->unit()) {
427
444
  std::stringstream msg; msg << "Incompatible units: '"
428
445
  << sass_start->unit() << "' and '"
429
446
  << sass_end->unit() << "'.";
430
- error(msg.str(), low->pstate(), backtrace());
447
+ error(msg.str(), low->pstate(), traces);
431
448
  }
432
449
  double start = sass_start->value();
433
450
  double end = sass_end->value();
@@ -435,17 +452,14 @@ namespace Sass {
435
452
  Env env(environment(), true);
436
453
  env_stack.push_back(&env);
437
454
  call_stack.push_back(f);
438
- Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), start, sass_end->unit());
439
- env.set_local(variable, &it);
440
- Block_Ptr body = &f->block();
455
+ Block_Ptr body = f->block();
441
456
  if (start < end) {
442
457
  if (f->is_inclusive()) ++end;
443
458
  for (double i = start;
444
459
  i < end;
445
460
  ++i) {
446
- it = SASS_MEMORY_COPY(it);
447
- it->value(i);
448
- env.set_local(variable, &it);
461
+ Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), i, sass_end->unit());
462
+ env.set_local(variable, it);
449
463
  append_block(body);
450
464
  }
451
465
  } else {
@@ -453,9 +467,8 @@ namespace Sass {
453
467
  for (double i = start;
454
468
  i > end;
455
469
  --i) {
456
- it = SASS_MEMORY_COPY(it);
457
- it->value(i);
458
- env.set_local(variable, &it);
470
+ Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), i, sass_end->unit());
471
+ env.set_local(variable, it);
459
472
  append_block(body);
460
473
  }
461
474
  }
@@ -473,25 +486,25 @@ namespace Sass {
473
486
  List_Obj list = 0;
474
487
  Map_Obj map;
475
488
  if (expr->concrete_type() == Expression::MAP) {
476
- map = SASS_MEMORY_CAST(Map, expr);
489
+ map = Cast<Map>(expr);
477
490
  }
478
- else if (Selector_List_Ptr ls = SASS_MEMORY_CAST(Selector_List, expr)) {
491
+ else if (Selector_List_Ptr ls = Cast<Selector_List>(expr)) {
479
492
  Listize listize;
480
493
  Expression_Obj rv = ls->perform(&listize);
481
- list = SASS_MEMORY_CAST(List, rv);
494
+ list = Cast<List>(rv);
482
495
  }
483
496
  else if (expr->concrete_type() != Expression::LIST) {
484
497
  list = SASS_MEMORY_NEW(List, expr->pstate(), 1, SASS_COMMA);
485
498
  list->append(expr);
486
499
  }
487
500
  else {
488
- list = SASS_MEMORY_CAST(List, expr);
501
+ list = Cast<List>(expr);
489
502
  }
490
503
  // remember variables and then reset them
491
504
  Env env(environment(), true);
492
505
  env_stack.push_back(&env);
493
506
  call_stack.push_back(e);
494
- Block_Ptr body = &e->block();
507
+ Block_Ptr body = e->block();
495
508
 
496
509
  if (map) {
497
510
  for (auto key : map->keys()) {
@@ -502,43 +515,43 @@ namespace Sass {
502
515
  List_Obj variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE);
503
516
  variable->append(k);
504
517
  variable->append(v);
505
- env.set_local(variables[0], &variable);
518
+ env.set_local(variables[0], variable);
506
519
  } else {
507
- env.set_local(variables[0], &k);
508
- env.set_local(variables[1], &v);
520
+ env.set_local(variables[0], k);
521
+ env.set_local(variables[1], v);
509
522
  }
510
523
  append_block(body);
511
524
  }
512
525
  }
513
526
  else {
514
527
  // bool arglist = list->is_arglist();
515
- if (list->length() == 1 && SASS_MEMORY_CAST(Selector_List, list)) {
516
- list = SASS_MEMORY_CAST(List, list);
528
+ if (list->length() == 1 && Cast<Selector_List>(list)) {
529
+ list = Cast<List>(list);
517
530
  }
518
531
  for (size_t i = 0, L = list->length(); i < L; ++i) {
519
- Expression_Obj e = list->at(i);
532
+ Expression_Obj item = list->at(i);
520
533
  // unwrap value if the expression is an argument
521
- if (Argument_Obj arg = SASS_MEMORY_CAST(Argument, e)) e = arg->value();
534
+ if (Argument_Obj arg = Cast<Argument>(item)) item = arg->value();
522
535
  // check if we got passed a list of args (investigate)
523
- if (List_Obj scalars = SASS_MEMORY_CAST(List, e)) {
536
+ if (List_Obj scalars = Cast<List>(item)) {
524
537
  if (variables.size() == 1) {
525
538
  List_Obj var = scalars;
526
539
  // if (arglist) var = (*scalars)[0];
527
- env.set_local(variables[0], &var);
540
+ env.set_local(variables[0], var);
528
541
  } else {
529
542
  for (size_t j = 0, K = variables.size(); j < K; ++j) {
530
543
  Expression_Obj res = j >= scalars->length()
531
544
  ? SASS_MEMORY_NEW(Null, expr->pstate())
532
545
  : (*scalars)[j]->perform(&eval);
533
- env.set_local(variables[j], &res);
546
+ env.set_local(variables[j], res);
534
547
  }
535
548
  }
536
549
  } else {
537
550
  if (variables.size() > 0) {
538
- env.set_local(variables.at(0), &e);
551
+ env.set_local(variables.at(0), item);
539
552
  for (size_t j = 1, K = variables.size(); j < K; ++j) {
540
553
  Expression_Obj res = SASS_MEMORY_NEW(Null, expr->pstate());
541
- env.set_local(variables[j], &res);
554
+ env.set_local(variables[j], res);
542
555
  }
543
556
  }
544
557
  }
@@ -553,12 +566,12 @@ namespace Sass {
553
566
  Statement_Ptr Expand::operator()(While_Ptr w)
554
567
  {
555
568
  Expression_Obj pred = w->predicate();
556
- Block_Ptr body = &w->block();
569
+ Block_Ptr body = w->block();
557
570
  Env env(environment(), true);
558
571
  env_stack.push_back(&env);
559
572
  call_stack.push_back(w);
560
573
  Expression_Obj cond = pred->perform(&eval);
561
- while (*&cond) {
574
+ while (!cond->is_false()) {
562
575
  append_block(body);
563
576
  cond = pred->perform(&eval);
564
577
  }
@@ -569,21 +582,21 @@ namespace Sass {
569
582
 
570
583
  Statement_Ptr Expand::operator()(Return_Ptr r)
571
584
  {
572
- error("@return may only be used within a function", r->pstate(), backtrace());
585
+ error("@return may only be used within a function", r->pstate(), traces);
573
586
  return 0;
574
587
  }
575
588
 
576
589
 
577
590
  void Expand::expand_selector_list(Selector_Obj s, Selector_List_Obj extender) {
578
591
 
579
- if (Selector_List_Obj sl = SASS_MEMORY_CAST(Selector_List, s)) {
592
+ if (Selector_List_Obj sl = Cast<Selector_List>(s)) {
580
593
  for (Complex_Selector_Obj complex_selector : sl->elements()) {
581
594
  Complex_Selector_Obj tail = complex_selector;
582
595
  while (tail) {
583
596
  if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) {
584
- if (SASS_MEMORY_CAST(Parent_Selector, header) == NULL) continue; // skip all others
597
+ if (Cast<Parent_Selector>(header) == NULL) continue; // skip all others
585
598
  std::string sel_str(complex_selector->to_string(ctx.c_options));
586
- error("Can't extend " + sel_str + ": can't extend parent selectors", header->pstate(), backtrace());
599
+ error("Can't extend " + sel_str + ": can't extend parent selectors", header->pstate(), traces);
587
600
  }
588
601
  tail = tail->tail();
589
602
  }
@@ -591,20 +604,20 @@ namespace Sass {
591
604
  }
592
605
 
593
606
 
594
- Selector_List_Obj contextualized = SASS_MEMORY_CAST_PTR(Selector_List, s->perform(&eval));
607
+ Selector_List_Obj contextualized = Cast<Selector_List>(s->perform(&eval));
595
608
  if (contextualized == false) return;
596
609
  for (auto complex_sel : contextualized->elements()) {
597
610
  Complex_Selector_Obj c = complex_sel;
598
611
  if (!c->head() || c->tail()) {
599
612
  std::string sel_str(contextualized->to_string(ctx.c_options));
600
- error("Can't extend " + sel_str + ": can't extend nested selectors", c->pstate(), backtrace());
613
+ error("Can't extend " + sel_str + ": can't extend nested selectors", c->pstate(), traces);
601
614
  }
602
- Compound_Selector_Obj placeholder = c->head();
603
- if (contextualized->is_optional()) placeholder->is_optional(true);
615
+ Compound_Selector_Obj target = c->head();
616
+ if (contextualized->is_optional()) target->is_optional(true);
604
617
  for (size_t i = 0, L = extender->length(); i < L; ++i) {
605
618
  Complex_Selector_Obj sel = (*extender)[i];
606
619
  if (!(sel->head() && sel->head()->length() > 0 &&
607
- SASS_MEMORY_CAST(Parent_Selector, (*sel->head())[0])))
620
+ Cast<Parent_Selector>((*sel->head())[0])))
608
621
  {
609
622
  Compound_Selector_Obj hh = SASS_MEMORY_NEW(Compound_Selector, (*extender)[i]->pstate());
610
623
  hh->media_block((*extender)[i]->media_block());
@@ -613,13 +626,13 @@ namespace Sass {
613
626
  if (sel->has_line_feed()) ssel->has_line_feed(true);
614
627
  Parent_Selector_Obj ps = SASS_MEMORY_NEW(Parent_Selector, (*extender)[i]->pstate());
615
628
  ps->media_block((*extender)[i]->media_block());
616
- hh->append(&ps);
629
+ hh->append(ps);
617
630
  ssel->tail(sel);
618
631
  ssel->head(hh);
619
632
  sel = ssel;
620
633
  }
621
634
  // if (c->has_line_feed()) sel->has_line_feed(true);
622
- ctx.subset_map.put(placeholder, std::make_pair(sel, placeholder));
635
+ ctx.subset_map.put(target, std::make_pair(sel, target));
623
636
  }
624
637
  }
625
638
 
@@ -627,31 +640,30 @@ namespace Sass {
627
640
 
628
641
  Statement* Expand::operator()(Extension_Ptr e)
629
642
  {
630
- if (Selector_List_Obj extender = SASS_MEMORY_CAST(Selector_List, selector())) {
631
- Selector_Obj s = e->selector();
632
- Selector_List_Obj sl = NULL;
633
- // check if we already have a valid selector list
634
- if ((sl = SASS_MEMORY_CAST(Selector_List, s))) {}
635
- // convert selector schema to a selector list
636
- else if (Selector_Schema_Obj schema = SASS_MEMORY_CAST(Selector_Schema, s)) {
643
+ if (Selector_List_Ptr extender = selector()) {
644
+ Selector_List_Ptr sl = e->selector();
645
+ // abort on invalid selector
646
+ if (sl == NULL) return NULL;
647
+ if (Selector_Schema_Ptr schema = sl->schema()) {
637
648
  if (schema->has_real_parent_ref()) {
638
- sl = eval(&schema);
649
+ // put root block on stack again (ignore parents)
650
+ // selector schema must not connect in eval!
651
+ block_stack.push_back(block_stack.at(1));
652
+ sl = eval(sl->schema());
653
+ block_stack.pop_back();
639
654
  } else {
640
655
  selector_stack.push_back(0);
641
- sl = eval(&schema);
642
- sl->remove_parent_selectors();
656
+ sl = eval(sl->schema());
643
657
  selector_stack.pop_back();
644
658
  }
645
659
  }
646
- // abort on invalid selector
647
- if (sl.isNull()) return NULL;
648
660
  for (Complex_Selector_Obj cs : sl->elements()) {
649
661
  if (!cs.isNull() && !cs->head().isNull()) {
650
662
  cs->head()->media_block(media_block_stack.back());
651
663
  }
652
664
  }
653
665
  selector_stack.push_back(0);
654
- expand_selector_list(&sl, extender);
666
+ expand_selector_list(sl, extender);
655
667
  selector_stack.pop_back();
656
668
  }
657
669
  return 0;
@@ -662,7 +674,7 @@ namespace Sass {
662
674
  Env* env = environment();
663
675
  Definition_Obj dd = SASS_MEMORY_COPY(d);
664
676
  env->local_frame()[d->name() +
665
- (d->type() == Definition::MIXIN ? "[m]" : "[f]")] = &dd;
677
+ (d->type() == Definition::MIXIN ? "[m]" : "[f]")] = dd;
666
678
 
667
679
  if (d->type() == Definition::FUNCTION && (
668
680
  Prelexer::calc_fn_call(d->name().c_str()) ||
@@ -671,9 +683,9 @@ namespace Sass {
671
683
  d->name() == "url"
672
684
  )) {
673
685
  deprecated(
674
- "Naming a function \"" + d->name() + "\" is disallowed",
686
+ "Naming a function \"" + d->name() + "\" is disallowed and will be an error in future versions of Sass.",
675
687
  "This name conflicts with an existing CSS function with special parse rules.",
676
- d->pstate()
688
+ false, d->pstate()
677
689
  );
678
690
  }
679
691
 
@@ -684,9 +696,8 @@ namespace Sass {
684
696
 
685
697
  Statement_Ptr Expand::operator()(Mixin_Call_Ptr c)
686
698
  {
687
-
688
699
  if (recursions > maxRecursion) {
689
- throw Exception::StackError(*c);
700
+ throw Exception::StackError(traces, *c);
690
701
  }
691
702
 
692
703
  recursions ++;
@@ -694,19 +705,28 @@ namespace Sass {
694
705
  Env* env = environment();
695
706
  std::string full_name(c->name() + "[m]");
696
707
  if (!env->has(full_name)) {
697
- error("no mixin named " + c->name(), c->pstate(), backtrace());
708
+ error("no mixin named " + c->name(), c->pstate(), traces);
698
709
  }
699
- Definition_Obj def = SASS_MEMORY_CAST(Definition, (*env)[full_name]);
710
+ Definition_Obj def = Cast<Definition>((*env)[full_name]);
700
711
  Block_Obj body = def->block();
701
712
  Parameters_Obj params = def->parameters();
702
713
 
703
714
  if (c->block() && c->name() != "@content" && !body->has_content()) {
704
- error("Mixin \"" + c->name() + "\" does not accept a content block.", c->pstate(), backtrace());
715
+ error("Mixin \"" + c->name() + "\" does not accept a content block.", c->pstate(), traces);
705
716
  }
706
717
  Expression_Obj rv = c->arguments()->perform(&eval);
707
- Arguments_Obj args = SASS_MEMORY_CAST(Arguments, rv);
708
- Backtrace new_bt(backtrace(), c->pstate(), ", in mixin `" + c->name() + "`");
709
- backtrace_stack.push_back(&new_bt);
718
+ Arguments_Obj args = Cast<Arguments>(rv);
719
+ std::string msg(", in mixin `" + c->name() + "`");
720
+ traces.push_back(Backtrace(c->pstate(), msg));
721
+ ctx.callee_stack.push_back({
722
+ c->name().c_str(),
723
+ c->pstate().path,
724
+ c->pstate().line + 1,
725
+ c->pstate().column + 1,
726
+ SASS_CALLEE_MIXIN,
727
+ { env }
728
+ });
729
+
710
730
  Env new_env(def->environment());
711
731
  env_stack.push_back(&new_env);
712
732
  if (c->block()) {
@@ -718,7 +738,7 @@ namespace Sass {
718
738
  c->block(),
719
739
  Definition::MIXIN);
720
740
  thunk->environment(env);
721
- new_env.local_frame()["@content[m]"] = &thunk;
741
+ new_env.local_frame()["@content[m]"] = thunk;
722
742
  }
723
743
 
724
744
  bind(std::string("Mixin"), c->name(), params, args, &ctx, &new_env, &eval);
@@ -726,16 +746,24 @@ namespace Sass {
726
746
  Block_Obj trace_block = SASS_MEMORY_NEW(Block, c->pstate());
727
747
  Trace_Obj trace = SASS_MEMORY_NEW(Trace, c->pstate(), c->name(), trace_block);
728
748
 
729
-
730
- block_stack.push_back(&trace_block);
749
+ env->set_global("is_in_mixin", bool_true);
750
+ if (Block_Ptr pr = block_stack.back()) {
751
+ trace_block->is_root(pr->is_root());
752
+ }
753
+ block_stack.push_back(trace_block);
731
754
  for (auto bb : body->elements()) {
755
+ if (Ruleset_Ptr r = Cast<Ruleset>(bb)) {
756
+ r->is_root(trace_block->is_root());
757
+ }
732
758
  Statement_Obj ith = bb->perform(this);
733
759
  if (ith) trace->block()->append(ith);
734
760
  }
735
761
  block_stack.pop_back();
762
+ env->del_global("is_in_mixin");
736
763
 
764
+ ctx.callee_stack.pop_back();
737
765
  env_stack.pop_back();
738
- backtrace_stack.pop_back();
766
+ traces.pop_back();
739
767
 
740
768
  recursions --;
741
769
  return trace.detach();
@@ -756,7 +784,7 @@ namespace Sass {
756
784
  "@content",
757
785
  SASS_MEMORY_NEW(Arguments, c->pstate()));
758
786
 
759
- Trace_Obj trace = SASS_MEMORY_CAST_PTR(Trace, call->perform(this));
787
+ Trace_Obj trace = Cast<Trace>(call->perform(this));
760
788
 
761
789
  if (block_stack.back()->is_root()) {
762
790
  selector_stack.pop_back();
@@ -770,8 +798,8 @@ namespace Sass {
770
798
  {
771
799
  std::string err =std:: string("`Expand` doesn't handle ") + typeid(*n).name();
772
800
  String_Quoted_Obj msg = SASS_MEMORY_NEW(String_Quoted, ParserState("[WARN]"), err);
773
- error("unknown internal error; please contact the LibSass maintainers", n->pstate(), backtrace());
774
- return SASS_MEMORY_NEW(Warning, ParserState("[WARN]"), &msg);
801
+ error("unknown internal error; please contact the LibSass maintainers", n->pstate(), traces);
802
+ return SASS_MEMORY_NEW(Warning, ParserState("[WARN]"), msg);
775
803
  }
776
804
 
777
805
  // process and add to last block on stack
@@ -779,7 +807,7 @@ namespace Sass {
779
807
  {
780
808
  if (b->is_root()) call_stack.push_back(b);
781
809
  for (size_t i = 0, L = b->length(); i < L; ++i) {
782
- Statement_Ptr stm = &b->at(i);
810
+ Statement_Ptr stm = b->at(i);
783
811
  Statement_Obj ith = stm->perform(this);
784
812
  if (ith) block_stack.back()->append(ith);
785
813
  }