sassc 1.7.1 → 1.8.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/ext/libsass/.gitignore +10 -6
  4. data/ext/libsass/.travis.yml +4 -1
  5. data/ext/libsass/GNUmakefile.am +88 -0
  6. data/ext/libsass/Makefile +157 -76
  7. data/ext/libsass/Makefile.conf +47 -0
  8. data/ext/libsass/Readme.md +13 -14
  9. data/ext/libsass/appveyor.yml +25 -41
  10. data/ext/libsass/configure.ac +20 -7
  11. data/ext/libsass/contrib/plugin.cpp +1 -1
  12. data/ext/libsass/include/sass.h +15 -0
  13. data/ext/libsass/{sass.h → include/sass/base.h} +17 -9
  14. data/ext/libsass/{sass_context.h → include/sass/context.h} +3 -1
  15. data/ext/libsass/{sass_functions.h → include/sass/functions.h} +4 -4
  16. data/ext/libsass/{sass_interface.h → include/sass/interface.h} +5 -2
  17. data/ext/libsass/{sass_values.h → include/sass/values.h} +15 -1
  18. data/ext/libsass/{sass_version.h → include/sass/version.h} +0 -0
  19. data/ext/libsass/{sass_version.h.in → include/sass/version.h.in} +0 -0
  20. data/ext/libsass/{sass2scss.h → include/sass2scss.h} +6 -7
  21. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +167 -0
  22. data/ext/libsass/script/ci-build-libsass +67 -23
  23. data/ext/libsass/src/GNUmakefile.am +54 -0
  24. data/ext/libsass/src/ast.cpp +2029 -0
  25. data/ext/libsass/{ast.hpp → src/ast.hpp} +832 -660
  26. data/ext/libsass/src/ast_def_macros.hpp +47 -0
  27. data/ext/libsass/src/ast_factory.hpp +93 -0
  28. data/ext/libsass/{ast_fwd_decl.hpp → src/ast_fwd_decl.hpp} +9 -4
  29. data/ext/libsass/{b64 → src/b64}/cencode.h +1 -1
  30. data/ext/libsass/{b64 → src/b64}/encode.h +0 -0
  31. data/ext/libsass/{backtrace.hpp → src/backtrace.hpp} +9 -10
  32. data/ext/libsass/{base64vlq.cpp → src/base64vlq.cpp} +2 -2
  33. data/ext/libsass/{base64vlq.hpp → src/base64vlq.hpp} +1 -2
  34. data/ext/libsass/{bind.cpp → src/bind.cpp} +96 -59
  35. data/ext/libsass/{bind.hpp → src/bind.hpp} +1 -1
  36. data/ext/libsass/src/c99func.c +54 -0
  37. data/ext/libsass/{cencode.c → src/cencode.c} +5 -5
  38. data/ext/libsass/src/color_maps.cpp +643 -0
  39. data/ext/libsass/src/color_maps.hpp +333 -0
  40. data/ext/libsass/{constants.cpp → src/constants.cpp} +10 -1
  41. data/ext/libsass/{constants.hpp → src/constants.hpp} +7 -0
  42. data/ext/libsass/{context.cpp → src/context.cpp} +152 -122
  43. data/ext/libsass/src/context.hpp +150 -0
  44. data/ext/libsass/{cssize.cpp → src/cssize.cpp} +123 -109
  45. data/ext/libsass/{cssize.hpp → src/cssize.hpp} +9 -13
  46. data/ext/libsass/{debug.hpp → src/debug.hpp} +9 -9
  47. data/ext/libsass/src/debugger.hpp +683 -0
  48. data/ext/libsass/{emitter.cpp → src/emitter.cpp} +13 -13
  49. data/ext/libsass/{emitter.hpp → src/emitter.hpp} +10 -11
  50. data/ext/libsass/src/environment.cpp +184 -0
  51. data/ext/libsass/src/environment.hpp +92 -0
  52. data/ext/libsass/src/error_handling.cpp +46 -0
  53. data/ext/libsass/src/error_handling.hpp +34 -0
  54. data/ext/libsass/src/eval.cpp +1462 -0
  55. data/ext/libsass/src/eval.hpp +107 -0
  56. data/ext/libsass/src/expand.cpp +653 -0
  57. data/ext/libsass/{expand.hpp → src/expand.hpp} +17 -16
  58. data/ext/libsass/{extend.cpp → src/extend.cpp} +198 -139
  59. data/ext/libsass/{extend.hpp → src/extend.hpp} +7 -8
  60. data/ext/libsass/{file.cpp → src/file.cpp} +103 -57
  61. data/ext/libsass/{file.hpp → src/file.hpp} +23 -14
  62. data/ext/libsass/{functions.cpp → src/functions.cpp} +642 -333
  63. data/ext/libsass/{functions.hpp → src/functions.hpp} +17 -4
  64. data/ext/libsass/{inspect.cpp → src/inspect.cpp} +147 -260
  65. data/ext/libsass/{inspect.hpp → src/inspect.hpp} +7 -7
  66. data/ext/libsass/{json.cpp → src/json.cpp} +33 -43
  67. data/ext/libsass/{json.hpp → src/json.hpp} +1 -1
  68. data/ext/libsass/{kwd_arg_macros.hpp → src/kwd_arg_macros.hpp} +0 -0
  69. data/ext/libsass/{lexer.cpp → src/lexer.cpp} +28 -0
  70. data/ext/libsass/{lexer.hpp → src/lexer.hpp} +25 -10
  71. data/ext/libsass/{listize.cpp → src/listize.cpp} +17 -13
  72. data/ext/libsass/{listize.hpp → src/listize.hpp} +0 -2
  73. data/ext/libsass/{mapping.hpp → src/mapping.hpp} +0 -0
  74. data/ext/libsass/src/memory_manager.cpp +76 -0
  75. data/ext/libsass/src/memory_manager.hpp +48 -0
  76. data/ext/libsass/{node.cpp → src/node.cpp} +89 -18
  77. data/ext/libsass/{node.hpp → src/node.hpp} +5 -6
  78. data/ext/libsass/{operation.hpp → src/operation.hpp} +18 -12
  79. data/ext/libsass/{output.cpp → src/output.cpp} +47 -55
  80. data/ext/libsass/{output.hpp → src/output.hpp} +5 -4
  81. data/ext/libsass/src/parser.cpp +2529 -0
  82. data/ext/libsass/{parser.hpp → src/parser.hpp} +84 -60
  83. data/ext/libsass/{paths.hpp → src/paths.hpp} +10 -13
  84. data/ext/libsass/{plugins.cpp → src/plugins.cpp} +14 -17
  85. data/ext/libsass/{plugins.hpp → src/plugins.hpp} +10 -11
  86. data/ext/libsass/{position.cpp → src/position.cpp} +5 -6
  87. data/ext/libsass/{position.hpp → src/position.hpp} +19 -22
  88. data/ext/libsass/{prelexer.cpp → src/prelexer.cpp} +401 -53
  89. data/ext/libsass/{prelexer.hpp → src/prelexer.hpp} +50 -10
  90. data/ext/libsass/{remove_placeholders.cpp → src/remove_placeholders.cpp} +12 -16
  91. data/ext/libsass/{remove_placeholders.hpp → src/remove_placeholders.hpp} +1 -7
  92. data/ext/libsass/{sass.cpp → src/sass.cpp} +3 -5
  93. data/ext/libsass/{sass2scss.cpp → src/sass2scss.cpp} +51 -46
  94. data/ext/libsass/{sass_context.cpp → src/sass_context.cpp} +114 -112
  95. data/ext/libsass/{sass_functions.cpp → src/sass_functions.cpp} +11 -18
  96. data/ext/libsass/{sass_interface.cpp → src/sass_interface.cpp} +44 -81
  97. data/ext/libsass/{sass_util.cpp → src/sass_util.cpp} +26 -8
  98. data/ext/libsass/{sass_util.hpp → src/sass_util.hpp} +14 -18
  99. data/ext/libsass/{sass_values.cpp → src/sass_values.cpp} +91 -20
  100. data/ext/libsass/{source_map.cpp → src/source_map.cpp} +13 -13
  101. data/ext/libsass/{source_map.hpp → src/source_map.hpp} +9 -9
  102. data/ext/libsass/{subset_map.hpp → src/subset_map.hpp} +29 -31
  103. data/ext/libsass/{support → src/support}/libsass.pc.in +0 -0
  104. data/ext/libsass/src/to_c.cpp +73 -0
  105. data/ext/libsass/src/to_c.hpp +41 -0
  106. data/ext/libsass/src/to_string.cpp +47 -0
  107. data/ext/libsass/{to_string.hpp → src/to_string.hpp} +9 -7
  108. data/ext/libsass/src/to_value.cpp +109 -0
  109. data/ext/libsass/src/to_value.hpp +50 -0
  110. data/ext/libsass/{units.cpp → src/units.cpp} +56 -51
  111. data/ext/libsass/{units.hpp → src/units.hpp} +8 -9
  112. data/ext/libsass/{utf8.h → src/utf8.h} +0 -0
  113. data/ext/libsass/{utf8 → src/utf8}/checked.h +0 -0
  114. data/ext/libsass/{utf8 → src/utf8}/core.h +12 -12
  115. data/ext/libsass/{utf8 → src/utf8}/unchecked.h +0 -0
  116. data/ext/libsass/{utf8_string.cpp → src/utf8_string.cpp} +0 -0
  117. data/ext/libsass/{utf8_string.hpp → src/utf8_string.hpp} +6 -6
  118. data/ext/libsass/{util.cpp → src/util.cpp} +144 -86
  119. data/ext/libsass/src/util.hpp +59 -0
  120. data/ext/libsass/src/values.cpp +137 -0
  121. data/ext/libsass/src/values.hpp +12 -0
  122. data/ext/libsass/test/test_node.cpp +33 -33
  123. data/ext/libsass/test/test_paths.cpp +5 -6
  124. data/ext/libsass/test/test_selector_difference.cpp +4 -5
  125. data/ext/libsass/test/test_specificity.cpp +4 -5
  126. data/ext/libsass/test/test_subset_map.cpp +91 -91
  127. data/ext/libsass/test/test_superselector.cpp +11 -11
  128. data/ext/libsass/test/test_unification.cpp +4 -4
  129. data/ext/libsass/win/libsass.targets +101 -0
  130. data/ext/libsass/win/libsass.vcxproj +45 -127
  131. data/ext/libsass/win/libsass.vcxproj.filters +303 -0
  132. data/lib/sassc/import_handler.rb +1 -1
  133. data/lib/sassc/native/native_functions_api.rb +3 -3
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/custom_importer_test.rb +1 -4
  136. data/test/functions_test.rb +3 -2
  137. data/test/native_test.rb +4 -3
  138. metadata +117 -110
  139. data/ext/libsass/Makefile.am +0 -146
  140. data/ext/libsass/ast.cpp +0 -945
  141. data/ext/libsass/ast_def_macros.hpp +0 -21
  142. data/ext/libsass/ast_factory.hpp +0 -92
  143. data/ext/libsass/color_names.hpp +0 -327
  144. data/ext/libsass/context.hpp +0 -157
  145. data/ext/libsass/contextualize.cpp +0 -148
  146. data/ext/libsass/contextualize.hpp +0 -46
  147. data/ext/libsass/contextualize_eval.cpp +0 -93
  148. data/ext/libsass/contextualize_eval.hpp +0 -44
  149. data/ext/libsass/debugger.hpp +0 -558
  150. data/ext/libsass/environment.hpp +0 -163
  151. data/ext/libsass/error_handling.cpp +0 -35
  152. data/ext/libsass/error_handling.hpp +0 -32
  153. data/ext/libsass/eval.cpp +0 -1392
  154. data/ext/libsass/eval.hpp +0 -88
  155. data/ext/libsass/expand.cpp +0 -575
  156. data/ext/libsass/memory_manager.hpp +0 -57
  157. data/ext/libsass/parser.cpp +0 -2403
  158. data/ext/libsass/posix/getopt.c +0 -562
  159. data/ext/libsass/posix/getopt.h +0 -95
  160. data/ext/libsass/to_c.cpp +0 -61
  161. data/ext/libsass/to_c.hpp +0 -44
  162. data/ext/libsass/to_string.cpp +0 -34
  163. data/ext/libsass/util.hpp +0 -54
  164. data/ext/libsass/win/libsass.filters +0 -312
