sassc 2.2.1 → 2.4.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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/CHANGELOG.md +18 -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 +4 -0
  9. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  10. data/ext/libsass/src/ast.cpp +158 -168
  11. data/ext/libsass/src/ast.hpp +389 -230
  12. data/ext/libsass/src/ast_def_macros.hpp +18 -10
  13. data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
  14. data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
  15. data/ext/libsass/src/ast_helpers.hpp +292 -0
  16. data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
  17. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  18. data/ext/libsass/src/ast_sel_unify.cpp +207 -212
  19. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  20. data/ext/libsass/src/ast_selectors.cpp +594 -1026
  21. data/ext/libsass/src/ast_selectors.hpp +339 -385
  22. data/ext/libsass/src/ast_supports.cpp +36 -52
  23. data/ext/libsass/src/ast_supports.hpp +29 -29
  24. data/ext/libsass/src/ast_values.cpp +271 -84
  25. data/ext/libsass/src/ast_values.hpp +116 -107
  26. data/ext/libsass/src/backtrace.cpp +9 -9
  27. data/ext/libsass/src/backtrace.hpp +5 -5
  28. data/ext/libsass/src/base64vlq.cpp +2 -2
  29. data/ext/libsass/src/base64vlq.hpp +1 -1
  30. data/ext/libsass/src/bind.cpp +18 -18
  31. data/ext/libsass/src/bind.hpp +1 -1
  32. data/ext/libsass/src/c2ast.cpp +3 -3
  33. data/ext/libsass/src/c2ast.hpp +1 -1
  34. data/ext/libsass/src/cencode.c +4 -6
  35. data/ext/libsass/src/check_nesting.cpp +40 -41
  36. data/ext/libsass/src/check_nesting.hpp +6 -2
  37. data/ext/libsass/src/color_maps.cpp +14 -13
  38. data/ext/libsass/src/color_maps.hpp +1 -9
  39. data/ext/libsass/src/constants.cpp +5 -0
  40. data/ext/libsass/src/constants.hpp +6 -0
  41. data/ext/libsass/src/context.cpp +92 -119
  42. data/ext/libsass/src/context.hpp +41 -53
  43. data/ext/libsass/src/cssize.cpp +66 -149
  44. data/ext/libsass/src/cssize.hpp +17 -23
  45. data/ext/libsass/src/dart_helpers.hpp +199 -0
  46. data/ext/libsass/src/debugger.hpp +451 -295
  47. data/ext/libsass/src/emitter.cpp +15 -16
  48. data/ext/libsass/src/emitter.hpp +10 -12
  49. data/ext/libsass/src/environment.cpp +27 -27
  50. data/ext/libsass/src/environment.hpp +29 -24
  51. data/ext/libsass/src/error_handling.cpp +62 -41
  52. data/ext/libsass/src/error_handling.hpp +61 -51
  53. data/ext/libsass/src/eval.cpp +167 -281
  54. data/ext/libsass/src/eval.hpp +27 -29
  55. data/ext/libsass/src/eval_selectors.cpp +75 -0
  56. data/ext/libsass/src/expand.cpp +275 -222
  57. data/ext/libsass/src/expand.hpp +36 -16
  58. data/ext/libsass/src/extender.cpp +1188 -0
  59. data/ext/libsass/src/extender.hpp +399 -0
  60. data/ext/libsass/src/extension.cpp +43 -0
  61. data/ext/libsass/src/extension.hpp +89 -0
  62. data/ext/libsass/src/file.cpp +81 -72
  63. data/ext/libsass/src/file.hpp +28 -37
  64. data/ext/libsass/src/fn_colors.cpp +20 -18
  65. data/ext/libsass/src/fn_lists.cpp +30 -29
  66. data/ext/libsass/src/fn_maps.cpp +3 -3
  67. data/ext/libsass/src/fn_miscs.cpp +34 -46
  68. data/ext/libsass/src/fn_numbers.cpp +20 -13
  69. data/ext/libsass/src/fn_selectors.cpp +98 -128
  70. data/ext/libsass/src/fn_strings.cpp +47 -33
  71. data/ext/libsass/src/fn_utils.cpp +31 -29
  72. data/ext/libsass/src/fn_utils.hpp +17 -11
  73. data/ext/libsass/src/inspect.cpp +186 -148
  74. data/ext/libsass/src/inspect.hpp +31 -29
  75. data/ext/libsass/src/lexer.cpp +20 -82
  76. data/ext/libsass/src/lexer.hpp +5 -16
  77. data/ext/libsass/src/listize.cpp +23 -37
  78. data/ext/libsass/src/listize.hpp +8 -9
  79. data/ext/libsass/src/mapping.hpp +1 -0
  80. data/ext/libsass/src/memory/allocator.cpp +48 -0
  81. data/ext/libsass/src/memory/allocator.hpp +138 -0
  82. data/ext/libsass/src/memory/config.hpp +20 -0
  83. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  84. data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
  85. data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
  86. data/ext/libsass/src/memory.hpp +12 -0
  87. data/ext/libsass/src/operation.hpp +71 -61
  88. data/ext/libsass/src/operators.cpp +19 -18
  89. data/ext/libsass/src/operators.hpp +11 -11
  90. data/ext/libsass/src/ordered_map.hpp +112 -0
  91. data/ext/libsass/src/output.cpp +45 -64
  92. data/ext/libsass/src/output.hpp +6 -6
  93. data/ext/libsass/src/parser.cpp +512 -700
  94. data/ext/libsass/src/parser.hpp +89 -97
  95. data/ext/libsass/src/parser_selectors.cpp +189 -0
  96. data/ext/libsass/src/permutate.hpp +164 -0
  97. data/ext/libsass/src/plugins.cpp +7 -7
  98. data/ext/libsass/src/plugins.hpp +8 -8
  99. data/ext/libsass/src/position.cpp +7 -26
  100. data/ext/libsass/src/position.hpp +44 -21
  101. data/ext/libsass/src/prelexer.cpp +6 -6
  102. data/ext/libsass/src/remove_placeholders.cpp +55 -56
  103. data/ext/libsass/src/remove_placeholders.hpp +21 -18
  104. data/ext/libsass/src/sass.cpp +16 -15
  105. data/ext/libsass/src/sass.hpp +10 -5
  106. data/ext/libsass/src/sass2scss.cpp +4 -4
  107. data/ext/libsass/src/sass_context.cpp +91 -122
  108. data/ext/libsass/src/sass_context.hpp +2 -2
  109. data/ext/libsass/src/sass_functions.cpp +1 -1
  110. data/ext/libsass/src/sass_values.cpp +8 -11
  111. data/ext/libsass/src/settings.hpp +19 -0
  112. data/ext/libsass/src/source.cpp +69 -0
  113. data/ext/libsass/src/source.hpp +95 -0
  114. data/ext/libsass/src/source_data.hpp +32 -0
  115. data/ext/libsass/src/source_map.cpp +22 -18
  116. data/ext/libsass/src/source_map.hpp +12 -9
  117. data/ext/libsass/src/stylesheet.cpp +22 -0
  118. data/ext/libsass/src/stylesheet.hpp +57 -0
  119. data/ext/libsass/src/to_value.cpp +2 -2
  120. data/ext/libsass/src/to_value.hpp +1 -1
  121. data/ext/libsass/src/units.cpp +24 -22
  122. data/ext/libsass/src/units.hpp +8 -8
  123. data/ext/libsass/src/utf8_string.cpp +9 -10
  124. data/ext/libsass/src/utf8_string.hpp +7 -6
  125. data/ext/libsass/src/util.cpp +48 -50
  126. data/ext/libsass/src/util.hpp +20 -21
  127. data/ext/libsass/src/util_string.cpp +111 -61
  128. data/ext/libsass/src/util_string.hpp +62 -8
  129. data/ext/libsass/src/values.cpp +12 -12
  130. data/lib/sassc/engine.rb +5 -3
  131. data/lib/sassc/functions_handler.rb +8 -8
  132. data/lib/sassc/native.rb +4 -6
  133. data/lib/sassc/script.rb +4 -4
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/functions_test.rb +18 -1
  136. data/test/native_test.rb +4 -4
  137. metadata +29 -15
  138. data/ext/libsass/src/extend.cpp +0 -2132
  139. data/ext/libsass/src/extend.hpp +0 -86
  140. data/ext/libsass/src/node.cpp +0 -322
  141. data/ext/libsass/src/node.hpp +0 -118
  142. data/ext/libsass/src/paths.hpp +0 -71
  143. data/ext/libsass/src/sass_util.cpp +0 -152
  144. data/ext/libsass/src/sass_util.hpp +0 -256
  145. data/ext/libsass/src/subset_map.cpp +0 -58
  146. data/ext/libsass/src/subset_map.hpp +0 -76
  147. data/lib/sassc/native/lib_c.rb +0 -21
