sassc 2.1.0.pre3 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/CHANGELOG.md +24 -0
  4. data/Rakefile +2 -4
  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.hpp +12 -0
  81. data/ext/libsass/src/memory/allocator.cpp +48 -0
  82. data/ext/libsass/src/memory/allocator.hpp +138 -0
  83. data/ext/libsass/src/memory/config.hpp +20 -0
  84. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  85. data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
  86. data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
  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 +11 -13
  132. data/lib/sassc/native.rb +9 -7
  133. data/lib/sassc/script.rb +4 -6
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/functions_test.rb +38 -1
  136. data/test/native_test.rb +4 -4
  137. metadata +31 -18
  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
@@ -1,14 +1,18 @@
1
1
  #ifndef SASS_CHECK_NESTING_H
2
2
  #define SASS_CHECK_NESTING_H
3
3
 
4
+ // sass.hpp must go before all system headers to get the
5
+ // __EXTENSIONS__ fix on Solaris.
6
+ #include "sass.hpp"
4
7
  #include "ast.hpp"
5
8
  #include "operation.hpp"
9
+ #include <vector>
6
10
 
7
11
  namespace Sass {
8
12
 
9
13
  class CheckNesting : public Operation_CRTP<Statement*, CheckNesting> {
10
14
 
11
- std::vector<Statement*> parents;
15
+ sass::vector<Statement*> parents;
12
16
  Backtraces traces;
13
17
  Statement* parent;
14
18
  Definition* current_mixin_definition;
@@ -29,7 +33,7 @@ namespace Sass {
29
33
  Statement* s = Cast<Statement>(x);
30
34
  if (s && this->should_visit(s)) {
31
35
  Block* b1 = Cast<Block>(s);
32
- Has_Block* b2 = Cast<Has_Block>(s);
36
+ ParentStatement* b2 = Cast<ParentStatement>(s);
33
37
  if (b1 || b2) return visit_children(s);
34
38
  }
35
39
  return s;
@@ -4,6 +4,7 @@
4
4
 
5
5
  #include "ast.hpp"
6
6
  #include "color_maps.hpp"
7
+ #include "util_string.hpp"
7
8
 
8
9
  namespace Sass {
9
10
 
@@ -161,7 +162,7 @@ namespace Sass {
161
162
  }
162
163
 
163
164
  namespace Colors {
164
- const ParserState color_table("[COLOR TABLE]");
165
+ const SourceSpan color_table("[COLOR TABLE]");
165
166
  const Color_RGBA aliceblue(color_table, 240, 248, 255, 1);
166
167
  const Color_RGBA antiquewhite(color_table, 250, 235, 215, 1);
167
168
  const Color_RGBA cyan(color_table, 0, 255, 255, 1);
@@ -313,7 +314,7 @@ namespace Sass {
313
314
  const Color_RGBA transparent(color_table, 0, 0, 0, 0);
314
315
  }
315
316
 
316
- const std::map<const int, const char*> colors_to_names {
317
+ static const auto* const colors_to_names = new std::unordered_map<int, const char*> {
317
318
  { 240 * 0x10000 + 248 * 0x100 + 255, ColorNames::aliceblue },
318
319
  { 250 * 0x10000 + 235 * 0x100 + 215, ColorNames::antiquewhite },
319
320
  { 0 * 0x10000 + 255 * 0x100 + 255, ColorNames::cyan },
@@ -455,7 +456,7 @@ namespace Sass {
455
456
  { 102 * 0x10000 + 51 * 0x100 + 153, ColorNames::rebeccapurple }
456
457
  };
457
458
 
458
- const std::map<const char*, const Color_RGBA*, map_cmp_str> names_to_colors
459
+ static const auto *const names_to_colors = new std::unordered_map<sass::string, const Color_RGBA*>
459
460
  {
460
461
  { ColorNames::aliceblue, &Colors::aliceblue },
461
462
  { ColorNames::antiquewhite, &Colors::antiquewhite },
@@ -610,29 +611,29 @@ namespace Sass {
610
611
 
611
612
  const Color_RGBA* name_to_color(const char* key)
612
613
  {
613
- return name_to_color(std::string(key));
614
+ return name_to_color(sass::string(key));
614
615
  }
615
616
 
616
- const Color_RGBA* name_to_color(const std::string& key)
617
+ const Color_RGBA* name_to_color(const sass::string& key)
617
618
  {
618
619
  // case insensitive lookup. See #2462
619
- std::string lower{key};
620
- std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
620
+ sass::string lower = key;
621
+ Util::ascii_str_tolower(&lower);
621
622
 
622
- auto p = names_to_colors.find(lower.c_str());
623
- if (p != names_to_colors.end()) {
623
+ auto p = names_to_colors->find(lower);
624
+ if (p != names_to_colors->end()) {
624
625
  return p->second;
625
626
  }
626
- return 0;
627
+ return nullptr;
627
628
  }
628
629
 
629
630
  const char* color_to_name(const int key)
630
631
  {
631
- auto p = colors_to_names.find(key);
632
- if (p != colors_to_names.end()) {
632
+ auto p = colors_to_names->find(key);
633
+ if (p != colors_to_names->end()) {
633
634
  return p->second;
634
635
  }
635
- return 0;
636
+ return nullptr;
636
637
  }
637
638
 
638
639
  const char* color_to_name(const double key)
@@ -7,14 +7,6 @@
7
7
 
8
8
  namespace Sass {
9
9
 
10
- struct map_cmp_str
11
- {
12
- bool operator()(char const *a, char const *b) const
13
- {
14
- return std::strcmp(a, b) < 0;
15
- }
16
- };
17
-
18
10
  namespace ColorNames
19
11
  {
20
12
  extern const char aliceblue[];
@@ -321,7 +313,7 @@ namespace Sass {
321
313
  }
322
314
 
323
315
  const Color_RGBA* name_to_color(const char*);
324
- const Color_RGBA* name_to_color(const std::string&);
316
+ const Color_RGBA* name_to_color(const sass::string&);
325
317
  const char* color_to_name(const int);
326
318
  const char* color_to_name(const Color_RGBA&);
327
319
  const char* color_to_name(const double);
@@ -45,6 +45,7 @@ namespace Sass {
45
45
  extern const char for_kwd[] = "@for";
46
46
  extern const char from_kwd[] = "from";
47
47
  extern const char to_kwd[] = "to";
48
+ extern const char of_kwd[] = "of";
48
49
  extern const char through_kwd[] = "through";
49
50
  extern const char each_kwd[] = "@each";
50
51
  extern const char in_kwd[] = "in";
@@ -161,6 +162,10 @@ namespace Sass {
161
162
  extern const char uri_chars[] = ":;/?!%&#@|[]{}'`^\"*+-.,_=~";
162
163
  extern const char real_uri_chars[] = "#%&";
163
164
 
165
+ extern const char selector_combinator_child[] = ">";
166
+ extern const char selector_combinator_general[] = "~";
167
+ extern const char selector_combinator_adjacent[] = "+";
168
+
164
169
  // some specific constant character classes
165
170
  // they must be static to be useable by lexer
166
171
  extern const char static_ops[] = "*/%";
@@ -43,6 +43,7 @@ namespace Sass {
43
43
  extern const char for_kwd[];
44
44
  extern const char from_kwd[];
45
45
  extern const char to_kwd[];
46
+ extern const char of_kwd[];
46
47
  extern const char through_kwd[];
47
48
  extern const char each_kwd[];
48
49
  extern const char in_kwd[];
@@ -161,6 +162,11 @@ namespace Sass {
161
162
  extern const char uri_chars[];
162
163
  extern const char real_uri_chars[];
163
164
 
165
+ // constants for selector combinators
166
+ extern const char selector_combinator_child[];
167
+ extern const char selector_combinator_general[];
168
+ extern const char selector_combinator_adjacent[];
169
+
164
170
  // some specific constant character classes
165
171
  // they must be static to be useable by lexer
166
172
  extern const char static_ops[];
@@ -1,44 +1,23 @@
1
1
  // sass.hpp must go before all system headers to get the
2
2
  // __EXTENSIONS__ fix on Solaris.
3
3
  #include "sass.hpp"
4
-
5
- #include <string>
6
- #include <cstdlib>
7
- #include <cstring>
8
- #include <iomanip>
9
- #include <sstream>
10
- #include <iostream>
11
-
12
4
  #include "ast.hpp"
13
- #include "util.hpp"
14
- #include "sass.h"
15
- #include "context.hpp"
16
- #include "plugins.hpp"
17
- #include "constants.hpp"
18
- #include "parser.hpp"
19
- #include "file.hpp"
20
- #include "inspect.hpp"
21
- #include "output.hpp"
22
- #include "expand.hpp"
23
- #include "eval.hpp"
24
- #include "check_nesting.hpp"
25
- #include "cssize.hpp"
26
- #include "listize.hpp"
27
- #include "extend.hpp"
5
+
28
6
  #include "remove_placeholders.hpp"
29
7
  #include "sass_functions.hpp"
30
- #include "backtrace.hpp"
31
- #include "sass2scss.h"
32
- #include "prelexer.hpp"
33
- #include "emitter.hpp"
34
- #include "fn_utils.hpp"
8
+ #include "check_nesting.hpp"
9
+ #include "fn_selectors.hpp"
10
+ #include "fn_strings.hpp"
11
+ #include "fn_numbers.hpp"
12
+ #include "fn_colors.hpp"
35
13
  #include "fn_miscs.hpp"
36
- #include "fn_maps.hpp"
37
14
  #include "fn_lists.hpp"
38
- #include "fn_colors.hpp"
39
- #include "fn_numbers.hpp"
40
- #include "fn_strings.hpp"
41
- #include "fn_selectors.hpp"
15
+ #include "fn_maps.hpp"
16
+ #include "context.hpp"
17
+ #include "expand.hpp"
18
+ #include "parser.hpp"
19
+ #include "cssize.hpp"
20
+ #include "source.hpp"
42
21
 
43
22
  namespace Sass {
44
23
  using namespace Constants;
@@ -48,25 +27,19 @@ namespace Sass {
48
27
  inline bool sort_importers (const Sass_Importer_Entry& i, const Sass_Importer_Entry& j)
49
28
  { return sass_importer_get_priority(i) > sass_importer_get_priority(j); }
50
29
 
51
- static std::string safe_input(const char* in_path)
30
+ static sass::string safe_input(const char* in_path)
52
31
  {
53
- // enforce some safe defaults
54
- // used to create relative file links
55
- std::string safe_path(in_path ? in_path : "");
56
- return safe_path == "" ? "stdin" : safe_path;
32
+ if (in_path == nullptr || in_path[0] == '\0') return "stdin";
33
+ return in_path;
57
34
  }
58
35
 
59
- static std::string safe_output(const char* out_path, const std::string& input_path = "")
36
+ static sass::string safe_output(const char* out_path, sass::string input_path)
60
37
  {
61
- std::string safe_path(out_path ? out_path : "");
62
- // maybe we can extract an output path from input path
63
- if (safe_path == "" && input_path != "") {
64
- int lastindex = static_cast<int>(input_path.find_last_of("."));
65
- return (lastindex > -1 ? input_path.substr(0, lastindex) : input_path) + ".css";
38
+ if (out_path == nullptr || out_path[0] == '\0') {
39
+ if (input_path.empty()) return "stdout";
40
+ return input_path.substr(0, input_path.find_last_of(".")) + ".css";
66
41
  }
67
- // enforce some safe defaults
68
- // used to create relative file links
69
- return safe_path == "" ? "stdout" : safe_path;
42
+ return out_path;
70
43
  }
71
44
 
72
45
  Context::Context(struct Sass_Context& c_ctx)
@@ -81,15 +54,15 @@ namespace Sass {
81
54
  strings(),
82
55
  resources(),
83
56
  sheets(),
84
- subset_map(),
85
57
  import_stack(),
86
58
  callee_stack(),
87
59
  traces(),
60
+ extender(Extender::NORMAL, traces),
88
61
  c_compiler(NULL),
89
62
 
90
- c_headers (std::vector<Sass_Importer_Entry>()),
91
- c_importers (std::vector<Sass_Importer_Entry>()),
92
- c_functions (std::vector<Sass_Function_Entry>()),
63
+ c_headers (sass::vector<Sass_Importer_Entry>()),
64
+ c_importers (sass::vector<Sass_Importer_Entry>()),
65
+ c_functions (sass::vector<Sass_Function_Entry>()),
93
66
 
94
67
  indent (safe_str(c_options.indent, " ")),
95
68
  linefeed (safe_str(c_options.linefeed, "\n")),
@@ -160,7 +133,7 @@ namespace Sass {
160
133
  }
161
134
  // clear inner structures (vectors) and input source
162
135
  resources.clear(); import_stack.clear();
163
- subset_map.clear(), sheets.clear();
136
+ sheets.clear();
164
137
  }
165
138
 
166
139
  Data_Context::~Data_Context()
@@ -183,7 +156,7 @@ namespace Sass {
183
156
  const char* end = Prelexer::find_first<PATH_SEP>(beg);
184
157
 
185
158
  while (end) {
186
- std::string path(beg, end - beg);
159
+ sass::string path(beg, end - beg);
187
160
  if (!path.empty()) {
188
161
  if (*path.rbegin() != '/') path += '/';
189
162
  include_paths.push_back(path);
@@ -192,7 +165,7 @@ namespace Sass {
192
165
  end = Prelexer::find_first<PATH_SEP>(beg);
193
166
  }
194
167
 
195
- std::string path(beg);
168
+ sass::string path(beg);
196
169
  if (!path.empty()) {
197
170
  if (*path.rbegin() != '/') path += '/';
198
171
  include_paths.push_back(path);
@@ -216,7 +189,7 @@ namespace Sass {
216
189
  const char* end = Prelexer::find_first<PATH_SEP>(beg);
217
190
 
218
191
  while (end) {
219
- std::string path(beg, end - beg);
192
+ sass::string path(beg, end - beg);
220
193
  if (!path.empty()) {
221
194
  if (*path.rbegin() != '/') path += '/';
222
195
  plugin_paths.push_back(path);
@@ -225,7 +198,7 @@ namespace Sass {
225
198
  end = Prelexer::find_first<PATH_SEP>(beg);
226
199
  }
227
200
 
228
- std::string path(beg);
201
+ sass::string path(beg);
229
202
  if (!path.empty()) {
230
203
  if (*path.rbegin() != '/') path += '/';
231
204
  plugin_paths.push_back(path);
@@ -244,17 +217,17 @@ namespace Sass {
244
217
 
245
218
  // resolve the imp_path in base_path or include_paths
246
219
  // looks for alternatives and returns a list from one directory
247
- std::vector<Include> Context::find_includes(const Importer& import)
220
+ sass::vector<Include> Context::find_includes(const Importer& import)
248
221
  {
249
222
  // make sure we resolve against an absolute path
250
- std::string base_path(rel2abs(import.base_path));
223
+ sass::string base_path(rel2abs(import.base_path));
251
224
  // first try to resolve the load path relative to the base path
252
- std::vector<Include> vec(resolve_includes(base_path, import.imp_path));
225
+ sass::vector<Include> vec(resolve_includes(base_path, import.imp_path));
253
226
  // then search in every include path (but only if nothing found yet)
254
227
  for (size_t i = 0, S = include_paths.size(); vec.size() == 0 && i < S; ++i)
255
228
  {
256
229
  // call resolve_includes and individual base path and append all results
257
- std::vector<Include> resolved(resolve_includes(include_paths[i], import.imp_path));
230
+ sass::vector<Include> resolved(resolve_includes(include_paths[i], import.imp_path));
258
231
  if (resolved.size()) vec.insert(vec.end(), resolved.begin(), resolved.end());
259
232
  }
260
233
  // return vector
@@ -301,22 +274,22 @@ namespace Sass {
301
274
 
302
275
  // get pointer to the loaded content
303
276
  const char* contents = resources[idx].contents;
304
- // keep a copy of the path around (for parserstates)
305
- // ToDo: we clean it, but still not very elegant!?
306
- strings.push_back(sass_copy_c_string(inc.abs_path.c_str()));
277
+ SourceFileObj source = SASS_MEMORY_NEW(SourceFile,
278
+ inc.abs_path.c_str(), contents, idx);
279
+
307
280
  // create the initial parser state from resource
308
- ParserState pstate(strings.back(), contents, idx);
281
+ SourceSpan pstate(source);
309
282
 
310
283
  // check existing import stack for possible recursion
311
284
  for (size_t i = 0; i < import_stack.size() - 2; ++i) {
312
285
  auto parent = import_stack[i];
313
286
  if (std::strcmp(parent->abs_path, import->abs_path) == 0) {
314
- std::string cwd(File::get_cwd());
287
+ sass::string cwd(File::get_cwd());
315
288
  // make path relative to the current directory
316
- std::string stack("An @import loop has been found:");
289
+ sass::string stack("An @import loop has been found:");
317
290
  for (size_t n = 1; n < i + 2; ++n) {
318
- stack += "\n " + std::string(File::abs2rel(import_stack[n]->abs_path, cwd, cwd)) +
319
- " imports " + std::string(File::abs2rel(import_stack[n+1]->abs_path, cwd, cwd));
291
+ stack += "\n " + sass::string(File::abs2rel(import_stack[n]->abs_path, cwd, cwd)) +
292
+ " imports " + sass::string(File::abs2rel(import_stack[n+1]->abs_path, cwd, cwd));
320
293
  }
321
294
  // implement error throw directly until we
322
295
  // decided how to handle full stack traces
@@ -326,7 +299,7 @@ namespace Sass {
326
299
  }
327
300
 
328
301
  // create a parser instance from the given c_str buffer
329
- Parser p(Parser::from_c_str(contents, *this, traces, pstate));
302
+ Parser p(source, *this, traces);
330
303
  // do not yet dispose these buffers
331
304
  sass_import_take_source(import);
332
305
  sass_import_take_srcmap(import);
@@ -337,7 +310,7 @@ namespace Sass {
337
310
  // remove current stack frame
338
311
  import_stack.pop_back();
339
312
  // create key/value pair for ast node
340
- std::pair<const std::string, StyleSheet>
313
+ std::pair<const sass::string, StyleSheet>
341
314
  ast_pair(inc.abs_path, { res, root });
342
315
  // register resulting resource
343
316
  sheets.insert(ast_pair);
@@ -345,7 +318,7 @@ namespace Sass {
345
318
 
346
319
  // register include with resolved path and its content
347
320
  // memory of the resources will be freed by us on exit
348
- void Context::register_resource(const Include& inc, const Resource& res, ParserState& prstate)
321
+ void Context::register_resource(const Include& inc, const Resource& res, SourceSpan& prstate)
349
322
  {
350
323
  traces.push_back(Backtrace(prstate));
351
324
  register_resource(inc, res);
@@ -353,16 +326,16 @@ namespace Sass {
353
326
  }
354
327
 
355
328
  // Add a new import to the context (called from `import_url`)
356
- Include Context::load_import(const Importer& imp, ParserState pstate)
329
+ Include Context::load_import(const Importer& imp, SourceSpan pstate)
357
330
  {
358
331
 
359
332
  // search for valid imports (ie. partials) on the filesystem
360
333
  // this may return more than one valid result (ambiguous imp_path)
361
- const std::vector<Include> resolved(find_includes(imp));
334
+ const sass::vector<Include> resolved(find_includes(imp));
362
335
 
363
336
  // error nicely on ambiguous imp_path
364
337
  if (resolved.size() > 1) {
365
- std::stringstream msg_stream;
338
+ sass::ostream msg_stream;
366
339
  msg_stream << "It's not clear which file to import for ";
367
340
  msg_stream << "'@import \"" << imp.imp_path << "\"'." << "\n";
368
341
  msg_stream << "Candidates:" << "\n";
@@ -392,20 +365,20 @@ namespace Sass {
392
365
 
393
366
  }
394
367
 
395
- void Context::import_url (Import* imp, std::string load_path, const std::string& ctx_path) {
368
+ void Context::import_url (Import* imp, sass::string load_path, const sass::string& ctx_path) {
396
369
 
397
- ParserState pstate(imp->pstate());
398
- std::string imp_path(unquote(load_path));
399
- std::string protocol("file");
370
+ SourceSpan pstate(imp->pstate());
371
+ sass::string imp_path(unquote(load_path));
372
+ sass::string protocol("file");
400
373
 
401
374
  using namespace Prelexer;
402
375
  if (const char* proto = sequence< identifier, exactly<':'>, exactly<'/'>, exactly<'/'> >(imp_path.c_str())) {
403
376
 
404
- protocol = std::string(imp_path.c_str(), proto - 3);
377
+ protocol = sass::string(imp_path.c_str(), proto - 3);
405
378
  // if (protocol.compare("file") && true) { }
406
379
  }
407
380
 
408
- // add urls (protocol other than file) and urls without procotol to `urls` member
381
+ // add urls (protocol other than file) and urls without protocol to `urls` member
409
382
  // ToDo: if ctx_path is already a file resource, we should not add it here?
410
383
  if (imp->import_queries() || protocol != "file" || imp_path.substr(0, 2) == "//") {
411
384
  imp->urls().push_back(SASS_MEMORY_NEW(String_Quoted, imp->pstate(), load_path));
@@ -415,7 +388,7 @@ namespace Sass {
415
388
  Argument_Obj loc_arg = SASS_MEMORY_NEW(Argument, pstate, loc);
416
389
  Arguments_Obj loc_args = SASS_MEMORY_NEW(Arguments, pstate);
417
390
  loc_args->append(loc_arg);
418
- Function_Call* new_url = SASS_MEMORY_NEW(Function_Call, pstate, std::string("url"), loc_args);
391
+ Function_Call* new_url = SASS_MEMORY_NEW(Function_Call, pstate, sass::string("url"), loc_args);
419
392
  imp->urls().push_back(new_url);
420
393
  }
421
394
  else {
@@ -431,7 +404,7 @@ namespace Sass {
431
404
 
432
405
 
433
406
  // call custom importers on the given (unquoted) load_path and eventually parse the resulting style_sheet
434
- bool Context::call_loader(const std::string& load_path, const char* ctx_path, ParserState& pstate, Import* imp, std::vector<Sass_Importer_Entry> importers, bool only_one)
407
+ bool Context::call_loader(const sass::string& load_path, const char* ctx_path, SourceSpan& pstate, Import* imp, sass::vector<Sass_Importer_Entry> importers, bool only_one)
435
408
  {
436
409
  // unique counter
437
410
  size_t count = 0;
@@ -449,9 +422,9 @@ namespace Sass {
449
422
  Sass_Import_List it_includes = includes;
450
423
  while (*it_includes) { ++count;
451
424
  // create unique path to use as key
452
- std::string uniq_path = load_path;
425
+ sass::string uniq_path = load_path;
453
426
  if (!only_one && count) {
454
- std::stringstream path_strm;
427
+ sass::ostream path_strm;
455
428
  path_strm << uniq_path << ":" << count;
456
429
  uniq_path = path_strm.str();
457
430
  }
@@ -468,14 +441,14 @@ namespace Sass {
468
441
  // it may (or may not) override the line and column info
469
442
  if (const char* err_message = sass_import_get_error_message(include_ent)) {
470
443
  if (source || srcmap) register_resource({ importer, uniq_path }, { source, srcmap }, pstate);
471
- if (line == std::string::npos && column == std::string::npos) error(err_message, pstate, traces);
472
- else error(err_message, ParserState(ctx_path, source, Position(line, column)), traces);
444
+ if (line == sass::string::npos && column == sass::string::npos) error(err_message, pstate, traces);
445
+ else { error(err_message, { pstate.source, { line, column } }, traces); }
473
446
  }
474
447
  // content for import was set
475
448
  else if (source) {
476
449
  // resolved abs_path should be set by custom importer
477
450
  // use the created uniq_path as fallback (maybe enforce)
478
- std::string path_key(abs_path ? abs_path : uniq_path);
451
+ sass::string path_key(abs_path ? abs_path : uniq_path);
479
452
  // create the importer struct
480
453
  Include include(importer, path_key);
481
454
  // attach information to AST node
@@ -512,7 +485,7 @@ namespace Sass {
512
485
 
513
486
  void register_function(Context&, Signature sig, Native_Function f, Env* env);
514
487
  void register_function(Context&, Signature sig, Native_Function f, size_t arity, Env* env);
515
- void register_overload_stub(Context&, std::string name, Env* env);
488
+ void register_overload_stub(Context&, sass::string name, Env* env);
516
489
  void register_built_in_functions(Context&, Env* env);
517
490
  void register_c_functions(Context&, Env* env, Sass_Function_List);
518
491
  void register_c_function(Context&, Env* env, Sass_Function_Entry);
@@ -529,7 +502,7 @@ namespace Sass {
529
502
  OutputBuffer emitted = emitter.get_buffer();
530
503
  // should we append a source map url?
531
504
  if (!c_options.omit_source_map_url) {
532
- // generate an embeded source map
505
+ // generate an embedded source map
533
506
  if (c_options.source_map_embed) {
534
507
  emitted.buffer += linefeed;
535
508
  emitted.buffer += format_embedded_source_map();
@@ -545,7 +518,7 @@ namespace Sass {
545
518
  return sass_copy_c_string(emitted.buffer.c_str());
546
519
  }
547
520
 
548
- void Context::apply_custom_headers(Block_Obj root, const char* ctx_path, ParserState pstate)
521
+ void Context::apply_custom_headers(Block_Obj root, const char* ctx_path, SourceSpan pstate)
549
522
  {
550
523
  // create a custom import to resolve headers
551
524
  Import_Obj imp = SASS_MEMORY_NEW(Import, pstate);
@@ -570,7 +543,7 @@ namespace Sass {
570
543
 
571
544
  // create absolute path from input filename
572
545
  // ToDo: this should be resolved via custom importers
573
- std::string abs_path(rel2abs(input_path, CWD));
546
+ sass::string abs_path(rel2abs(input_path, CWD));
574
547
 
575
548
  // try to load the entry file
576
549
  char* contents = read_file(abs_path);
@@ -585,7 +558,9 @@ namespace Sass {
585
558
  }
586
559
 
587
560
  // abort early if no content could be loaded (various reasons)
588
- if (!contents) throw std::runtime_error("File to read not found or unreadable: " + input_path);
561
+ if (!contents) throw std::runtime_error(
562
+ "File to read not found or unreadable: "
563
+ + std::string(input_path.c_str()));
589
564
 
590
565
  // store entry path
591
566
  entry_path = abs_path;
@@ -628,7 +603,7 @@ namespace Sass {
628
603
  entry_path = input_path.empty() ? "stdin" : input_path;
629
604
 
630
605
  // ToDo: this may be resolved via custom importers
631
- std::string abs_path(rel2abs(entry_path));
606
+ sass::string abs_path(rel2abs(entry_path));
632
607
  char* abs_path_c_str = sass_copy_c_string(abs_path.c_str());
633
608
  strings.push_back(abs_path_c_str);
634
609
 
@@ -649,8 +624,6 @@ namespace Sass {
649
624
  return compile();
650
625
  }
651
626
 
652
-
653
-
654
627
  // parse root block from includes
655
628
  Block_Obj Context::compile()
656
629
  {
@@ -678,60 +651,60 @@ namespace Sass {
678
651
  }
679
652
  // expand and eval the tree
680
653
  root = expand(root);
654
+
655
+ Extension unsatisfied;
656
+ // check that all extends were used
657
+ if (extender.checkForUnsatisfiedExtends(unsatisfied)) {
658
+ throw Exception::UnsatisfiedExtend(traces, unsatisfied);
659
+ }
660
+
681
661
  // check nesting
682
662
  check_nesting(root);
683
663
  // merge and bubble certain rules
684
664
  root = cssize(root);
685
- // should we extend something?
686
- if (!subset_map.empty()) {
687
- // create crtp visitor object
688
- Extend extend(subset_map);
689
- extend.setEval(expand.eval);
690
- // extend tree nodes
691
- extend(root);
692
- }
693
665
 
694
666
  // clean up by removing empty placeholders
695
667
  // ToDo: maybe we can do this somewhere else?
696
668
  Remove_Placeholders remove_placeholders;
697
669
  root->perform(&remove_placeholders);
670
+
698
671
  // return processed tree
699
672
  return root;
700
673
  }
701
674
  // EO compile
702
675
 
703
- std::string Context::format_embedded_source_map()
676
+ sass::string Context::format_embedded_source_map()
704
677
  {
705
- std::string map = emitter.render_srcmap(*this);
706
- std::istringstream is( map );
707
- std::ostringstream buffer;
678
+ sass::string map = emitter.render_srcmap(*this);
679
+ sass::istream is( map.c_str() );
680
+ sass::ostream buffer;
708
681
  base64::encoder E;
709
682
  E.encode(is, buffer);
710
- std::string url = "data:application/json;base64," + buffer.str();
683
+ sass::string url = "data:application/json;base64," + buffer.str();
711
684
  url.erase(url.size() - 1);
712
685
  return "/*# sourceMappingURL=" + url + " */";
713
686
  }
714
687
 
715
- std::string Context::format_source_mapping_url(const std::string& file)
688
+ sass::string Context::format_source_mapping_url(const sass::string& file)
716
689
  {
717
- std::string url = abs2rel(file, output_path, CWD);
690
+ sass::string url = abs2rel(file, output_path, CWD);
718
691
  return "/*# sourceMappingURL=" + url + " */";
719
692
  }
720
693
 
721
694
  char* Context::render_srcmap()
722
695
  {
723
696
  if (source_map_file == "") return 0;
724
- std::string map = emitter.render_srcmap(*this);
697
+ sass::string map = emitter.render_srcmap(*this);
725
698
  return sass_copy_c_string(map.c_str());
726
699
  }
727
700
 
728
701
 
729
702
  // for data context we want to start after "stdin"
730
703
  // we probably always want to skip the header includes?
731
- std::vector<std::string> Context::get_included_files(bool skip, size_t headers)
704
+ sass::vector<sass::string> Context::get_included_files(bool skip, size_t headers)
732
705
  {
733
706
  // create a copy of the vector for manipulations
734
- std::vector<std::string> includes = included_files;
707
+ sass::vector<sass::string> includes = included_files;
735
708
  if (includes.size() == 0) return includes;
736
709
  if (skip) { includes.erase( includes.begin(), includes.begin() + 1 + headers); }
737
710
  else { includes.erase( includes.begin() + 1, includes.begin() + 1 + headers); }
@@ -750,20 +723,20 @@ namespace Sass {
750
723
  void register_function(Context& ctx, Signature sig, Native_Function f, size_t arity, Env* env)
751
724
  {
752
725
  Definition* def = make_native_function(sig, f, ctx);
753
- std::stringstream ss;
726
+ sass::ostream ss;
754
727
  ss << def->name() << "[f]" << arity;
755
728
  def->environment(env);
756
729
  (*env)[ss.str()] = def;
757
730
  }
758
731
 
759
- void register_overload_stub(Context& ctx, std::string name, Env* env)
732
+ void register_overload_stub(Context& ctx, sass::string name, Env* env)
760
733
  {
761
734
  Definition* stub = SASS_MEMORY_NEW(Definition,
762
- ParserState("[built-in function]"),
763
- 0,
735
+ SourceSpan{ "[built-in function]" },
736
+ nullptr,
764
737
  name,
765
- {},
766
- 0,
738
+ Parameters_Obj{},
739
+ nullptr,
767
740
  true);
768
741
  (*env)[name + "[f]"] = stub;
769
742
  }