@@ -1,43 +1,44 @@
1
1
  #ifndef SASS_EXPAND_H
2
2
  #define SASS_EXPAND_H
3
3
 
4
- #include <map>
5
4
  #include <vector>
6
- #include <iostream>
7
5
 
8
6
  #include "ast.hpp"
9
7
  #include "eval.hpp"
10
8
  #include "operation.hpp"
11
9
  #include "environment.hpp"
12
- #include "contextualize.hpp"
13
10
 
14
11
  namespace Sass {
15
- using namespace std;
16
12
 
13
+ class Listize;
17
14
  class Context;
18
15
  class Eval;
19
- class Contextualize_Eval;
20
16
  typedef Environment<AST_Node*> Env;
21
17
  struct Backtrace;
22
18
 
23
19
  class Expand : public Operation_CRTP<Statement*, Expand> {
20
+ public:
21
+
22
+ Env* environment();
23
+ Context& context();
24
+ Selector_List* selector();
25
+ Backtrace* backtrace();
24
26
 
25
27
  Context& ctx;
26
- Eval* eval;
27
- Contextualize_Eval* contextualize_eval;
28
- Env* env;
29
- vector<Block*> block_stack;
30
- vector<String*> property_stack;
31
- vector<Selector*> selector_stack;
32
- vector<Selector*> at_root_selector_stack;
33
- bool in_at_root;
28
+ Eval eval;
29
+
30
+ // it's easier to work with vectors
31
+ std::vector<Env*> env_stack;
32
+ std::vector<Block*> block_stack;
33
+ std::vector<String*> property_stack;
34
+ std::vector<Selector_List*> selector_stack;
35
+ std::vector<Backtrace*>backtrace_stack;
34
36
  bool in_keyframes;
35
- Backtrace* backtrace;
36
37
 
37
38
  Statement* fallback_impl(AST_Node* n);
38
39
 
39
40
  public:
40
- Expand(Context&, Eval*, Contextualize_Eval*, Env*, Backtrace*);
41
+ Expand(Context&, Env*, Backtrace*);
41
42
  virtual ~Expand() { }
42
43
 
43
44
  using Operation<Statement*>::operator();
@@ -46,7 +47,7 @@ namespace Sass {
46
47
  Statement* operator()(Ruleset*);
47
48
  Statement* operator()(Propset*);
48
49
  Statement* operator()(Media_Block*);
49
- Statement* operator()(Feature_Block*);
50
+ Statement* operator()(Supports_Block*);
50
51
  Statement* operator()(At_Root_Block*);
51
52
  Statement* operator()(At_Rule*);
52
53
  Statement* operator()(Declaration*);
@@ -1,6 +1,9 @@
1
+ #ifdef _MSC_VER
2
+ #pragma warning(disable : 4503)
3
+ #endif
4
+
1
5
  #include "extend.hpp"
2
6
  #include "context.hpp"
3
- #include "contextualize.hpp"
4
7
  #include "to_string.hpp"
5
8
  #include "backtrace.hpp"
6
9
  #include "paths.hpp"
@@ -10,6 +13,8 @@
10
13
  #include "debug.hpp"
11
14
  #include <iostream>
12
15
  #include <deque>
16
+ #include <set>
17
+
13
18
 
14
19
  /*
15
20
  NOTES:
@@ -45,7 +50,7 @@
45
50
 
46
51
  - wrap the contents of the print functions in DEBUG preprocesser conditionals so they will be optimized away in non-debug mode.
47
52
 
48
- - consider making the extend* functions member functions to avoid passing around ctx and subsetMap map around. This has the
53
+ - consider making the extend* functions member functions to avoid passing around ctx and subset_map map around. This has the
49
54
  drawback that the implementation details of the operator are then exposed to the outside world, which is not ideal and
50
55
  can cause additional compile time dependencies.
51
56
 
@@ -60,54 +65,85 @@
60
65
  namespace Sass {
61
66
 
62
67
 
63
- typedef pair<Complex_Selector*, Compound_Selector*> ExtensionPair;
64
- typedef vector<ExtensionPair> SubsetMapEntries;
65
-
66
-
68
+ typedef std::pair<Complex_Selector*, Compound_Selector*> ExtensionPair;
69
+ typedef std::vector<ExtensionPair> SubsetMapEntries;
67
70
 
68
71
  #ifdef DEBUG
69
72
 
70
73
  // TODO: move the ast specific ostream operators into ast.hpp/ast.cpp
71
- ostream& operator<<(ostream& os, const Complex_Selector::Combinator combinator) {
74
+ std::ostream& operator<<(std::ostream& os, const Complex_Selector::Combinator combinator) {
72
75
  switch (combinator) {
73
76
  case Complex_Selector::ANCESTOR_OF: os << "\" \""; break;
74
77
  case Complex_Selector::PARENT_OF: os << "\">\""; break;
75
78
  case Complex_Selector::PRECEDES: os << "\"~\""; break;
76
79
  case Complex_Selector::ADJACENT_TO: os << "\"+\""; break;
80
+ case Complex_Selector::REFERENCE: os << "\"/\""; break;
77
81
  }
78
82
 
79
83
  return os;
80
84
  }
81
85
 
82
86
 
83
- ostream& operator<<(ostream& os, Compound_Selector& compoundSelector) {
87
+ std::ostream& operator<<(std::ostream& os, Compound_Selector& compoundSelector) {
88
+ To_String to_string;
89
+ for (size_t i = 0, L = compoundSelector.length(); i < L; ++i) {
90
+ if (i > 0) os << ", ";
91
+ os << compoundSelector[i]->perform(&to_string);
92
+ }
93
+ return os;
94
+ }
95
+
96
+ std::ostream& operator<<(std::ostream& os, Simple_Selector& simpleSelector) {
84
97
  To_String to_string;
85
- os << compoundSelector.perform(&to_string);
98
+ os << simpleSelector.perform(&to_string);
86
99
  return os;
87
100
  }
88
101
 
102
+ // Print a string representation of a Compound_Selector
103
+ static void printSimpleSelector(Simple_Selector* pSimpleSelector, const char* message=NULL, bool newline=true) {
104
+ To_String to_string;
105
+
106
+ if (message) {
107
+ std::cerr << message;
108
+ }
109
+
110
+ if (pSimpleSelector) {
111
+ std::cerr << "[" << *pSimpleSelector << "]";
112
+ } else {
113
+ std::cerr << "NULL";
114
+ }
115
+
116
+ if (newline) {
117
+ std::cerr << std::endl;
118
+ }
119
+ }
120
+
121
+ // Print a string representation of a Compound_Selector
122
+ typedef std::pair<Compound_Selector*, Complex_Selector*> SelsNewSeqPair;
123
+ typedef std::vector<SelsNewSeqPair> SelsNewSeqPairCollection;
124
+
89
125
 
90
126
  // Print a string representation of a Compound_Selector
91
127
  static void printCompoundSelector(Compound_Selector* pCompoundSelector, const char* message=NULL, bool newline=true) {
92
128
  To_String to_string;
93
129
 
94
130
  if (message) {
95
- cerr << message;
131
+ std::cerr << message;
96
132
  }
97
133
 
98
134
  if (pCompoundSelector) {
99
- cerr << *pCompoundSelector;
135
+ std::cerr << "[" << *pCompoundSelector << "]";
100
136
  } else {
101
- cerr << "NULL";
137
+ std::cerr << "NULL";
102
138
  }
103
139
 
104
140
  if (newline) {
105
- cerr << endl;
141
+ std::cerr << std::endl;
106
142
  }
107
143
  }
108
144
 
109
145
 
110
- ostream& operator<<(ostream& os, Complex_Selector& complexSelector) {
146
+ std::ostream& operator<<(std::ostream& os, Complex_Selector& complexSelector) {
111
147
  To_String to_string;
112
148
 
113
149
  os << "[";
@@ -146,36 +182,62 @@ namespace Sass {
146
182
  To_String to_string;
147
183
 
148
184
  if (message) {
149
- cerr << message;
185
+ std::cerr << message;
150
186
  }
151
187
 
152
188
  if (pComplexSelector) {
153
- cerr << *pComplexSelector;
189
+ std::cerr << *pComplexSelector;
154
190
  } else {
155
- cerr << "NULL";
191
+ std::cerr << "NULL";
156
192
  }
157
193
 
158
194
  if (newline) {
159
- cerr << endl;
195
+ std::cerr << std::endl;
160
196
  }
161
197
  }
162
198
 
199
+ static void printSelsNewSeqPairCollection(SelsNewSeqPairCollection& collection, const char* message=NULL, bool newline=true) {
200
+ To_String to_string;
201
+
202
+ if (message) {
203
+ std::cerr << message;
204
+ }
205
+ bool first = true;
206
+ std::cerr << "[";
207
+ for(SelsNewSeqPair& pair : collection) {
208
+ if (first) {
209
+ first = false;
210
+ } else {
211
+ std::cerr << ", ";
212
+ }
213
+ std::cerr << "[";
214
+ Compound_Selector* pSels = pair.first;
215
+ Complex_Selector* pNewSelector = pair.second;
216
+ std::cerr << "[" << *pSels << "], ";
217
+ printComplexSelector(pNewSelector, NULL, false);
218
+ }
219
+ std::cerr << "]";
220
+
221
+ if (newline) {
222
+ std::cerr << std::endl;
223
+ }
224
+ }
163
225
 
164
226
  // Print a string representation of a SourcesSet
165
227
  static void printSourcesSet(SourcesSet& sources, Context& ctx, const char* message=NULL, bool newline=true) {
166
228
  To_String to_string;
167
229
 
168
230
  if (message) {
169
- cerr << message;
231
+ std::cerr << message;
170
232
  }
171
233
 
172
234
  // Convert to a deque of strings so we can sort since order doesn't matter in a set. This should cut down on
173
235
  // the differences we see when debug printing.
174
- typedef deque<string> SourceStrings;
236
+ typedef std::deque<std::string> SourceStrings;
175
237
  SourceStrings sourceStrings;
176
238
  for (SourcesSet::iterator iterator = sources.begin(), iteratorEnd = sources.end(); iterator != iteratorEnd; ++iterator) {
177
239
  Complex_Selector* pSource = *iterator;
178
- stringstream sstream;
240
+ std::stringstream sstream;
179
241
  sstream << complexSelectorToNode(pSource, ctx);
180
242
  sourceStrings.push_back(sstream.str());
181
243
  }
@@ -183,23 +245,23 @@ namespace Sass {
183
245
  // Sort to get consistent output
184
246
  std::sort(sourceStrings.begin(), sourceStrings.end());
185
247
 
186
- cerr << "SourcesSet[";
248
+ std::cerr << "SourcesSet[";
187
249
  for (SourceStrings::iterator iterator = sourceStrings.begin(), iteratorEnd = sourceStrings.end(); iterator != iteratorEnd; ++iterator) {
188
- string source = *iterator;
250
+ std::string source = *iterator;
189
251
  if (iterator != sourceStrings.begin()) {
190
- cerr << ", ";
252
+ std::cerr << ", ";
191
253
  }
192
- cerr << source;
254
+ std::cerr << source;
193
255
  }
194
- cerr << "]";
256
+ std::cerr << "]";
195
257
 
196
258
  if (newline) {
197
- cerr << endl;
259
+ std::cerr << std::endl;
198
260
  }
199
261
  }
200
262
 
201
263
 
202
- ostream& operator<<(ostream& os, SubsetMapEntries& entries) {
264
+ std::ostream& operator<<(std::ostream& os, SubsetMapEntries& entries) {
203
265
  os << "SUBSET_MAP_ENTRIES[";
204
266
 
205
267
  for (SubsetMapEntries::iterator iterator = entries.begin(), endIterator = entries.end(); iterator != endIterator; ++iterator) {
@@ -213,17 +275,17 @@ namespace Sass {
213
275
  os << "(";
214
276
 
215
277
  if (pExtComplexSelector) {
216
- cerr << *pExtComplexSelector;
278
+ std::cerr << *pExtComplexSelector;
217
279
  } else {
218
- cerr << "NULL";
280
+ std::cerr << "NULL";
219
281
  }
220
282
 
221
283
  os << " -> ";
222
284
 
223
285
  if (pExtCompoundSelector) {
224
- cerr << *pExtCompoundSelector;
286
+ std::cerr << *pExtCompoundSelector;
225
287
  } else {
226
- cerr << "NULL";
288
+ std::cerr << "NULL";
227
289
  }
228
290
 
229
291
  os << ")";
@@ -360,7 +422,7 @@ namespace Sass {
360
422
  //DEBUG_PRINTLN(LCS, "LCSTABLE: X=" << x << " Y=" << y)
361
423
  // TODO: make printComplexSelectorDeque and use DEBUG_EXEC AND DEBUG_PRINTLN HERE to get equivalent output
362
424
 
363
- LCSTable c(x.size(), vector<int>(y.size()));
425
+ LCSTable c(x.size(), std::vector<int>(y.size()));
364
426
 
365
427
  // These shouldn't be necessary since the vector will be initialized to 0 already.
366
428
  // x.size.times {|i| c[i][0] = 0}
@@ -373,7 +435,7 @@ namespace Sass {
373
435
  if (comparator(x[i], y[j], pCompareOut)) {
374
436
  c[i][j] = c[i - 1][j - 1] + 1;
375
437
  } else {
376
- c[i][j] = max(c[i][j - 1], c[i - 1][j]);
438
+ c[i][j] = std::max(c[i][j - 1], c[i - 1][j]);
377
439
  }
378
440
  }
379
441
  }
@@ -475,7 +537,7 @@ namespace Sass {
475
537
  /*
476
538
  - IMPROVEMENT: We could probably work directly in the output trimmed deque.
477
539
  */
478
- static Node trim(Node& seqses, Context& ctx) {
540
+ static Node trim(Node& seqses, Context& ctx, bool isReplace) {
479
541
  // See the comments in the above ruby code before embarking on understanding this function.
480
542
 
481
543
  // Avoid poor performance in extreme cases.
@@ -503,6 +565,7 @@ namespace Sass {
503
565
  DEBUG_PRINTLN(TRIM, "SEQS1: " << seqs1 << " " << toTrimIndex)
504
566
 
505
567
  Node tempResult = Node::createCollection();
568
+ tempResult.got_line_feed = seqs1.got_line_feed;
506
569
 
507
570
  for (NodeDeque::iterator seqs1Iter = seqs1.collection()->begin(), seqs1EndIter = seqs1.collection()->end(); seqs1Iter != seqs1EndIter; ++seqs1Iter) {
508
571
  Node& seq1 = *seqs1Iter;
@@ -517,15 +580,15 @@ namespace Sass {
517
580
  // had an extra source that the ruby version did not have. Without a failing test case, this is going to be extra hard to find. My
518
581
  // best guess at this point is that we're cloning an object somewhere and maintaining the sources when we shouldn't be. This is purely
519
582
  // a guess though.
520
- unsigned long maxSpecificity = 0;
583
+ unsigned long maxSpecificity = isReplace ? pSeq1->specificity() : 0;
521
584
  SourcesSet sources = pSeq1->sources();
522
585
 
523
- DEBUG_PRINTLN(TRIM, "TRIMASDF SEQ1: " << seq1)
524
- DEBUG_EXEC(TRIM, printSourcesSet(sources, ctx, "TRIMASDF SOURCES: "))
586
+ DEBUG_PRINTLN(TRIM, "TRIM SEQ1: " << seq1)
587
+ DEBUG_EXEC(TRIM, printSourcesSet(sources, ctx, "TRIM SOURCES: "))
525
588
 
526
589
  for (SourcesSet::iterator sourcesSetIterator = sources.begin(), sourcesSetIteratorEnd = sources.end(); sourcesSetIterator != sourcesSetIteratorEnd; ++sourcesSetIterator) {
527
590
  const Complex_Selector* const pCurrentSelector = *sourcesSetIterator;
528
- maxSpecificity = max(maxSpecificity, pCurrentSelector->specificity());
591
+ maxSpecificity = std::max(maxSpecificity, pCurrentSelector->specificity());
529
592
  }
530
593
 
531
594
  DEBUG_PRINTLN(TRIM, "MAX SPECIFICITY: " << maxSpecificity)
@@ -624,6 +687,7 @@ namespace Sass {
624
687
 
625
688
  bool operator()(const Node& seq) const {
626
689
  // {|s| parent_superselector?(s.first, lcs.first)}
690
+ if (seq.collection()->size() == 0) return false;
627
691
  return parentSuperselector(seq.collection()->front(), mLcs.collection()->front(), mCtx);
628
692
  }
629
693
  };
@@ -672,7 +736,7 @@ namespace Sass {
672
736
  template<typename ChunkerType>
673
737
  static Node chunks(Node& seq1, Node& seq2, const ChunkerType& chunker) {
674
738
  Node chunk1 = Node::createCollection();
675
- while (!chunker(seq1)) {
739
+ while (seq1.collection()->size() && !chunker(seq1)) {
676
740
  chunk1.collection()->push_back(seq1.collection()->front());
677
741
  seq1.collection()->pop_front();
678
742
  }
@@ -1026,8 +1090,8 @@ namespace Sass {
1026
1090
  res.collection()->push_front(op2);
1027
1091
  res.collection()->push_front(sel2);
1028
1092
 
1029
- seq2.collection()->push_back(sel1);
1030
- seq2.collection()->push_back(op1);
1093
+ seq1.collection()->push_back(sel1);
1094
+ seq1.collection()->push_back(op1);
1031
1095
 
1032
1096
  } else if (op2.combinator() == Complex_Selector::PARENT_OF && (op1.combinator() == Complex_Selector::PRECEDES || op1.combinator() == Complex_Selector::ADJACENT_TO)) {
1033
1097
 
@@ -1134,7 +1198,7 @@ namespace Sass {
1134
1198
  result
1135
1199
  end
1136
1200
  */
1137
- static Node subweave(Node& one, Node& two, Context& ctx) {
1201
+ Node Extend::subweave(Node& one, Node& two, Context& ctx) {
1138
1202
  // Check for the simple cases
1139
1203
  if (one.collection()->size() == 0) {
1140
1204
  Node out = Node::createCollection();
@@ -1232,8 +1296,8 @@ namespace Sass {
1232
1296
  seqLcs.collection()->pop_front();
1233
1297
  diff.collection()->push_back(lcsWrapper);
1234
1298
 
1235
- groupSeq1.collection()->pop_front();
1236
- groupSeq2.collection()->pop_front();
1299
+ if (groupSeq1.collection()->size()) groupSeq1.collection()->pop_front();
1300
+ if (groupSeq2.collection()->size()) groupSeq2.collection()->pop_front();
1237
1301
  }
1238
1302
 
1239
1303
  DEBUG_PRINTLN(SUBWEAVE, "DIFF POST LCS: " << diff)
@@ -1423,7 +1487,7 @@ namespace Sass {
1423
1487
  for (NodeDeque::iterator beforesIter = befores.collection()->begin(), beforesEndIter = befores.collection()->end(); beforesIter != beforesEndIter; beforesIter++) {
1424
1488
  Node& before = *beforesIter;
1425
1489
 
1426
- Node sub = subweave(before, current, ctx);
1490
+ Node sub = Extend::subweave(before, current, ctx);
1427
1491
 
1428
1492
  DEBUG_PRINTLN(WEAVE, "SUB: " << sub)
1429
1493
 
@@ -1457,8 +1521,8 @@ namespace Sass {
1457
1521
  static Node extendComplexSelector(
1458
1522
  Complex_Selector* pComplexSelector,
1459
1523
  Context& ctx,
1460
- ExtensionSubsetMap& subsetMap,
1461
- set<Compound_Selector> seen);
1524
+ ExtensionSubsetMap& subset_map,
1525
+ std::set<Compound_Selector> seen, bool isReplace, bool isOriginal);
1462
1526
 
1463
1527
 
1464
1528
 
@@ -1485,43 +1549,43 @@ namespace Sass {
1485
1549
  static Node extendCompoundSelector(
1486
1550
  Compound_Selector* pSelector,
1487
1551
  Context& ctx,
1488
- ExtensionSubsetMap& subsetMap,
1489
- set<Compound_Selector> seen) {
1552
+ ExtensionSubsetMap& subset_map,
1553
+ std::set<Compound_Selector> seen, bool isReplace) {
1490
1554
 
1491
1555
  DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSelector, "EXTEND COMPOUND: "))
1556
+ // TODO: Ruby has another loop here to skip certain members?
1492
1557
 
1493
1558
  Node extendedSelectors = Node::createCollection();
1559
+ // extendedSelectors.got_line_feed = true;
1494
1560
 
1495
1561
  To_String to_string;
1496
1562
 
1497
- SubsetMapEntries entries = subsetMap.get_v(pSelector->to_str_vec());
1498
-
1563
+ SubsetMapEntries entries = subset_map.get_v(pSelector->to_str_vec());
1499
1564
 
1500
- typedef vector<pair<Complex_Selector, vector<ExtensionPair> > > GroupedByToAResult;
1565
+ typedef std::vector<std::pair<Complex_Selector, std::vector<ExtensionPair> > > GroupedByToAResult;
1501
1566
 
1502
1567
  GroupByToAFunctor<Complex_Selector> extPairKeyFunctor;
1503
1568
  GroupedByToAResult arr;
1504
1569
  group_by_to_a(entries, extPairKeyFunctor, arr);
1505
1570
 
1506
-
1507
- typedef pair<Compound_Selector*, Complex_Selector*> SelsNewSeqPair;
1508
- typedef vector<SelsNewSeqPair> SelsNewSeqPairCollection;
1571
+ typedef std::pair<Compound_Selector*, Complex_Selector*> SelsNewSeqPair;
1572
+ typedef std::vector<SelsNewSeqPair> SelsNewSeqPairCollection;
1509
1573
 
1510
1574
 
1511
1575
  SelsNewSeqPairCollection holder;
1512
1576
 
1513
1577
 
1514
1578
  for (GroupedByToAResult::iterator groupedIter = arr.begin(), groupedIterEnd = arr.end(); groupedIter != groupedIterEnd; groupedIter++) {
1515
- pair<Complex_Selector, vector<ExtensionPair> >& groupedPair = *groupedIter;
1579
+ std::pair<Complex_Selector, std::vector<ExtensionPair> >& groupedPair = *groupedIter;
1516
1580
 
1517
1581
  Complex_Selector& seq = groupedPair.first;
1518
- vector<ExtensionPair>& group = groupedPair.second;
1582
+ std::vector<ExtensionPair>& group = groupedPair.second;
1519
1583
 
1520
- // DEBUG_EXEC(EXTEND_COMPOUND, printComplexSelector(&seq, "SEQ: "))
1584
+ DEBUG_EXEC(EXTEND_COMPOUND, printComplexSelector(&seq, "SEQ: "))
1521
1585
 
1522
1586
 
1523
- Compound_Selector* pSels = new (ctx.mem) Compound_Selector(pSelector->pstate());
1524
- for (vector<ExtensionPair>::iterator groupIter = group.begin(), groupIterEnd = group.end(); groupIter != groupIterEnd; groupIter++) {
1587
+ Compound_Selector* pSels = SASS_MEMORY_NEW(ctx.mem, Compound_Selector, pSelector->pstate());
1588
+ for (std::vector<ExtensionPair>::iterator groupIter = group.begin(), groupIterEnd = group.end(); groupIter != groupIterEnd; groupIter++) {
1525
1589
  ExtensionPair& pair = *groupIter;
1526
1590
  Compound_Selector* pCompound = pair.second;
1527
1591
  for (size_t index = 0; index < pCompound->length(); index++) {
@@ -1530,55 +1594,48 @@ namespace Sass {
1530
1594
  }
1531
1595
  }
1532
1596
 
1533
-
1534
-
1535
- // DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSels, "SELS: "))
1536
-
1597
+ DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSels, "SELS: "))
1537
1598
 
1538
1599
  Complex_Selector* pExtComplexSelector = &seq; // The selector up to where the @extend is (ie, the thing to merge)
1539
1600
  Compound_Selector* pExtCompoundSelector = pSels; // All the simple selectors to be replaced from the current compound selector from all extensions
1540
1601
 
1541
-
1542
-
1543
1602
  // TODO: This can return a Compound_Selector with no elements. Should that just be returning NULL?
1603
+ // RUBY: self_without_sel = Sass::Util.array_minus(members, sels)
1544
1604
  Compound_Selector* pSelectorWithoutExtendSelectors = pSelector->minus(pExtCompoundSelector, ctx);
1545
1605
 
1606
+ DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSelector, "MEMBERS: "))
1607
+ DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSelectorWithoutExtendSelectors, "SELF_WO_SEL: "))
1546
1608
 
1547
- // DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSelector, "MEMBERS: "))
1548
- // DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSelectorWithoutExtendSelectors, "SELF_WO_SEL: "))
1549
-
1550
-
1551
- Compound_Selector* pInnermostCompoundSelector = pExtComplexSelector->base();
1609
+ Compound_Selector* pInnermostCompoundSelector = pExtComplexSelector->last()->head();
1552
1610
  Compound_Selector* pUnifiedSelector = NULL;
1553
1611
 
1554
1612
  if (!pInnermostCompoundSelector) {
1555
- pInnermostCompoundSelector = new (ctx.mem) Compound_Selector(pSelector->pstate());
1613
+ pInnermostCompoundSelector = SASS_MEMORY_NEW(ctx.mem, Compound_Selector, pSelector->pstate());
1556
1614
  }
1557
1615
 
1558
1616
  pUnifiedSelector = pInnermostCompoundSelector->unify_with(pSelectorWithoutExtendSelectors, ctx);
1559
1617
 
1560
- // DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pInnermostCompoundSelector, "LHS: "))
1561
- // DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSelectorWithoutExtendSelectors, "RHS: "))
1562
- // DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pUnifiedSelector, "UNIFIED: "))
1563
1618
 
1619
+ DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pInnermostCompoundSelector, "LHS: "))
1620
+ DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSelectorWithoutExtendSelectors, "RHS: "))
1621
+ DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pUnifiedSelector, "UNIFIED: "))
1622
+
1623
+ // RUBY: next unless unified
1564
1624
  if (!pUnifiedSelector || pUnifiedSelector->length() == 0) {
1565
1625
  continue;
1566
1626
  }
1567
1627
 
1568
-
1569
-
1570
1628
  // TODO: implement the parent directive match (if necessary based on test failures)
1571
1629
  // next if group.map {|e, _| check_directives_match!(e, parent_directives)}.none?
1572
1630
 
1573
-
1574
-
1575
-
1576
1631
  // TODO: This seems a little fishy to me. See if it causes any problems. From the ruby, we should be able to just
1577
1632
  // get rid of the last Compound_Selector and replace it with this one. I think the reason this code is more
1578
1633
  // complex is that Complex_Selector contains a combinator, but in ruby combinators have already been filtered
1579
1634
  // out and aren't operated on.
1580
- Complex_Selector* pNewSelector = pExtComplexSelector->cloneFully(ctx);
1581
- Complex_Selector* pNewInnerMost = new (ctx.mem) Complex_Selector(pSelector->pstate(), Complex_Selector::ANCESTOR_OF, pUnifiedSelector, NULL);
1635
+ Complex_Selector* pNewSelector = pExtComplexSelector->cloneFully(ctx); // ->first();
1636
+
1637
+ Complex_Selector* pNewInnerMost = SASS_MEMORY_NEW(ctx.mem, Complex_Selector, pSelector->pstate(), Complex_Selector::ANCESTOR_OF, pUnifiedSelector, NULL);
1638
+
1582
1639
  Complex_Selector::Combinator combinator = pNewSelector->clear_innermost();
1583
1640
  pNewSelector->set_innermost(pNewInnerMost, combinator);
1584
1641
 
@@ -1595,8 +1652,7 @@ namespace Sass {
1595
1652
  #endif
1596
1653
 
1597
1654
 
1598
- if (pSelector && pSelector->has_line_feed()) pNewSelector->has_line_feed(true);
1599
-
1655
+ // if (pSelector && pSelector->has_line_feed()) pNewInnerMost->has_line_feed(true);
1600
1656
  // Set the sources on our new Complex_Selector to the sources of this simple sequence plus the thing we're extending.
1601
1657
  DEBUG_PRINTLN(EXTEND_COMPOUND, "SOURCES SETTING ON NEW SEQ: " << complexSelectorToNode(pNewSelector, ctx))
1602
1658
 
@@ -1608,14 +1664,16 @@ namespace Sass {
1608
1664
  newSourcesSet.insert(pExtComplexSelector);
1609
1665
  DEBUG_EXEC(EXTEND_COMPOUND, printSourcesSet(newSourcesSet, ctx, "SOURCES WITH NEW SOURCE: "))
1610
1666
 
1667
+ // RUBY: new_seq.add_sources!(sources + [seq])
1611
1668
  pNewSelector->addSources(newSourcesSet, ctx);
1612
1669
 
1613
1670
  DEBUG_EXEC(EXTEND_COMPOUND, SourcesSet newSet = pNewSelector->sources(); printSourcesSet(newSet, ctx, "SOURCES ON NEW SELECTOR AFTER ADD: "))
1614
1671
  DEBUG_EXEC(EXTEND_COMPOUND, printSourcesSet(pSelector->sources(), ctx, "SOURCES THIS EXTEND WHICH SHOULD BE SAME STILL: "))
1615
1672
 
1616
1673
 
1674
+ if (pSels->has_line_feed()) pNewSelector->has_line_feed(true);;
1617
1675
 
1618
- holder.push_back(make_pair(pSels, pNewSelector));
1676
+ holder.push_back(std::make_pair(pSels, pNewSelector));
1619
1677
  }
1620
1678
 
1621
1679
 
@@ -1626,18 +1684,18 @@ namespace Sass {
1626
1684
  Complex_Selector* pNewSelector = pair.second;
1627
1685
 
1628
1686
 
1687
+ // RUBY??: next [] if seen.include?(sels)
1629
1688
  if (seen.find(*pSels) != seen.end()) {
1630
1689
  continue;
1631
1690
  }
1632
1691
 
1633
1692
 
1634
- set<Compound_Selector> recurseSeen(seen);
1693
+ std::set<Compound_Selector> recurseSeen(seen);
1635
1694
  recurseSeen.insert(*pSels);
1636
1695
 
1637
1696
 
1638
1697
  DEBUG_PRINTLN(EXTEND_COMPOUND, "RECURSING DO EXTEND: " << complexSelectorToNode(pNewSelector, ctx))
1639
-
1640
- Node recurseExtendedSelectors = extendComplexSelector(pNewSelector, ctx, subsetMap, recurseSeen);
1698
+ Node recurseExtendedSelectors = extendComplexSelector(pNewSelector, ctx, subset_map, recurseSeen, isReplace, false); // !:isOriginal
1641
1699
 
1642
1700
  DEBUG_PRINTLN(EXTEND_COMPOUND, "RECURSING DO EXTEND RETURN: " << recurseExtendedSelectors)
1643
1701
 
@@ -1664,7 +1722,7 @@ namespace Sass {
1664
1722
  static bool complexSelectorHasExtension(
1665
1723
  Complex_Selector* pComplexSelector,
1666
1724
  Context& ctx,
1667
- ExtensionSubsetMap& subsetMap) {
1725
+ ExtensionSubsetMap& subset_map) {
1668
1726
 
1669
1727
  bool hasExtension = false;
1670
1728
 
@@ -1674,7 +1732,7 @@ namespace Sass {
1674
1732
  Compound_Selector* pHead = pIter->head();
1675
1733
 
1676
1734
  if (pHead) {
1677
- SubsetMapEntries entries = subsetMap.get_v(pHead->to_str_vec());
1735
+ SubsetMapEntries entries = subset_map.get_v(pHead->to_str_vec());
1678
1736
  for (ExtensionPair ext : entries) {
1679
1737
  // check if both selectors have the same media block parent
1680
1738
  if (ext.first->media_block() == pComplexSelector->media_block()) continue;
@@ -1684,16 +1742,16 @@ namespace Sass {
1684
1742
  ext.second->media_block()->media_queries() &&
1685
1743
  pComplexSelector->media_block()->media_queries()
1686
1744
  ) {
1687
- string query_left(ext.second->media_block()->media_queries()->perform(&to_string));
1688
- string query_right(pComplexSelector->media_block()->media_queries()->perform(&to_string));
1745
+ std::string query_left(ext.second->media_block()->media_queries()->perform(&to_string));
1746
+ std::string query_right(pComplexSelector->media_block()->media_queries()->perform(&to_string));
1689
1747
  if (query_left == query_right) continue;
1690
1748
  }
1691
1749
 
1692
1750
  // fail if one goes across media block boundaries
1693
- stringstream err;
1694
- string cwd(Sass::File::get_cwd());
1751
+ std::stringstream err;
1752
+ std::string cwd(Sass::File::get_cwd());
1695
1753
  ParserState pstate(ext.second->pstate());
1696
- string rel_path(Sass::File::resolve_relative_path(pstate.path, cwd, cwd));
1754
+ std::string rel_path(Sass::File::resolve_relative_path(pstate.path, cwd, cwd));
1697
1755
  err << "You may not @extend an outer selector from within @media.\n";
1698
1756
  err << "You may only @extend selectors within the same directive.\n";
1699
1757
  err << "From \"@extend " << ext.second->perform(&to_string) << "\"";
@@ -1708,19 +1766,19 @@ namespace Sass {
1708
1766
 
1709
1767
  if (!hasExtension) {
1710
1768
  /* ToDo: don't break stuff
1711
- stringstream err;
1769
+ std::stringstream err;
1712
1770
  To_String to_string(&ctx);
1713
- string cwd(Sass::File::get_cwd());
1714
- string sel1(pComplexSelector->perform(&to_string));
1771
+ std::string cwd(Sass::File::get_cwd());
1772
+ std::string sel1(pComplexSelector->perform(&to_string));
1715
1773
  Compound_Selector* pExtendSelector = 0;
1716
- for (auto i : subsetMap.values()) {
1774
+ for (auto i : subset_map.values()) {
1717
1775
  if (i.first == pComplexSelector) {
1718
1776
  pExtendSelector = i.second;
1719
1777
  break;
1720
1778
  }
1721
1779
  }
1722
1780
  if (!pExtendSelector || !pExtendSelector->is_optional()) {
1723
- string sel2(pExtendSelector ? pExtendSelector->perform(&to_string) : "[unknown]");
1781
+ std::string sel2(pExtendSelector ? pExtendSelector->perform(&to_string) : "[unknown]");
1724
1782
  err << "\"" << sel1 << "\" failed to @extend \"" << sel2 << "\"\n";
1725
1783
  err << "The selector \"" << sel2 << "\" was not found.\n";
1726
1784
  err << "Use \"@extend " << sel2 << " !optional\" if the extend should be able to fail.";
@@ -1747,22 +1805,25 @@ namespace Sass {
1747
1805
  static Node extendComplexSelector(
1748
1806
  Complex_Selector* pComplexSelector,
1749
1807
  Context& ctx,
1750
- ExtensionSubsetMap& subsetMap,
1751
- set<Compound_Selector> seen) {
1752
-
1753
- pComplexSelector->tail()->has_line_feed(pComplexSelector->has_line_feed());
1808
+ ExtensionSubsetMap& subset_map,
1809
+ std::set<Compound_Selector> seen, bool isReplace, bool isOriginal) {
1754
1810
 
1755
1811
  Node complexSelector = complexSelectorToNode(pComplexSelector, ctx);
1756
1812
  DEBUG_PRINTLN(EXTEND_COMPLEX, "EXTEND COMPLEX: " << complexSelector)
1757
1813
 
1758
1814
  Node extendedNotExpanded = Node::createCollection();
1759
1815
 
1760
- for (NodeDeque::iterator complexSelIter = complexSelector.collection()->begin(), complexSelIterEnd = complexSelector.collection()->end(); complexSelIter != complexSelIterEnd; ++complexSelIter) {
1816
+ for (NodeDeque::iterator complexSelIter = complexSelector.collection()->begin(),
1817
+ complexSelIterEnd = complexSelector.collection()->end();
1818
+ complexSelIter != complexSelIterEnd; ++complexSelIter)
1819
+ {
1820
+
1761
1821
  Node& sseqOrOp = *complexSelIter;
1762
1822
 
1763
1823
  DEBUG_PRINTLN(EXTEND_COMPLEX, "LOOP: " << sseqOrOp)
1764
1824
 
1765
1825
  // If it's not a selector (meaning it's a combinator), just include it automatically
1826
+ // RUBY: next [[sseq_or_op]] unless sseq_or_op.is_a?(SimpleSequence)
1766
1827
  if (!sseqOrOp.isSelector()) {
1767
1828
  // Wrap our Combinator in two collections to match ruby. This is essentially making a collection Node
1768
1829
  // with one collection child. The collection child represents a Complex_Selector that is only a combinator.
@@ -1776,8 +1837,9 @@ namespace Sass {
1776
1837
 
1777
1838
  Compound_Selector* pCompoundSelector = sseqOrOp.selector()->head();
1778
1839
 
1779
- Node extended = extendCompoundSelector(pCompoundSelector, ctx, subsetMap, seen);
1780
-
1840
+ // RUBY: extended = sseq_or_op.do_extend(extends, parent_directives, replace, seen)
1841
+ Node extended = extendCompoundSelector(pCompoundSelector, ctx, subset_map, seen, isReplace);
1842
+ if (sseqOrOp.got_line_feed) extended.got_line_feed = true;
1781
1843
  DEBUG_PRINTLN(EXTEND_COMPLEX, "EXTENDED: " << extended)
1782
1844
 
1783
1845
 
@@ -1785,6 +1847,14 @@ namespace Sass {
1785
1847
  // due to the member mapping: choices = extended.map {|seq| seq.members}
1786
1848
  Complex_Selector* pJustCurrentCompoundSelector = sseqOrOp.selector();
1787
1849
 
1850
+ // RUBY: extended.first.add_sources!([self]) if original && !has_placeholder?
1851
+ if (isOriginal && !pComplexSelector->has_placeholder()) {
1852
+ SourcesSet srcset;
1853
+ srcset.insert(pComplexSelector);
1854
+ pJustCurrentCompoundSelector->addSources(srcset, ctx);
1855
+ DEBUG_PRINTLN(EXTEND_COMPLEX, "ADD SOURCES: " << *pComplexSelector)
1856
+ }
1857
+
1788
1858
  bool isSuperselector = false;
1789
1859
  for (NodeDeque::iterator iterator = extended.collection()->begin(), endIterator = extended.collection()->end();
1790
1860
  iterator != endIterator; ++iterator) {
@@ -1797,6 +1867,7 @@ namespace Sass {
1797
1867
  }
1798
1868
 
1799
1869
  if (!isSuperselector) {
1870
+ if (sseqOrOp.got_line_feed) pJustCurrentCompoundSelector->has_line_feed(sseqOrOp.got_line_feed);
1800
1871
  extended.collection()->push_front(complexSelectorToNode(pJustCurrentCompoundSelector, ctx));
1801
1872
  }
1802
1873
 
@@ -1824,6 +1895,7 @@ namespace Sass {
1824
1895
  for (NodeDeque::iterator pathsIter = paths.collection()->begin(), pathsEndIter = paths.collection()->end(); pathsIter != pathsEndIter; ++pathsIter) {
1825
1896
  Node& path = *pathsIter;
1826
1897
  Node weaved = weave(path, ctx);
1898
+ weaved.got_line_feed = path.got_line_feed;
1827
1899
  weaves.collection()->push_back(weaved);
1828
1900
  }
1829
1901
 
@@ -1832,7 +1904,7 @@ namespace Sass {
1832
1904
 
1833
1905
 
1834
1906
  // Ruby Equivalent: trim
1835
- Node trimmed = trim(weaves, ctx);
1907
+ Node trimmed = trim(weaves, ctx, isReplace);
1836
1908
 
1837
1909
  DEBUG_PRINTLN(EXTEND_COMPLEX, "TRIMMED: " << trimmed)
1838
1910
 
@@ -1854,11 +1926,11 @@ namespace Sass {
1854
1926
  /*
1855
1927
  This is the equivalent of ruby's CommaSequence.do_extend.
1856
1928
  */
1857
- static Selector_List* extendSelectorList(Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subsetMap, bool& extendedSomething) {
1929
+ Selector_List* Extend::extendSelectorList(Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace, bool& extendedSomething) {
1858
1930
 
1859
1931
  To_String to_string(&ctx);
1860
1932
 
1861
- Selector_List* pNewSelectors = new (ctx.mem) Selector_List(pSelectorList->pstate(), pSelectorList->length());
1933
+ Selector_List* pNewSelectors = SASS_MEMORY_NEW(ctx.mem, Selector_List, pSelectorList->pstate(), pSelectorList->length());
1862
1934
 
1863
1935
  extendedSomething = false;
1864
1936
 
@@ -1870,23 +1942,26 @@ namespace Sass {
1870
1942
  // run through the extend code (which does a data model transformation), check if there is anything to extend before doing
1871
1943
  // the extend. We might be able to optimize extendComplexSelector, but this approach keeps us closer to ruby sass (which helps
1872
1944
  // when debugging).
1873
- if (!complexSelectorHasExtension(pSelector, ctx, subsetMap)) {
1945
+ if (!complexSelectorHasExtension(pSelector, ctx, subset_map)) {
1874
1946
  *pNewSelectors << pSelector;
1875
1947
  continue;
1876
1948
  }
1877
1949
 
1878
1950
  extendedSomething = true;
1879
1951
 
1880
- set<Compound_Selector> seen;
1881
- Node extendedSelectors = extendComplexSelector(pSelector, ctx, subsetMap, seen);
1952
+ std::set<Compound_Selector> seen;
1882
1953
 
1954
+ Node extendedSelectors = extendComplexSelector(pSelector, ctx, subset_map, seen, isReplace, true);
1883
1955
  if (!pSelector->has_placeholder()) {
1884
1956
  if (!extendedSelectors.contains(complexSelectorToNode(pSelector, ctx), true /*simpleSelectorOrderDependent*/)) {
1885
1957
  *pNewSelectors << pSelector;
1886
1958
  }
1887
1959
  }
1888
1960
 
1889
- for (NodeDeque::iterator iterator = extendedSelectors.collection()->begin(), iteratorEnd = extendedSelectors.collection()->end(); iterator != iteratorEnd; ++iterator) {
1961
+ for (NodeDeque::iterator iterator = extendedSelectors.collection()->begin(), iteratorBegin = extendedSelectors.collection()->begin(), iteratorEnd = extendedSelectors.collection()->end(); iterator != iteratorEnd; ++iterator) {
1962
+ // When it is a replace, skip the first one, unless there is only one
1963
+ if(isReplace && iterator == iteratorBegin && extendedSelectors.collection()->size() > 1 ) continue;
1964
+
1890
1965
  Node& childNode = *iterator;
1891
1966
  *pNewSelectors << nodeToComplexSelector(childNode, ctx);
1892
1967
  }
@@ -1930,7 +2005,7 @@ namespace Sass {
1930
2005
 
1931
2006
  // Extend a ruleset by extending the selectors and updating them on the ruleset. The block's rules don't need to change.
1932
2007
  template <typename ObjectType>
1933
- static void extendObjectWithSelectorAndBlock(ObjectType* pObject, Context& ctx, ExtensionSubsetMap& subsetMap) {
2008
+ static void extendObjectWithSelectorAndBlock(ObjectType* pObject, Context& ctx, ExtensionSubsetMap& subset_map) {
1934
2009
  To_String to_string(&ctx);
1935
2010
 
1936
2011
  DEBUG_PRINTLN(EXTEND_OBJECT, "FOUND SELECTOR: " << static_cast<Selector_List*>(pObject->selector())->perform(&to_string))
@@ -1943,23 +2018,13 @@ namespace Sass {
1943
2018
  }
1944
2019
 
1945
2020
  bool extendedSomething = false;
1946
- Selector_List* pNewSelectorList = extendSelectorList(static_cast<Selector_List*>(pObject->selector()), ctx, subsetMap, extendedSomething);
2021
+ Selector_List* pNewSelectorList = Extend::extendSelectorList(static_cast<Selector_List*>(pObject->selector()), ctx, subset_map, false, extendedSomething);
1947
2022
 
1948
2023
  if (extendedSomething && pNewSelectorList) {
1949
2024
  DEBUG_PRINTLN(EXTEND_OBJECT, "EXTEND ORIGINAL SELECTORS: " << static_cast<Selector_List*>(pObject->selector())->perform(&to_string))
1950
2025
  DEBUG_PRINTLN(EXTEND_OBJECT, "EXTEND SETTING NEW SELECTORS: " << pNewSelectorList->perform(&to_string))
1951
-
1952
- // re-parse in order to restructure expanded placeholder nodes correctly.
1953
- //
1954
- // TODO: I don't know if this is needed, but it was in the original C++ implementation, so I kept it. Try running the tests without re-parsing.
1955
- // this probably messes up source-maps
1956
- pObject->selector(
1957
- Parser::from_c_str(
1958
- (pNewSelectorList->perform(&to_string) + ";").c_str(),
1959
- ctx,
1960
- pNewSelectorList->pstate()
1961
- ).parse_selector_group()
1962
- );
2026
+ pNewSelectorList->remove_parent_selectors();
2027
+ pObject->selector(pNewSelectorList);
1963
2028
  } else {
1964
2029
  DEBUG_PRINTLN(EXTEND_OBJECT, "EXTEND DID NOT TRY TO EXTEND ANYTHING")
1965
2030
  }
@@ -1981,30 +2046,24 @@ namespace Sass {
1981
2046
  void Extend::operator()(Ruleset* pRuleset)
1982
2047
  {
1983
2048
  extendObjectWithSelectorAndBlock(pRuleset, ctx, subset_map);
1984
-
1985
2049
  pRuleset->block()->perform(this);
1986
2050
  }
1987
2051
 
1988
- void Extend::operator()(Feature_Block* pFeatureBlock)
2052
+ void Extend::operator()(Supports_Block* pFeatureBlock)
1989
2053
  {
1990
- if (pFeatureBlock->selector()) {
1991
- extendObjectWithSelectorAndBlock(pFeatureBlock, ctx, subset_map);
1992
- }
1993
-
1994
2054
  pFeatureBlock->block()->perform(this);
1995
2055
  }
1996
2056
 
1997
2057
  void Extend::operator()(Media_Block* pMediaBlock)
1998
2058
  {
1999
- if (pMediaBlock->selector()) {
2000
- extendObjectWithSelectorAndBlock(pMediaBlock, ctx, subset_map);
2001
- }
2002
-
2003
2059
  pMediaBlock->block()->perform(this);
2004
2060
  }
2005
2061
 
2006
2062
  void Extend::operator()(At_Rule* a)
2007
2063
  {
2064
+ // Selector_List* ls = dynamic_cast<Selector_List*>(a->selector());
2065
+ // selector_stack.push_back(ls);
2008
2066
  if (a->block()) a->block()->perform(this);
2067
+ // exp.selector_stack.pop_back();
2009
2068
  }
2010
2069
  }