@@ -0,0 +1,186 @@
1
+ #ifndef SASS_MEMORY_POOL_H
2
+ #define SASS_MEMORY_POOL_H
3
+
4
+ #include <stdlib.h>
5
+ #include <iostream>
6
+ #include <algorithm>
7
+ #include <climits>
8
+ #include <vector>
9
+
10
+ namespace Sass {
11
+
12
+ // SIMPLE MEMORY-POOL ALLOCATOR WITH FREE-LIST ON TOP
13
+
14
+ // This is a memory pool allocator with a free list on top.
15
+ // We only allocate memory arenas from the system in specific
16
+ // sizes (`SassAllocatorArenaSize`). Users claim memory slices
17
+ // of certain sizes from the pool. If the allocation is too big
18
+ // to fit into our buckets, we use regular malloc/free instead.
19
+
20
+ // When the systems starts, we allocate the first arena and then
21
+ // start to give out addresses to memory slices. During that
22
+ // we steadily increase `offset` until the current arena is full.
23
+ // Once that happens we allocate a new arena and continue.
24
+ // https://en.wikipedia.org/wiki/Memory_pool
25
+
26
+ // Fragments that get deallocated are not really freed, we put
27
+ // them on our free-list. For every bucket we have a pointer to
28
+ // the first item for reuse. That item itself holds a pointer to
29
+ // the previously free item (regular free-list implementation).
30
+ // https://en.wikipedia.org/wiki/Free_list
31
+
32
+ // On allocation calls we first check if there is any suitable
33
+ // item on the free-list. If there is we pop it from the stack
34
+ // and return it to the caller. Otherwise we have to take out
35
+ // a new slice from the current `arena` and increase `offset`.
36
+
37
+ // Note that this is not thread safe. This is on purpose as we
38
+ // want to use the memory pool in a thread local usage. In order
39
+ // to get this thread safe you need to only allocate one pool
40
+ // per thread. This can be achieved by using thread local PODs.
41
+ // Simply create a pool on the first allocation and dispose
42
+ // it once all allocations have been returned. E.g. by using:
43
+ // static thread_local size_t allocations;
44
+ // static thread_local MemoryPool* pool;
45
+
46
+ class MemoryPool {
47
+
48
+ // Current arena we fill up
49
+ char* arena;
50
+
51
+ // Position into the arena
52
+ size_t offset = std::string::npos;
53
+
54
+ // A list of full arenas
55
+ std::vector<void*> arenas;
56
+
57
+ // One pointer for every bucket (zero init)
58
+ #ifdef _MSC_VER
59
+ #pragma warning (suppress:4351)
60
+ #endif
61
+ void* freeList[SassAllocatorBuckets]{};
62
+
63
+ // Increase the address until it sits on a
64
+ // memory aligned address (maybe use `aligned`).
65
+ inline static size_t alignMemAddr(size_t addr) {
66
+ return (addr + SASS_MEM_ALIGN - 1) & ~(SASS_MEM_ALIGN - 1);
67
+ }
68
+
69
+ public:
70
+
71
+ // Default ctor
72
+ MemoryPool() :
73
+ // Wait for first allocation
74
+ arena(nullptr),
75
+ // Set to maximum value in order to
76
+ // make an allocation on the first run
77
+ offset(std::string::npos)
78
+ {
79
+ }
80
+
81
+ // Destructor
82
+ ~MemoryPool() {
83
+ // Delete full arenas
84
+ for (auto area : arenas) {
85
+ free(area);
86
+ }
87
+ // Delete current arena
88
+ free(arena);
89
+
90
+ }
91
+
92
+ // Allocate a slice of the memory pool
93
+ void* allocate(size_t size)
94
+ {
95
+
96
+ // Increase size so its memory is aligned
97
+ size = alignMemAddr(
98
+ // Make sure we have enough space for us to
99
+ // create the pointer to the free list later
100
+ std::max(sizeof(void*), size)
101
+ // and the size needed for our book-keeping
102
+ + SassAllocatorBookSize);
103
+
104
+ // Size must be multiple of alignment
105
+ // So we can derive bucket index from it
106
+ size_t bucket = size / SASS_MEM_ALIGN;
107
+
108
+ // Everything bigger is allocated via malloc
109
+ // Malloc is optimized for exactly this case
110
+ if (bucket >= SassAllocatorBuckets) {
111
+ char* buffer = (char*)malloc(size);
112
+ if (buffer == nullptr) {
113
+ throw std::bad_alloc();
114
+ }
115
+ // Mark it for deallocation via free
116
+ ((unsigned int*)buffer)[0] = UINT_MAX;
117
+ // Return pointer after our book-keeping space
118
+ return (void*)(buffer + SassAllocatorBookSize);
119
+ }
120
+ // Use custom allocator
121
+ else {
122
+ // Get item from free list
123
+ void*& free = freeList[bucket];
124
+ // Do we have a free item?
125
+ if (free != nullptr) {
126
+ // Copy pointer to return
127
+ void* ptr = free;
128
+ // Update free list pointer
129
+ free = ((void**)ptr)[0];
130
+ // Return popped item
131
+ return ptr;
132
+ }
133
+ }
134
+
135
+ // Make sure we have enough space in the arena
136
+ if (!arena || offset > SassAllocatorArenaSize - size) {
137
+ if (arena) arenas.emplace_back(arena);
138
+ arena = (char*)malloc(SassAllocatorArenaSize);
139
+ if (arena == nullptr) throw std::bad_alloc();
140
+ offset = SassAllocatorArenaHeadSize;
141
+ }
142
+
143
+ // Get pointer into the arena
144
+ char* buffer = arena + offset;
145
+ // Consume object size
146
+ offset += size;
147
+
148
+ // Set the bucket index for this slice
149
+ ((unsigned int*)buffer)[0] = (unsigned int)bucket;
150
+
151
+ // Return pointer after our book-keeping space
152
+ return (void*)(buffer + SassAllocatorBookSize);
153
+
154
+ }
155
+ // EO allocate
156
+
157
+ void deallocate(void* ptr)
158
+ {
159
+
160
+ // Rewind buffer from pointer
161
+ char* buffer = (char*)ptr -
162
+ SassAllocatorBookSize;
163
+
164
+ // Get the bucket index stored in the header
165
+ unsigned int bucket = ((unsigned int*)buffer)[0];
166
+
167
+ // Check allocation method
168
+ if (bucket != UINT_MAX) {
169
+ // Let memory point to previous item in free list
170
+ ((void**)ptr)[0] = freeList[bucket];
171
+ // Free list now points to our memory
172
+ freeList[bucket] = (void*)ptr;
173
+ }
174
+ else {
175
+ // Release memory
176
+ free(buffer);
177
+ }
178
+
179
+ }
180
+ // EO deallocate
181
+
182
+ };
183
+
184
+ }
185
+
186
+ #endif
@@ -2,7 +2,7 @@
2
2
  #include <iostream>
