sassc 1.11.4 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
  }