sassc 2.2.1 → 2.3.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +13 -0
  4. data/Rakefile +1 -3
  5. data/ext/extconf.rb +13 -5
  6. data/ext/libsass/VERSION +1 -1
  7. data/ext/libsass/include/sass/base.h +2 -1
  8. data/ext/libsass/include/sass/context.h +1 -0
  9. data/ext/libsass/src/ast.cpp +49 -59
  10. data/ext/libsass/src/ast.hpp +263 -102
  11. data/ext/libsass/src/ast_def_macros.hpp +8 -0
  12. data/ext/libsass/src/ast_fwd_decl.cpp +2 -1
  13. data/ext/libsass/src/ast_fwd_decl.hpp +40 -116
  14. data/ext/libsass/src/ast_helpers.hpp +292 -0
  15. data/ext/libsass/src/ast_sel_cmp.cpp +209 -722
  16. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  17. data/ext/libsass/src/ast_sel_unify.cpp +207 -212
  18. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  19. data/ext/libsass/src/ast_selectors.cpp +559 -1001
  20. data/ext/libsass/src/ast_selectors.hpp +311 -367
  21. data/ext/libsass/src/ast_supports.cpp +1 -17
  22. data/ext/libsass/src/ast_values.cpp +216 -29
  23. data/ext/libsass/src/ast_values.hpp +42 -33
  24. data/ext/libsass/src/bind.cpp +1 -1
  25. data/ext/libsass/src/cencode.c +4 -6
  26. data/ext/libsass/src/check_nesting.cpp +5 -6
  27. data/ext/libsass/src/check_nesting.hpp +4 -0
  28. data/ext/libsass/src/color_maps.cpp +11 -10
  29. data/ext/libsass/src/color_maps.hpp +0 -8
  30. data/ext/libsass/src/constants.cpp +5 -0
  31. data/ext/libsass/src/constants.hpp +6 -0
  32. data/ext/libsass/src/context.cpp +30 -60
  33. data/ext/libsass/src/context.hpp +8 -20
  34. data/ext/libsass/src/cssize.cpp +36 -120
  35. data/ext/libsass/src/cssize.hpp +4 -10
  36. data/ext/libsass/src/dart_helpers.hpp +199 -0
  37. data/ext/libsass/src/debugger.hpp +364 -207
  38. data/ext/libsass/src/emitter.cpp +3 -4
  39. data/ext/libsass/src/emitter.hpp +0 -2
  40. data/ext/libsass/src/environment.hpp +5 -0
  41. data/ext/libsass/src/error_handling.cpp +21 -0
  42. data/ext/libsass/src/error_handling.hpp +25 -3
  43. data/ext/libsass/src/eval.cpp +33 -153
  44. data/ext/libsass/src/eval.hpp +11 -13
  45. data/ext/libsass/src/eval_selectors.cpp +75 -0
  46. data/ext/libsass/src/expand.cpp +214 -167
  47. data/ext/libsass/src/expand.hpp +26 -6
  48. data/ext/libsass/src/extender.cpp +1186 -0
  49. data/ext/libsass/src/extender.hpp +399 -0
  50. data/ext/libsass/src/extension.cpp +43 -0
  51. data/ext/libsass/src/extension.hpp +89 -0
  52. data/ext/libsass/src/file.cpp +15 -14
  53. data/ext/libsass/src/file.hpp +5 -12
  54. data/ext/libsass/src/fn_colors.cpp +12 -10
  55. data/ext/libsass/src/fn_lists.cpp +12 -11
  56. data/ext/libsass/src/fn_miscs.cpp +22 -34
  57. data/ext/libsass/src/fn_numbers.cpp +13 -6
  58. data/ext/libsass/src/fn_selectors.cpp +94 -124
  59. data/ext/libsass/src/fn_strings.cpp +16 -14
  60. data/ext/libsass/src/fn_utils.cpp +5 -6
  61. data/ext/libsass/src/fn_utils.hpp +9 -3
  62. data/ext/libsass/src/inspect.cpp +154 -117
  63. data/ext/libsass/src/inspect.hpp +10 -8
  64. data/ext/libsass/src/lexer.cpp +17 -81
  65. data/ext/libsass/src/lexer.hpp +5 -16
  66. data/ext/libsass/src/listize.cpp +22 -36
  67. data/ext/libsass/src/listize.hpp +8 -9
  68. data/ext/libsass/src/memory/SharedPtr.hpp +39 -5
  69. data/ext/libsass/src/operation.hpp +27 -17
  70. data/ext/libsass/src/operators.cpp +1 -0
  71. data/ext/libsass/src/ordered_map.hpp +112 -0
  72. data/ext/libsass/src/output.cpp +30 -49
  73. data/ext/libsass/src/output.hpp +1 -1
  74. data/ext/libsass/src/parser.cpp +211 -381
  75. data/ext/libsass/src/parser.hpp +17 -15
  76. data/ext/libsass/src/parser_selectors.cpp +189 -0
  77. data/ext/libsass/src/permutate.hpp +140 -0
  78. data/ext/libsass/src/position.hpp +1 -1
  79. data/ext/libsass/src/prelexer.cpp +6 -6
  80. data/ext/libsass/src/remove_placeholders.cpp +55 -56
  81. data/ext/libsass/src/remove_placeholders.hpp +21 -18
  82. data/ext/libsass/src/sass.hpp +1 -0
  83. data/ext/libsass/src/sass2scss.cpp +4 -4
  84. data/ext/libsass/src/sass_context.cpp +42 -91
  85. data/ext/libsass/src/sass_context.hpp +2 -2
  86. data/ext/libsass/src/sass_functions.cpp +1 -1
  87. data/ext/libsass/src/sass_values.cpp +0 -1
  88. data/ext/libsass/src/stylesheet.cpp +22 -0
  89. data/ext/libsass/src/stylesheet.hpp +57 -0
  90. data/ext/libsass/src/to_value.cpp +2 -2
  91. data/ext/libsass/src/to_value.hpp +1 -1
  92. data/ext/libsass/src/units.cpp +5 -3
  93. data/ext/libsass/src/util.cpp +10 -12
  94. data/ext/libsass/src/util.hpp +2 -3
  95. data/ext/libsass/src/util_string.cpp +111 -61
  96. data/ext/libsass/src/util_string.hpp +61 -8
  97. data/lib/sassc/engine.rb +5 -3
  98. data/lib/sassc/functions_handler.rb +8 -8
  99. data/lib/sassc/native.rb +1 -1
  100. data/lib/sassc/script.rb +4 -4
  101. data/lib/sassc/version.rb +1 -1
  102. data/test/functions_test.rb +18 -1
  103. data/test/native_test.rb +1 -1
  104. metadata +17 -12
  105. data/ext/libsass/src/extend.cpp +0 -2132
  106. data/ext/libsass/src/extend.hpp +0 -86
  107. data/ext/libsass/src/node.cpp +0 -322
  108. data/ext/libsass/src/node.hpp +0 -118
  109. data/ext/libsass/src/paths.hpp +0 -71
  110. data/ext/libsass/src/sass_util.cpp +0 -152
  111. data/ext/libsass/src/sass_util.hpp +0 -256
  112. data/ext/libsass/src/subset_map.cpp +0 -58
  113. data/ext/libsass/src/subset_map.hpp +0 -76