3
3
  #include <typeinfo>
4
4
 
5
- #include "SharedPtr.hpp"
5
+ #include "shared_ptr.hpp"
6
6
  #include "../ast_fwd_decl.hpp"
7
7
 
8
8
  #ifdef DEBUG_SHARED_PTR
@@ -26,7 +26,7 @@ namespace Sass {
26
26
  }
27
27
  }
28
28
  }
29
- std::vector<SharedObj*> SharedObj::all;
29
+ sass::vector<SharedObj*> SharedObj::all;
30
30
  #endif
31
31
 
32
32
  bool SharedObj::taint = false;
@@ -3,14 +3,21 @@
3
3
 
4
4
  #include "sass/base.h"
5
5
 
6
+ #include "../sass.hpp"
7
+ #include "allocator.hpp"
6
8
  #include <cstddef>
7
9
  #include <iostream>
8
10
  #include <string>
9
11
  #include <type_traits>
10
12
  #include <vector>
11
13
 
14
+ // https://lokiastari.com/blog/2014/12/30/c-plus-plus-by-example-smart-pointer/index.html
15
+ // https://lokiastari.com/blog/2015/01/15/c-plus-plus-by-example-smart-pointer-part-ii/index.html
16
+ // https://lokiastari.com/blog/2015/01/23/c-plus-plus-by-example-smart-pointer-part-iii/index.html
17
+
12
18
  namespace Sass {
13
19
 
20
+ // Forward declaration
14
21
  class SharedPtr;
15
22
 
16
23
  ///////////////////////////////////////////////////////////////////////////////
@@ -42,6 +49,16 @@ namespace Sass {
42
49
 
43
50
  #endif
44
51
 
52
+ // SharedObj is the base class for all objects that can be stored as a shared object
53
+ // It adds the reference counter and other values directly to the objects
54
+ // This gives a slight overhead when directly used as a stack object, but has some
55
+ // advantages for our code. It is safe to create two shared pointers from the same
56
+ // objects, as the "control block" is directly attached to it. This would lead
57
+ // to undefined behavior with std::shared_ptr. This also avoids the need to
58
+ // allocate additional control blocks and/or the need to dereference two
59
+ // pointers on each operation. This can be optimized in `std::shared_ptr`
60
+ // too by using `std::make_shared` (where the control block and the actual
61
+ // object are allocated in one continuous memory block via one single call).
45
62
  class SharedObj {
46
63
  public:
47
64
  SharedObj() : refcount(0), detached(false) {
@@ -51,18 +68,23 @@ namespace Sass {
51
68
  }
52
69
  virtual ~SharedObj() {
53
70
  #ifdef DEBUG_SHARED_PTR
54
- all.clear();
71
+ for (size_t i = 0; i < all.size(); i++) {
72
+ if (all[i] == this) {
73
+ all.erase(all.begin() + i);
74
+ break;
75
+ }
76
+ }
55
77
  #endif
56
78
  }
57
79
 
58
80
  #ifdef DEBUG_SHARED_PTR
59
81
  static void dumpMemLeaks();
60
- SharedObj* trace(std::string file, size_t line) {
82
+ SharedObj* trace(sass::string file, size_t line) {
61
83
  this->file = file;
62
84
  this->line = line;
63
85
  return this;
64
86
  }
65
- std::string getDbgFile() { return file; }
87
+ sass::string getDbgFile() { return file; }
66
88
  size_t getDbgLine() { return line; }
67
89
  void setDbg(bool dbg) { this->dbg = dbg; }
68
90
  size_t getRefCount() const { return refcount; }
@@ -70,7 +92,16 @@ namespace Sass {
70
92
 
71
93
  static void setTaint(bool val) { taint = val; }
72
94
 
73
- virtual const std::string to_string() const = 0;
95
+ #ifdef SASS_CUSTOM_ALLOCATOR
96
+ inline void* operator new(size_t nbytes) {
97
+ return allocateMem(nbytes);
98
+ }
99
+ inline void operator delete(void* ptr) {
100
+ return deallocateMem(ptr);
101
+ }
102
+ #endif
103
+
104
+ virtual sass::string to_string() const = 0;
74
105
  protected:
75
106
  friend class SharedPtr;
76
107
  friend class Memory_Manager;
@@ -78,13 +109,16 @@ namespace Sass {
78
109
  bool detached;
79
110
  static bool taint;
80
111
  #ifdef DEBUG_SHARED_PTR
81
- std::string file;
112
+ sass::string file;
82
113
  size_t line;
83
114
  bool dbg = false;
84
- static std::vector<SharedObj*> all;
115
+ static sass::vector<SharedObj*> all;
85
116
  #endif
86
117
  };
87
118
 
119
+ // SharedPtr is a intermediate (template-less) base class for SharedImpl.
120
+ // ToDo: there should be a way to include this in SharedImpl and to get
121
+ // ToDo: rid of all the static_cast that are now needed in SharedImpl.
88
122
  class SharedPtr {
89
123
  public:
90
124
  SharedPtr() : node(nullptr) {}
@@ -114,6 +148,11 @@ namespace Sass {
114
148
  // Prevents all SharedPtrs from freeing this node until it is assigned to another SharedPtr.
115
149
  SharedObj* detach() {
116
150
  if (node != nullptr) node->detached = true;
151
+ #ifdef DEBUG_SHARED_PTR
152
+ if (node->dbg) {
153
+ std::cerr << "DETACHING NODE\n";
154
+ }
155
+ #endif
117
156
  return node;
118
157
  }
119
158
 
@@ -136,6 +175,11 @@ namespace Sass {
136
175
  #endif
137
176
  delete node;
138
177
  }
178
+ else if (node->refcount == 0) {
179
+ #ifdef DEBUG_SHARED_PTR
180
+ if (node->dbg) std::cerr << "NODE EVAEDED DELETE " << node << "\n";
181
+ #endif
182
+ }
139
183
  }
140
184
  void incRefCount() {
141
185
  if (node == nullptr) return;
@@ -149,7 +193,8 @@ namespace Sass {
149
193
 
150
194
  template <class T>
151
195
  class SharedImpl : private SharedPtr {
152
- public:
196
+
197
+ public:
153
198
  SharedImpl() : SharedPtr(nullptr) {}
154
199
 
155
200
  template <class U>
@@ -172,9 +217,9 @@ namespace Sass {
172
217
  SharedPtr::operator=(static_cast<const SharedImpl<T>&>(rhs)));
173
218
  }
174
219
 
175
- operator const std::string() const {
220
+ operator sass::string() const {
176
221
  if (node) return node->to_string();
177
- return "[nullptr]";
222
+ return "null";
178
223
  }
179
224
 
180
225
  using SharedPtr::isNull;
@@ -185,6 +230,7 @@ namespace Sass {
185
230
  T* operator-> () const { return static_cast<T*>(this->obj()); };
186
231
  T* ptr () const { return static_cast<T*>(this->obj()); };
187
232
  T* detach() { return static_cast<T*>(SharedPtr::detach()); }
233
+
188
234
  };
189
235
 
190
236
  // Comparison operators, based on:
@@ -0,0 +1,12 @@
1
+ #ifndef SASS_MEMORY_H
2
+ #define SASS_MEMORY_H
3
+
4
+ #include "settings.hpp"
5
+
6
+ // Include memory headers
7
+ #include "memory/config.hpp"
8
+ #include "memory/allocator.hpp"
9
+ #include "memory/shared_ptr.hpp"
10
+ #include "memory/memory_pool.hpp"
11
+
12
+ #endif
@@ -1,9 +1,14 @@
1
1
  #ifndef SASS_OPERATION_H
2
2
  #define SASS_OPERATION_H
3
3
 
4
+ // sass.hpp must go before all system headers to get the
5
+ // __EXTENSIONS__ fix on Solaris.
6
+ #include "sass.hpp"
7
+
4
8
  // base classes to implement curiously recurring template pattern (CRTP)
5
9
  // https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
6
10
 
11
+ #include <typeinfo>
7
12
  #include <stdexcept>
8
13
 
9
14
  #include "ast_fwd_decl.hpp"
@@ -14,13 +19,13 @@ namespace Sass {
14
19
  #define ATTACH_ABSTRACT_CRTP_PERFORM_METHODS()\
15
20
  virtual void perform(Operation<void>* op) = 0; \
16
21
  virtual Value* perform(Operation<Value*>* op) = 0; \
17
- virtual std::string perform(Operation<std::string>* op) = 0; \
22
+ virtual sass::string perform(Operation<sass::string>* op) = 0; \
18
23
  virtual AST_Node* perform(Operation<AST_Node*>* op) = 0; \
19
24
  virtual Selector* perform(Operation<Selector*>* op) = 0; \
20
25
  virtual Statement* perform(Operation<Statement*>* op) = 0; \
21
26
  virtual Expression* perform(Operation<Expression*>* op) = 0; \
22
27
  virtual union Sass_Value* perform(Operation<union Sass_Value*>* op) = 0; \
23
- virtual Supports_Condition* perform(Operation<Supports_Condition*>* op) = 0; \
28
+ virtual SupportsCondition* perform(Operation<SupportsCondition*>* op) = 0; \
24
29
 
25
30
  // you must add operators to every class
26
31
  // ensures `this` of actual instance type
@@ -29,13 +34,13 @@ namespace Sass {
29
34
  #define ATTACH_CRTP_PERFORM_METHODS()\
30
35
  virtual void perform(Operation<void>* op) override { return (*op)(this); } \
31
36
  virtual Value* perform(Operation<Value*>* op) override { return (*op)(this); } \
32
- virtual std::string perform(Operation<std::string>* op) override { return (*op)(this); } \
37
+ virtual sass::string perform(Operation<sass::string>* op) override { return (*op)(this); } \
33
38
  virtual AST_Node* perform(Operation<AST_Node*>* op) override { return (*op)(this); } \
34
39
  virtual Selector* perform(Operation<Selector*>* op) override { return (*op)(this); } \
35
40
  virtual Statement* perform(Operation<Statement*>* op) override { return (*op)(this); } \
36
41
  virtual Expression* perform(Operation<Expression*>* op) override { return (*op)(this); } \
37
42
  virtual union Sass_Value* perform(Operation<union Sass_Value*>* op) override { return (*op)(this); } \
38
- virtual Supports_Condition* perform(Operation<Supports_Condition*>* op) override { return (*op)(this); } \
43
+ virtual SupportsCondition* perform(Operation<SupportsCondition*>* op) override { return (*op)(this); } \
39
44
 
40
45
  template<typename T>
41
46
  class Operation {
@@ -43,29 +48,31 @@ namespace Sass {
43
48
  virtual T operator()(AST_Node* x) = 0;
44
49
  // statements
45
50
  virtual T operator()(Block* x) = 0;
46
- virtual T operator()(Ruleset* x) = 0;
51
+ virtual T operator()(StyleRule* x) = 0;
47
52
  virtual T operator()(Bubble* x) = 0;
48
53
  virtual T operator()(Trace* x) = 0;
49
- virtual T operator()(Supports_Block* x) = 0;
50
- virtual T operator()(Media_Block* x) = 0;
51
- virtual T operator()(At_Root_Block* x) = 0;
52
- virtual T operator()(Directive* x) = 0;
54
+ virtual T operator()(SupportsRule* x) = 0;
55
+ virtual T operator()(MediaRule* x) = 0;
56
+ virtual T operator()(CssMediaRule* x) = 0;
57
+ virtual T operator()(CssMediaQuery* x) = 0;
58
+ virtual T operator()(AtRootRule* x) = 0;
59
+ virtual T operator()(AtRule* x) = 0;
53
60
  virtual T operator()(Keyframe_Rule* x) = 0;
54
61
  virtual T operator()(Declaration* x) = 0;
55
62
  virtual T operator()(Assignment* x) = 0;
56
63
  virtual T operator()(Import* x) = 0;
57
64
  virtual T operator()(Import_Stub* x) = 0;
58
- virtual T operator()(Warning* x) = 0;
59
- virtual T operator()(Error* x) = 0;
60
- virtual T operator()(Debug* x) = 0;
65
+ virtual T operator()(WarningRule* x) = 0;
66
+ virtual T operator()(ErrorRule* x) = 0;
67
+ virtual T operator()(DebugRule* x) = 0;
61
68
  virtual T operator()(Comment* x) = 0;
62
69
  virtual T operator()(If* x) = 0;
63
- virtual T operator()(For* x) = 0;
64
- virtual T operator()(Each* x) = 0;
65
- virtual T operator()(While* x) = 0;
70
+ virtual T operator()(ForRule* x) = 0;
71
+ virtual T operator()(EachRule* x) = 0;
72
+ virtual T operator()(WhileRule* x) = 0;
66
73
  virtual T operator()(Return* x) = 0;
67
74
  virtual T operator()(Content* x) = 0;
68
- virtual T operator()(Extension* x) = 0;
75
+ virtual T operator()(ExtendRule* x) = 0;
69
76
  virtual T operator()(Definition* x) = 0;
70
77
  virtual T operator()(Mixin_Call* x) = 0;
71
78
  // expressions
@@ -87,15 +94,14 @@ namespace Sass {
87
94
  virtual T operator()(String_Schema* x) = 0;
88
95
  virtual T operator()(String_Quoted* x) = 0;
89
96
  virtual T operator()(String_Constant* x) = 0;
90
- virtual T operator()(Supports_Condition* x) = 0;
91
- virtual T operator()(Supports_Operator* x) = 0;
92
- virtual T operator()(Supports_Negation* x) = 0;
93
- virtual T operator()(Supports_Declaration* x) = 0;
97
+ virtual T operator()(SupportsCondition* x) = 0;
98
+ virtual T operator()(SupportsOperation* x) = 0;
99
+ virtual T operator()(SupportsNegation* x) = 0;
100
+ virtual T operator()(SupportsDeclaration* x) = 0;
94
101
  virtual T operator()(Supports_Interpolation* x) = 0;
95
- virtual T operator()(Media_Query* x) = 0;
102
+ virtual T operator()(Media_Query* x) = 0;
96
103
  virtual T operator()(Media_Query_Expression* x) = 0;
97
104
  virtual T operator()(At_Root_Query* x) = 0;
98
- virtual T operator()(Parent_Selector* x) = 0;
99
105
  virtual T operator()(Parent_Reference* x) = 0;
100
106
  // parameters and arguments
101
107
  virtual T operator()(Parameter* x) = 0;
@@ -104,51 +110,55 @@ namespace Sass {
104
110
  virtual T operator()(Arguments* x) = 0;
105
111
  // selectors
106
112
  virtual T operator()(Selector_Schema* x) = 0;
107
- virtual T operator()(Placeholder_Selector* x) = 0;
108
- virtual T operator()(Type_Selector* x) = 0;
109
- virtual T operator()(Class_Selector* x) = 0;
110
- virtual T operator()(Id_Selector* x) = 0;
111
- virtual T operator()(Attribute_Selector* x) = 0;
112
- virtual T operator()(Pseudo_Selector* x) = 0;
113
- virtual T operator()(Wrapped_Selector* x) = 0;
114
- virtual T operator()(Compound_Selector* x)= 0;
115
- virtual T operator()(Complex_Selector* x) = 0;
116
- virtual T operator()(Selector_List* x) = 0;
113
+ virtual T operator()(PlaceholderSelector* x) = 0;
114
+ virtual T operator()(TypeSelector* x) = 0;
115
+ virtual T operator()(ClassSelector* x) = 0;
116
+ virtual T operator()(IDSelector* x) = 0;
117
+ virtual T operator()(AttributeSelector* x) = 0;
118
+ virtual T operator()(PseudoSelector* x) = 0;
119
+ virtual T operator()(SelectorComponent* x) = 0;
120
+ virtual T operator()(SelectorCombinator* x) = 0;
121
+ virtual T operator()(CompoundSelector* x) = 0;
122
+ virtual T operator()(ComplexSelector* x) = 0;
123
+ virtual T operator()(SelectorList* x) = 0;
124
+
117
125
  };
118
126
 
119
127
  // example: Operation_CRTP<Expression*, Eval>
120
128
  // T is the base return type of all visitors
121
129
  // D is the class derived visitor class
122
- // normaly you want to implement all operators
130
+ // normally you want to implement all operators
123
131
  template <typename T, typename D>
124
132
  class Operation_CRTP : public Operation<T> {
125
133
  public:
126
134
  T operator()(AST_Node* x) { return static_cast<D*>(this)->fallback(x); }
127
135
  // statements
128
136
  T operator()(Block* x) { return static_cast<D*>(this)->fallback(x); }
129
- T operator()(Ruleset* x) { return static_cast<D*>(this)->fallback(x); }
137
+ T operator()(StyleRule* x) { return static_cast<D*>(this)->fallback(x); }
130
138
  T operator()(Bubble* x) { return static_cast<D*>(this)->fallback(x); }
131
139
  T operator()(Trace* x) { return static_cast<D*>(this)->fallback(x); }
132
- T operator()(Supports_Block* x) { return static_cast<D*>(this)->fallback(x); }
133
- T operator()(Media_Block* x) { return static_cast<D*>(this)->fallback(x); }
134
- T operator()(At_Root_Block* x) { return static_cast<D*>(this)->fallback(x); }
135
- T operator()(Directive* x) { return static_cast<D*>(this)->fallback(x); }
140
+ T operator()(SupportsRule* x) { return static_cast<D*>(this)->fallback(x); }
141
+ T operator()(MediaRule* x) { return static_cast<D*>(this)->fallback(x); }
142
+ T operator()(CssMediaRule* x) { return static_cast<D*>(this)->fallback(x); }
143
+ T operator()(CssMediaQuery* x) { return static_cast<D*>(this)->fallback(x); }
144
+ T operator()(AtRootRule* x) { return static_cast<D*>(this)->fallback(x); }
145
+ T operator()(AtRule* x) { return static_cast<D*>(this)->fallback(x); }
136
146
  T operator()(Keyframe_Rule* x) { return static_cast<D*>(this)->fallback(x); }
137
147
  T operator()(Declaration* x) { return static_cast<D*>(this)->fallback(x); }
138
148
  T operator()(Assignment* x) { return static_cast<D*>(this)->fallback(x); }
139
149
  T operator()(Import* x) { return static_cast<D*>(this)->fallback(x); }
140
150
  T operator()(Import_Stub* x) { return static_cast<D*>(this)->fallback(x); }
141
- T operator()(Warning* x) { return static_cast<D*>(this)->fallback(x); }
142
- T operator()(Error* x) { return static_cast<D*>(this)->fallback(x); }
143
- T operator()(Debug* x) { return static_cast<D*>(this)->fallback(x); }
151
+ T operator()(WarningRule* x) { return static_cast<D*>(this)->fallback(x); }
152
+ T operator()(ErrorRule* x) { return static_cast<D*>(this)->fallback(x); }
153
+ T operator()(DebugRule* x) { return static_cast<D*>(this)->fallback(x); }
144
154
  T operator()(Comment* x) { return static_cast<D*>(this)->fallback(x); }
145
155
  T operator()(If* x) { return static_cast<D*>(this)->fallback(x); }
146
- T operator()(For* x) { return static_cast<D*>(this)->fallback(x); }
147
- T operator()(Each* x) { return static_cast<D*>(this)->fallback(x); }
148
- T operator()(While* x) { return static_cast<D*>(this)->fallback(x); }
156
+ T operator()(ForRule* x) { return static_cast<D*>(this)->fallback(x); }
157
+ T operator()(EachRule* x) { return static_cast<D*>(this)->fallback(x); }
158
+ T operator()(WhileRule* x) { return static_cast<D*>(this)->fallback(x); }
149
159
  T operator()(Return* x) { return static_cast<D*>(this)->fallback(x); }
150
160
  T operator()(Content* x) { return static_cast<D*>(this)->fallback(x); }
151
- T operator()(Extension* x) { return static_cast<D*>(this)->fallback(x); }
161
+ T operator()(ExtendRule* x) { return static_cast<D*>(this)->fallback(x); }
152
162
  T operator()(Definition* x) { return static_cast<D*>(this)->fallback(x); }
153
163
  T operator()(Mixin_Call* x) { return static_cast<D*>(this)->fallback(x); }
154
164
  // expressions
@@ -170,15 +180,14 @@ namespace Sass {
170
180
  T operator()(String_Schema* x) { return static_cast<D*>(this)->fallback(x); }
171
181
  T operator()(String_Constant* x) { return static_cast<D*>(this)->fallback(x); }
172
182
  T operator()(String_Quoted* x) { return static_cast<D*>(this)->fallback(x); }
173
- T operator()(Supports_Condition* x) { return static_cast<D*>(this)->fallback(x); }
174
- T operator()(Supports_Operator* x) { return static_cast<D*>(this)->fallback(x); }
175
- T operator()(Supports_Negation* x) { return static_cast<D*>(this)->fallback(x); }
176
- T operator()(Supports_Declaration* x) { return static_cast<D*>(this)->fallback(x); }
183
+ T operator()(SupportsCondition* x) { return static_cast<D*>(this)->fallback(x); }
184
+ T operator()(SupportsOperation* x) { return static_cast<D*>(this)->fallback(x); }
185
+ T operator()(SupportsNegation* x) { return static_cast<D*>(this)->fallback(x); }
186
+ T operator()(SupportsDeclaration* x) { return static_cast<D*>(this)->fallback(x); }
177
187
  T operator()(Supports_Interpolation* x) { return static_cast<D*>(this)->fallback(x); }
178
188
  T operator()(Media_Query* x) { return static_cast<D*>(this)->fallback(x); }
179
189
  T operator()(Media_Query_Expression* x) { return static_cast<D*>(this)->fallback(x); }
180
190
  T operator()(At_Root_Query* x) { return static_cast<D*>(this)->fallback(x); }
181
- T operator()(Parent_Selector* x) { return static_cast<D*>(this)->fallback(x); }
182
191
  T operator()(Parent_Reference* x) { return static_cast<D*>(this)->fallback(x); }
183
192
  // parameters and arguments
184
193
  T operator()(Parameter* x) { return static_cast<D*>(this)->fallback(x); }
@@ -187,20 +196,21 @@ namespace Sass {
187
196
  T operator()(Arguments* x) { return static_cast<D*>(this)->fallback(x); }
188
197
  // selectors
189
198
  T operator()(Selector_Schema* x) { return static_cast<D*>(this)->fallback(x); }
190
- T operator()(Placeholder_Selector* x) { return static_cast<D*>(this)->fallback(x); }
191
- T operator()(Type_Selector* x) { return static_cast<D*>(this)->fallback(x); }
192
- T operator()(Class_Selector* x) { return static_cast<D*>(this)->fallback(x); }
193
- T operator()(Id_Selector* x) { return static_cast<D*>(this)->fallback(x); }
194
- T operator()(Attribute_Selector* x) { return static_cast<D*>(this)->fallback(x); }
195
- T operator()(Pseudo_Selector* x) { return static_cast<D*>(this)->fallback(x); }
196
- T operator()(Wrapped_Selector* x) { return static_cast<D*>(this)->fallback(x); }
197
- T operator()(Compound_Selector* x){ return static_cast<D*>(this)->fallback(x); }
198
- T operator()(Complex_Selector* x) { return static_cast<D*>(this)->fallback(x); }
199
- T operator()(Selector_List* x) { return static_cast<D*>(this)->fallback(x); }
199
+ T operator()(PlaceholderSelector* x) { return static_cast<D*>(this)->fallback(x); }
200
+ T operator()(TypeSelector* x) { return static_cast<D*>(this)->fallback(x); }
201
+ T operator()(ClassSelector* x) { return static_cast<D*>(this)->fallback(x); }
202
+ T operator()(IDSelector* x) { return static_cast<D*>(this)->fallback(x); }
203
+ T operator()(AttributeSelector* x) { return static_cast<D*>(this)->fallback(x); }
204
+ T operator()(PseudoSelector* x) { return static_cast<D*>(this)->fallback(x); }
205
+ T operator()(SelectorComponent* x) { return static_cast<D*>(this)->fallback(x); }
206
+ T operator()(SelectorCombinator* x) { return static_cast<D*>(this)->fallback(x); }
207
+ T operator()(CompoundSelector* x) { return static_cast<D*>(this)->fallback(x); }
208
+ T operator()(ComplexSelector* x) { return static_cast<D*>(this)->fallback(x); }
209
+ T operator()(SelectorList* x) { return static_cast<D*>(this)->fallback(x); }
200
210
 
201
211
  // fallback with specific type U
202
212
  // will be called if not overloaded
203
- template <typename U> T fallback(U x)
213
+ template <typename U> inline T fallback(U x)
204
214
  {
205
215
  throw std::runtime_error(
206
216
  std::string(typeid(*this).name()) + ": CRTP not implemented for " + typeid(x).name());