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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.md +18 -0
- data/Rakefile +1 -3
- data/ext/extconf.rb +13 -5
- data/ext/libsass/VERSION +1 -1
- data/ext/libsass/include/sass/base.h +2 -1
- data/ext/libsass/include/sass/context.h +4 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +158 -168
- data/ext/libsass/src/ast.hpp +389 -230
- data/ext/libsass/src/ast_def_macros.hpp +18 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
- data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +207 -212
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +594 -1026
- data/ext/libsass/src/ast_selectors.hpp +339 -385
- data/ext/libsass/src/ast_supports.cpp +36 -52
- data/ext/libsass/src/ast_supports.hpp +29 -29
- data/ext/libsass/src/ast_values.cpp +271 -84
- data/ext/libsass/src/ast_values.hpp +116 -107
- data/ext/libsass/src/backtrace.cpp +9 -9
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +2 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +18 -18
- data/ext/libsass/src/bind.hpp +1 -1
- data/ext/libsass/src/c2ast.cpp +3 -3
- data/ext/libsass/src/c2ast.hpp +1 -1
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +40 -41
- data/ext/libsass/src/check_nesting.hpp +6 -2
- data/ext/libsass/src/color_maps.cpp +14 -13
- data/ext/libsass/src/color_maps.hpp +1 -9
- data/ext/libsass/src/constants.cpp +5 -0
- data/ext/libsass/src/constants.hpp +6 -0
- data/ext/libsass/src/context.cpp +92 -119
- data/ext/libsass/src/context.hpp +41 -53
- data/ext/libsass/src/cssize.cpp +66 -149
- data/ext/libsass/src/cssize.hpp +17 -23
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +451 -295
- data/ext/libsass/src/emitter.cpp +15 -16
- data/ext/libsass/src/emitter.hpp +10 -12
- data/ext/libsass/src/environment.cpp +27 -27
- data/ext/libsass/src/environment.hpp +29 -24
- data/ext/libsass/src/error_handling.cpp +62 -41
- data/ext/libsass/src/error_handling.hpp +61 -51
- data/ext/libsass/src/eval.cpp +167 -281
- data/ext/libsass/src/eval.hpp +27 -29
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +275 -222
- data/ext/libsass/src/expand.hpp +36 -16
- data/ext/libsass/src/extender.cpp +1188 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +81 -72
- data/ext/libsass/src/file.hpp +28 -37
- data/ext/libsass/src/fn_colors.cpp +20 -18
- data/ext/libsass/src/fn_lists.cpp +30 -29
- data/ext/libsass/src/fn_maps.cpp +3 -3
- data/ext/libsass/src/fn_miscs.cpp +34 -46
- data/ext/libsass/src/fn_numbers.cpp +20 -13
- data/ext/libsass/src/fn_selectors.cpp +98 -128
- data/ext/libsass/src/fn_strings.cpp +47 -33
- data/ext/libsass/src/fn_utils.cpp +31 -29
- data/ext/libsass/src/fn_utils.hpp +17 -11
- data/ext/libsass/src/inspect.cpp +186 -148
- data/ext/libsass/src/inspect.hpp +31 -29
- data/ext/libsass/src/lexer.cpp +20 -82
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +23 -37
- data/ext/libsass/src/listize.hpp +8 -9
- data/ext/libsass/src/mapping.hpp +1 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
- data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/operation.hpp +71 -61
- data/ext/libsass/src/operators.cpp +19 -18
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +45 -64
- data/ext/libsass/src/output.hpp +6 -6
- data/ext/libsass/src/parser.cpp +512 -700
- data/ext/libsass/src/parser.hpp +89 -97
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +7 -7
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +7 -26
- data/ext/libsass/src/position.hpp +44 -21
- data/ext/libsass/src/prelexer.cpp +6 -6
- data/ext/libsass/src/remove_placeholders.cpp +55 -56
- data/ext/libsass/src/remove_placeholders.hpp +21 -18
- data/ext/libsass/src/sass.cpp +16 -15
- data/ext/libsass/src/sass.hpp +10 -5
- data/ext/libsass/src/sass2scss.cpp +4 -4
- data/ext/libsass/src/sass_context.cpp +91 -122
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +1 -1
- data/ext/libsass/src/sass_values.cpp +8 -11
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +22 -18
- data/ext/libsass/src/source_map.hpp +12 -9
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +2 -2
- data/ext/libsass/src/to_value.hpp +1 -1
- data/ext/libsass/src/units.cpp +24 -22
- data/ext/libsass/src/units.hpp +8 -8
- data/ext/libsass/src/utf8_string.cpp +9 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +48 -50
- data/ext/libsass/src/util.hpp +20 -21
- data/ext/libsass/src/util_string.cpp +111 -61
- data/ext/libsass/src/util_string.hpp +62 -8
- data/ext/libsass/src/values.cpp +12 -12
- data/lib/sassc/engine.rb +5 -3
- data/lib/sassc/functions_handler.rb +8 -8
- data/lib/sassc/native.rb +4 -6
- data/lib/sassc/script.rb +4 -4
- data/lib/sassc/version.rb +1 -1
- data/test/functions_test.rb +18 -1
- data/test/native_test.rb +4 -4
- metadata +29 -15
- data/ext/libsass/src/extend.cpp +0 -2132
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/node.cpp +0 -322
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -152
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -58
- data/ext/libsass/src/subset_map.hpp +0 -76
- 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 "
|
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
|
-
|
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.
|
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(
|
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
|
-
|
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
|
-
|
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
|
-
|
112
|
+
sass::string file;
|
82
113
|
size_t line;
|
83
114
|
bool dbg = false;
|
84
|
-
static
|
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
|
-
|
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
|
220
|
+
operator sass::string() const {
|
176
221
|
if (node) return node->to_string();
|
177
|
-
return "
|
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:
|
@@ -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
|
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
|
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
|
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
|
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()(
|
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()(
|
50
|
-
virtual T operator()(
|
51
|
-
virtual T operator()(
|
52
|
-
virtual T operator()(
|
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()(
|
59
|
-
virtual T operator()(
|
60
|
-
virtual T operator()(
|
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()(
|
64
|
-
virtual T operator()(
|
65
|
-
virtual T operator()(
|
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()(
|
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()(
|
91
|
-
virtual T operator()(
|
92
|
-
virtual T operator()(
|
93
|
-
virtual T operator()(
|
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)
|
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()(
|
108
|
-
virtual T operator()(
|
109
|
-
virtual T operator()(
|
110
|
-
virtual T operator()(
|
111
|
-
virtual T operator()(
|
112
|
-
virtual T operator()(
|
113
|
-
virtual T operator()(
|
114
|
-
virtual T operator()(
|
115
|
-
virtual T operator()(
|
116
|
-
virtual T operator()(
|
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
|
-
//
|
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()(
|
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()(
|
133
|
-
T operator()(
|
134
|
-
T operator()(
|
135
|
-
T operator()(
|
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()(
|
142
|
-
T operator()(
|
143
|
-
T operator()(
|
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()(
|
147
|
-
T operator()(
|
148
|
-
T operator()(
|
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()(
|
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()(
|
174
|
-
T operator()(
|
175
|
-
T operator()(
|
176
|
-
T operator()(
|
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()(
|
191
|
-
T operator()(
|
192
|
-
T operator()(
|
193
|
-
T operator()(
|
194
|
-
T operator()(
|
195
|
-
T operator()(
|
196
|
-
T operator()(
|
197
|
-
T operator()(
|
198
|
-
T operator()(
|
199
|
-
T operator()(
|
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());
|