@@ -23,7 +23,6 @@ namespace Sass {
23
23
  virtual void operator()(Ruleset*);
24
24
  virtual void operator()(Bubble*);
25
25
  virtual void operator()(Supports_Block*);
26
- virtual void operator()(Media_Block*);
27
26
  virtual void operator()(At_Root_Block*);
28
27
  virtual void operator()(Directive*);
29
28
  virtual void operator()(Keyframe_Rule*);
@@ -40,7 +39,7 @@ namespace Sass {
40
39
  virtual void operator()(Each*);
41
40
  virtual void operator()(While*);
42
41
  virtual void operator()(Return*);
43
- virtual void operator()(Extension*);
42
+ virtual void operator()(ExtendRule*);
44
43
  virtual void operator()(Definition*);
45
44
  virtual void operator()(Mixin_Call*);
46
45
  virtual void operator()(Content*);
@@ -67,11 +66,14 @@ namespace Sass {
67
66
  virtual void operator()(Supports_Negation*);
68
67
  virtual void operator()(Supports_Declaration*);
69
68
  virtual void operator()(Supports_Interpolation*);
69
+ virtual void operator()(MediaRule*);
70
+ virtual void operator()(CssMediaRule*);
71
+ virtual void operator()(CssMediaQuery*);
70
72
  virtual void operator()(Media_Query*);
71
73
  virtual void operator()(Media_Query_Expression*);
72
74
  virtual void operator()(At_Root_Query*);
73
75
  virtual void operator()(Null*);
74
- virtual void operator()(Parent_Selector* p);
76
+ virtual void operator()(Parent_Reference* p);
75
77
  // parameters and arguments
76
78
  virtual void operator()(Parameter*);
77
79
  virtual void operator()(Parameters*);
@@ -85,11 +87,11 @@ namespace Sass {
85
87
  virtual void operator()(Id_Selector*);
86
88
  virtual void operator()(Attribute_Selector*);
87
89
  virtual void operator()(Pseudo_Selector*);
88
- virtual void operator()(Wrapped_Selector*);
89
- virtual void operator()(Compound_Selector*);
90
- virtual void operator()(Complex_Selector*);
91
- virtual void operator()(Selector_List*);
92
-
90
+ virtual void operator()(SelectorComponent*);
91
+ virtual void operator()(SelectorCombinator*);
92
+ virtual void operator()(CompoundSelector*);
93
+ virtual void operator()(ComplexSelector*);
94
+ virtual void operator()(SelectorList*);
93
95
  virtual std::string lbracket(List*);
94
96
  virtual std::string rbracket(List*);
95
97
 
@@ -2,11 +2,11 @@
2
2
  // __EXTENSIONS__ fix on Solaris.
3
3
  #include "sass.hpp"
4
4
 
5
- #include <cctype>
6
5
  #include <iostream>
7
6
  #include <iomanip>
8
7
  #include "lexer.hpp"
9
8
  #include "constants.hpp"
9
+ #include "util_string.hpp"
10
10
 
11
11
 
12
12
  namespace Sass {
@@ -28,77 +28,14 @@ namespace Sass {
28
28
  const char* kwd_minus(const char* src) { return exactly<'-'>(src); };
29
29
  const char* kwd_slash(const char* src) { return exactly<'/'>(src); };
30
30
 
31
- //####################################
32
- // implement some function that do exist in the standard
33
- // but those are locale aware which brought some trouble
34
- // this even seems to improve performance by quite a bit
35
- //####################################
36
-
37
- bool is_alpha(const char& chr)
38
- {
39
- return unsigned(chr - 'A') <= 'Z' - 'A' ||
40
- unsigned(chr - 'a') <= 'z' - 'a';
41
- }
42
-
43
- bool is_space(const char& chr)
44
- {
45
- // adapted the technique from is_alpha
46
- return chr == ' ' || unsigned(chr - '\t') <= '\r' - '\t';
47
- }
48
-
49
- bool is_digit(const char& chr)
50
- {
51
- // adapted the technique from is_alpha
52
- return unsigned(chr - '0') <= '9' - '0';
53
- }
54
-
55
- bool is_number(const char& chr)
56
- {
57
- // adapted the technique from is_alpha
58
- return is_digit(chr) || chr == '-' || chr == '+';
59
- }
60
-
61
- bool is_xdigit(const char& chr)
62
- {
63
- // adapted the technique from is_alpha
64
- return unsigned(chr - '0') <= '9' - '0' ||
65
- unsigned(chr - 'a') <= 'f' - 'a' ||
66
- unsigned(chr - 'A') <= 'F' - 'A';
67
- }
68
-
69
- bool is_punct(const char& chr)
70
- {
71
- // locale independent
72
- return chr == '.';
73
- }
74
-
75
- bool is_alnum(const char& chr)
76
- {
77
- return is_alpha(chr) || is_digit(chr);
78
- }
79
-
80
- // check if char is outside ascii range
81
- bool is_unicode(const char& chr)
82
- {
83
- // check for unicode range
84
- return unsigned(chr) > 127;
85
- }
86
-
87
- // check if char is outside ascii range
88
- // but with specific ranges (copied from Ruby Sass)
89
- bool is_nonascii(const char& chr)
90
- {
91
- unsigned int cmp = unsigned(chr);
92
- return (
93
- (cmp >= 128 && cmp <= 15572911) ||
94
- (cmp >= 15630464 && cmp <= 15712189) ||
95
- (cmp >= 4036001920)
96
- );
31
+ bool is_number(char chr) {
32
+ return Util::ascii_isdigit(static_cast<unsigned char>(chr)) ||
33
+ chr == '-' || chr == '+';
97
34
  }
98
35
 
99
36
  // check if char is within a reduced ascii range
100
37
  // valid in a uri (copied from Ruby Sass)
101
- bool is_uri_character(const char& chr)
38
+ bool is_uri_character(char chr)
102
39
  {
103
40
  unsigned int cmp = unsigned(chr);
104
41
  return (cmp > 41 && cmp < 127) ||
@@ -107,17 +44,19 @@ namespace Sass {
107
44
 
108
45
  // check if char is within a reduced ascii range
109
46
  // valid for escaping (copied from Ruby Sass)
110
- bool is_escapable_character(const char& chr)
47
+ bool is_escapable_character(char chr)
111
48
  {
112
49
  unsigned int cmp = unsigned(chr);
113
50
  return cmp > 31 && cmp < 127;
114
51
  }
115
52
 
116
53
  // Match word character (look ahead)
117
- bool is_character(const char& chr)
54
+ bool is_character(char chr)
118
55
  {
119
56
  // valid alpha, numeric or unicode char (plus hyphen)
120
- return is_alnum(chr) || is_unicode(chr) || chr == '-';
57
+ return Util::ascii_isalnum(static_cast<unsigned char>(chr)) ||
58
+ !Util::ascii_isascii(static_cast<unsigned char>(chr)) ||
59
+ chr == '-';
121
60
  }
122
61
 
123
62
  //####################################
@@ -125,16 +64,13 @@ namespace Sass {
125
64
  //####################################
126
65
 
127
66
  // create matchers that advance the position
128
- const char* space(const char* src) { return is_space(*src) ? src + 1 : 0; }
129
- const char* alpha(const char* src) { return is_alpha(*src) ? src + 1 : 0; }
130
- const char* unicode(const char* src) { return is_unicode(*src) ? src + 1 : 0; }
131
- const char* nonascii(const char* src) { return is_nonascii(*src) ? src + 1 : 0; }
132
- const char* digit(const char* src) { return is_digit(*src) ? src + 1 : 0; }
133
- const char* xdigit(const char* src) { return is_xdigit(*src) ? src + 1 : 0; }
134
- const char* alnum(const char* src) { return is_alnum(*src) ? src + 1 : 0; }
135
- const char* punct(const char* src) { return is_punct(*src) ? src + 1 : 0; }
136
- const char* hyphen(const char* src) { return *src && *src == '-' ? src + 1 : 0; }
137
- const char* character(const char* src) { return is_character(*src) ? src + 1 : 0; }
67
+ const char* space(const char* src) { return Util::ascii_isspace(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
68
+ const char* alpha(const char* src) { return Util::ascii_isalpha(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
69
+ const char* nonascii(const char* src) { return Util::ascii_isascii(static_cast<unsigned char>(*src)) ? nullptr : src + 1; }
70
+ const char* digit(const char* src) { return Util::ascii_isdigit(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
71
+ const char* xdigit(const char* src) { return Util::ascii_isxdigit(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
72
+ const char* alnum(const char* src) { return Util::ascii_isalnum(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
73
+ const char* hyphen(const char* src) { return *src == '-' ? src + 1 : 0; }
138
74
  const char* uri_character(const char* src) { return is_uri_character(*src) ? src + 1 : 0; }
139
75
  const char* escapable_character(const char* src) { return is_escapable_character(*src) ? src + 1 : 0; }
140
76
 
@@ -24,19 +24,11 @@ namespace Sass {
24
24
  // BASIC CLASS MATCHERS
25
25
  //####################################
26
26
 
27
- // These are locale independant
28
- bool is_space(const char& src);
29
- bool is_alpha(const char& src);
30
- bool is_punct(const char& src);
31
- bool is_digit(const char& src);
32
- bool is_number(const char& src);
33
- bool is_alnum(const char& src);
34
- bool is_xdigit(const char& src);
35
- bool is_unicode(const char& src);
36
- bool is_nonascii(const char& src);
37
- bool is_character(const char& src);
38
- bool is_uri_character(const char& src);
39
- bool escapable_character(const char& src);
27
+ // Matches ASCII digits, +, and -.
28
+ bool is_number(char src);
29
+
30
+ bool is_uri_character(char src);
31
+ bool escapable_character(char src);
40
32
 
41
33
  // Match a single ctype predicate.
42
34
  const char* space(const char* src);
@@ -44,11 +36,8 @@ namespace Sass {
44
36
  const char* digit(const char* src);
45
37
  const char* xdigit(const char* src);
46
38
  const char* alnum(const char* src);
47
- const char* punct(const char* src);
48
39
  const char* hyphen(const char* src);
49
- const char* unicode(const char* src);
50
40
  const char* nonascii(const char* src);
51
- const char* character(const char* src);
52
41
  const char* uri_character(const char* src);
53
42
  const char* escapable_character(const char* src);
54
43
 
@@ -16,7 +16,13 @@ namespace Sass {
16
16
  Listize::Listize()
17
17
  { }
18
18
 
19
- Expression* Listize::operator()(Selector_List* sel)
19
+ Expression* Listize::perform(AST_Node* node)
20
+ {
21
+ Listize listize;
22
+ return node->perform(&listize);
23
+ }
24
+
25
+ Expression* Listize::operator()(SelectorList* sel)
20
26
  {
21
27
  List_Obj l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA);
22
28
  l->from_selector(true);
@@ -28,7 +34,7 @@ namespace Sass {
28
34
  return SASS_MEMORY_NEW(Null, l->pstate());
29
35
  }
30
36
 
31
- Expression* Listize::operator()(Compound_Selector* sel)
37
+ Expression* Listize::operator()(CompoundSelector* sel)
32
38
  {
33
39
  std::string str;
34
40
  for (size_t i = 0, L = sel->length(); i < L; ++i) {
@@ -38,45 +44,25 @@ namespace Sass {
38
44
  return SASS_MEMORY_NEW(String_Quoted, sel->pstate(), str);
39
45
  }
40
46
 
41
- Expression* Listize::operator()(Complex_Selector* sel)
47
+ Expression* Listize::operator()(ComplexSelector* sel)
42
48
  {
43
- List_Obj l = SASS_MEMORY_NEW(List, sel->pstate(), 2);
49
+ List_Obj l = SASS_MEMORY_NEW(List, sel->pstate());
50
+ // ToDo: investigate what this does
51
+ // Note: seems reated to parent ref
44
52
  l->from_selector(true);
45
- Compound_Selector_Obj head = sel->head();
46
- if (head && !head->is_empty_reference())
47
- {
48
- Expression* hh = head->perform(this);
49
- if (hh) l->append(hh);
50
- }
51
53
 
52
- std::string reference = ! sel->reference() ? ""
53
- : sel->reference()->to_string();
54
- switch(sel->combinator())
55
- {
56
- case Complex_Selector::PARENT_OF:
57
- l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), ">"));
58
- break;
59
- case Complex_Selector::ADJACENT_TO:
60
- l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), "+"));
61
- break;
62
- case Complex_Selector::REFERENCE:
63
- l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), "/" + reference + "/"));
64
- break;
65
- case Complex_Selector::PRECEDES:
66
- l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), "~"));
67
- break;
68
- case Complex_Selector::ANCESTOR_OF:
69
- break;
70
- default: break;
54
+ for (auto component : sel->elements()) {
55
+ if (CompoundSelectorObj compound = Cast<CompoundSelector>(component)) {
56
+ if (!compound->empty()) {
57
+ Expression_Obj hh = compound->perform(this);
58
+ if (hh) l->append(hh);
59
+ }
60
+ }
61
+ else if (component) {
62
+ l->append(SASS_MEMORY_NEW(String_Quoted, component->pstate(), component->to_string()));
63
+ }
71
64
  }
72
65
 
73
- Complex_Selector_Obj tail = sel->tail();
74
- if (tail)
75
- {
76
- Expression_Obj tt = tail->perform(this);
77
- if (List* ls = Cast<List>(tt))
78
- { l->concat(ls); }
79
- }
80
66
  if (l->length() == 0) return 0;
81
67
  return l.detach();
82
68
  }
@@ -5,13 +5,8 @@
5
5
  // __EXTENSIONS__ fix on Solaris.
6
6
  #include "sass.hpp"
7
7
 
8
- #include <vector>
9
- #include <iostream>
10
-
11
- #include "ast.hpp"
12
- #include "context.hpp"
8
+ #include "ast_fwd_decl.hpp"
13
9
  #include "operation.hpp"
14
- #include "environment.hpp"
15
10
 
16
11
  namespace Sass {
17
12
 
@@ -19,13 +14,17 @@ namespace Sass {
19
14
 
20
15
  class Listize : public Operation_CRTP<Expression*, Listize> {
21
16
 
17
+ public:
18
+
19
+ static Expression* perform(AST_Node* node);
20
+
22
21
  public:
23
22
  Listize();
24
23
  ~Listize() { }
25
24
 
26
- Expression* operator()(Selector_List*);
27
- Expression* operator()(Complex_Selector*);
28
- Expression* operator()(Compound_Selector*);
25
+ Expression* operator()(SelectorList*);
26
+ Expression* operator()(ComplexSelector*);
27
+ Expression* operator()(CompoundSelector*);
29
28
 
30
29
  // generic fallback
31
30
  template <typename U>
@@ -9,6 +9,10 @@
9
9
  #include <type_traits>
10
10
  #include <vector>
11
11
 
12
+ // https://lokiastari.com/blog/2014/12/30/c-plus-plus-by-example-smart-pointer/index.html
13
+ // https://lokiastari.com/blog/2015/01/15/c-plus-plus-by-example-smart-pointer-part-ii/index.html
14
+ // https://lokiastari.com/blog/2015/01/23/c-plus-plus-by-example-smart-pointer-part-iii/index.html
15
+
12
16
  namespace Sass {
13
17
 
14
18
  class SharedPtr;
@@ -42,6 +46,16 @@ namespace Sass {
42
46
 
43
47
  #endif
44
48
 
49
+ // SharedObj is the base class for all objects that can be stored as a shared object
50
+ // It adds the reference counter and other values directly to the objects
51
+ // This gives a slight overhead when directly used as a stack object, but has some
52
+ // advantages for our code. It is safe to create two shared pointers from the same
53
+ // objects, as the "control block" is directly attached to it. This would lead
54
+ // to undefined behavior with std::shared_ptr. This also avoids the need to
55
+ // allocate additional control blocks and/or the need to dereference two
56
+ // pointers on each operation. This can be optimized in `std::shared_ptr`
57
+ // too by using `std::make_shared` (where the control block and the actual
58
+ // object are allocated in one continuous memory block via one single call).
45
59
  class SharedObj {
46
60
  public:
47
61
  SharedObj() : refcount(0), detached(false) {
@@ -51,7 +65,12 @@ namespace Sass {
51
65
  }
52
66
  virtual ~SharedObj() {
53
67
  #ifdef DEBUG_SHARED_PTR
54
- all.clear();
68
+ for (size_t i = 0; i < all.size(); i++) {
69
+ if (all[i] == this) {
70
+ all.erase(all.begin() + i);
71
+ break;
72
+ }
73
+ }
55
74
  #endif
56
75
  }
57
76
 
@@ -70,7 +89,7 @@ namespace Sass {
70
89
 
71
90
  static void setTaint(bool val) { taint = val; }
72
91
 
73
- virtual const std::string to_string() const = 0;
92
+ virtual std::string to_string() const = 0;
74
93
  protected:
75
94
  friend class SharedPtr;
76
95
  friend class Memory_Manager;
@@ -85,6 +104,9 @@ namespace Sass {
85
104
  #endif
86
105
  };
87
106
 
107
+ // SharedPtr is a intermediate (template-less) base class for SharedImpl.
108
+ // ToDo: there should be a way to include this in SharedImpl and to get
109
+ // ToDo: rid of all the static_cast that are now needed in SharedImpl.
88
110
  class SharedPtr {
89
111
  public:
90
112
  SharedPtr() : node(nullptr) {}
@@ -114,6 +136,11 @@ namespace Sass {
114
136
  // Prevents all SharedPtrs from freeing this node until it is assigned to another SharedPtr.
115
137
  SharedObj* detach() {
116
138
  if (node != nullptr) node->detached = true;
139
+ #ifdef DEBUG_SHARED_PTR
140
+ if (node->dbg) {
141
+ std::cerr << "DETACHING NODE\n";
142
+ }
143
+ #endif
117
144
  return node;
118
145
  }
119
146
 
@@ -136,6 +163,11 @@ namespace Sass {
136
163
  #endif
137
164
  delete node;
138
165
  }
166
+ else if (node->refcount == 0) {
167
+ #ifdef DEBUG_SHARED_PTR
168
+ if (node->dbg) std::cerr << "NODE EVAEDED DELETE " << node << "\n";
169
+ #endif
170
+ }
139
171
  }
140
172
  void incRefCount() {
141
173
  if (node == nullptr) return;
@@ -149,7 +181,8 @@ namespace Sass {
149
181
 
150
182
  template <class T>
151
183
  class SharedImpl : private SharedPtr {
152
- public:
184
+
185
+ public:
153
186
  SharedImpl() : SharedPtr(nullptr) {}
154
187
 
155
188
  template <class U>
@@ -172,9 +205,9 @@ namespace Sass {
172
205
  SharedPtr::operator=(static_cast<const SharedImpl<T>&>(rhs)));
173
206
  }
174
207
 
175
- operator const std::string() const {
208
+ operator std::string() const {
176
209
  if (node) return node->to_string();
177
- return "[nullptr]";
210
+ return "null";
178
211
  }
179
212
 
180
213
  using SharedPtr::isNull;
@@ -185,6 +218,7 @@ namespace Sass {
185
218
  T* operator-> () const { return static_cast<T*>(this->obj()); };
186
219
  T* ptr () const { return static_cast<T*>(this->obj()); };
187
220
  T* detach() { return static_cast<T*>(SharedPtr::detach()); }
221
+
188
222
  };
189
223
 
190
224
  // Comparison operators, based on: