sassc 1.11.4 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +2 -2
  3. data/CODE_OF_CONDUCT.md +10 -0
  4. data/README.md +4 -1
  5. data/ext/libsass/.editorconfig +1 -1
  6. data/ext/libsass/.github/CONTRIBUTING.md +7 -7
  7. data/ext/libsass/.github/ISSUE_TEMPLATE.md +31 -6
  8. data/ext/libsass/.gitignore +3 -0
  9. data/ext/libsass/.travis.yml +37 -18
  10. data/ext/libsass/GNUmakefile.am +23 -37
  11. data/ext/libsass/Makefile +10 -6
  12. data/ext/libsass/Makefile.conf +3 -0
  13. data/ext/libsass/Readme.md +68 -63
  14. data/ext/libsass/appveyor.yml +7 -3
  15. data/ext/libsass/configure.ac +10 -14
  16. data/ext/libsass/docs/api-context-internal.md +29 -21
  17. data/ext/libsass/docs/api-context.md +26 -6
  18. data/ext/libsass/docs/api-doc.md +49 -16
  19. data/ext/libsass/docs/api-function-example.md +1 -1
  20. data/ext/libsass/docs/api-function.md +31 -7
  21. data/ext/libsass/docs/api-importer.md +19 -19
  22. data/ext/libsass/docs/api-value.md +4 -2
  23. data/ext/libsass/docs/build-on-windows.md +4 -4
  24. data/ext/libsass/docs/build-with-mingw.md +3 -3
  25. data/ext/libsass/docs/build.md +9 -9
  26. data/ext/libsass/docs/custom-functions-internal.md +10 -8
  27. data/ext/libsass/docs/implementations.md +20 -8
  28. data/ext/libsass/docs/unicode.md +16 -10
  29. data/ext/libsass/include/sass/base.h +0 -3
  30. data/ext/libsass/include/sass/context.h +20 -2
  31. data/ext/libsass/include/sass/functions.h +31 -0
  32. data/ext/libsass/include/sass/values.h +3 -1
  33. data/ext/libsass/include/sass/version.h +1 -1
  34. data/ext/libsass/include/sass/version.h.in +1 -1
  35. data/ext/libsass/include/sass2scss.h +1 -1
  36. data/ext/libsass/res/resource.rc +6 -6
  37. data/ext/libsass/script/ci-build-libsass +10 -5
  38. data/ext/libsass/script/ci-build-plugin +62 -0
  39. data/ext/libsass/script/ci-install-compiler +1 -1
  40. data/ext/libsass/script/ci-install-deps +4 -7
  41. data/ext/libsass/script/ci-report-coverage +13 -3
  42. data/ext/libsass/script/tap-driver +1 -1
  43. data/ext/libsass/script/tap-runner +1 -1
  44. data/ext/libsass/src/GNUmakefile.am +1 -1
  45. data/ext/libsass/src/ast.cpp +537 -762
  46. data/ext/libsass/src/ast.hpp +377 -419
  47. data/ext/libsass/src/ast_def_macros.hpp +26 -1
  48. data/ext/libsass/src/ast_fwd_decl.cpp +29 -0
  49. data/ext/libsass/src/ast_fwd_decl.hpp +94 -21
  50. data/ext/libsass/src/b64/encode.h +3 -1
  51. data/ext/libsass/src/backtrace.cpp +46 -0
  52. data/ext/libsass/src/backtrace.hpp +7 -54
  53. data/ext/libsass/src/bind.cpp +72 -50
  54. data/ext/libsass/src/bind.hpp +0 -1
  55. data/ext/libsass/src/cencode.c +6 -0
  56. data/ext/libsass/src/check_nesting.cpp +157 -135
  57. data/ext/libsass/src/check_nesting.hpp +11 -10
  58. data/ext/libsass/src/color_maps.cpp +10 -6
  59. data/ext/libsass/src/color_maps.hpp +6 -8
  60. data/ext/libsass/src/constants.cpp +4 -3
  61. data/ext/libsass/src/constants.hpp +4 -3
  62. data/ext/libsass/src/context.cpp +110 -47
  63. data/ext/libsass/src/context.hpp +11 -1
  64. data/ext/libsass/src/cssize.cpp +105 -94
  65. data/ext/libsass/src/cssize.hpp +4 -5
  66. data/ext/libsass/src/debugger.hpp +247 -244
  67. data/ext/libsass/src/emitter.cpp +30 -6
  68. data/ext/libsass/src/emitter.hpp +7 -0
  69. data/ext/libsass/src/environment.cpp +67 -16
  70. data/ext/libsass/src/environment.hpp +28 -7
  71. data/ext/libsass/src/error_handling.cpp +92 -64
  72. data/ext/libsass/src/error_handling.hpp +64 -43
  73. data/ext/libsass/src/eval.cpp +494 -544
  74. data/ext/libsass/src/eval.hpp +17 -23
  75. data/ext/libsass/src/expand.cpp +182 -154
  76. data/ext/libsass/src/expand.hpp +4 -5
  77. data/ext/libsass/src/extend.cpp +299 -291
  78. data/ext/libsass/src/extend.hpp +46 -11
  79. data/ext/libsass/src/file.cpp +103 -36
  80. data/ext/libsass/src/file.hpp +21 -4
  81. data/ext/libsass/src/functions.cpp +561 -312
  82. data/ext/libsass/src/functions.hpp +8 -5
  83. data/ext/libsass/src/inspect.cpp +108 -53
  84. data/ext/libsass/src/inspect.hpp +5 -2
  85. data/ext/libsass/src/lexer.cpp +15 -7
  86. data/ext/libsass/src/lexer.hpp +13 -4
  87. data/ext/libsass/src/listize.cpp +3 -2
  88. data/ext/libsass/src/listize.hpp +0 -1
  89. data/ext/libsass/src/memory/SharedPtr.cpp +16 -18
  90. data/ext/libsass/src/memory/SharedPtr.hpp +47 -43
  91. data/ext/libsass/src/node.cpp +34 -38
  92. data/ext/libsass/src/node.hpp +6 -8
  93. data/ext/libsass/src/operation.hpp +2 -2
  94. data/ext/libsass/src/operators.cpp +240 -0
  95. data/ext/libsass/src/operators.hpp +30 -0
  96. data/ext/libsass/src/output.cpp +22 -20
  97. data/ext/libsass/src/parser.cpp +719 -358
  98. data/ext/libsass/src/parser.hpp +57 -22
  99. data/ext/libsass/src/plugins.cpp +28 -10
  100. data/ext/libsass/src/position.cpp +21 -3
  101. data/ext/libsass/src/position.hpp +2 -1
  102. data/ext/libsass/src/prelexer.cpp +104 -19
  103. data/ext/libsass/src/prelexer.hpp +10 -3
  104. data/ext/libsass/src/remove_placeholders.cpp +9 -10
  105. data/ext/libsass/src/remove_placeholders.hpp +1 -5
  106. data/ext/libsass/src/sass.cpp +62 -4
  107. data/ext/libsass/src/sass.hpp +5 -2
  108. data/ext/libsass/src/sass_context.cpp +96 -58
  109. data/ext/libsass/src/sass_context.hpp +7 -5
  110. data/ext/libsass/src/sass_functions.cpp +63 -1
  111. data/ext/libsass/src/sass_functions.hpp +19 -1
  112. data/ext/libsass/src/sass_util.cpp +3 -3
  113. data/ext/libsass/src/sass_util.hpp +4 -4
  114. data/ext/libsass/src/sass_values.cpp +42 -39
  115. data/ext/libsass/src/sass_values.hpp +2 -1
  116. data/ext/libsass/src/source_map.cpp +16 -18
  117. data/ext/libsass/src/subset_map.cpp +6 -8
  118. data/ext/libsass/src/subset_map.hpp +6 -6
  119. data/ext/libsass/src/to_c.cpp +2 -2
  120. data/ext/libsass/src/to_value.cpp +8 -3
  121. data/ext/libsass/src/to_value.hpp +1 -0
  122. data/ext/libsass/src/units.cpp +349 -45
  123. data/ext/libsass/src/units.hpp +39 -22
  124. data/ext/libsass/src/utf8/checked.h +7 -0
  125. data/ext/libsass/src/utf8/unchecked.h +7 -0
  126. data/ext/libsass/src/utf8_string.cpp +1 -1
  127. data/ext/libsass/src/util.cpp +139 -45
  128. data/ext/libsass/src/util.hpp +4 -7
  129. data/ext/libsass/src/values.cpp +15 -23
  130. data/ext/libsass/win/libsass.sln +13 -2
  131. data/ext/libsass/win/libsass.sln.DotSettings +9 -0
  132. data/ext/libsass/win/libsass.targets +3 -0
  133. data/ext/libsass/win/libsass.vcxproj.filters +9 -0
  134. data/lib/sassc/version.rb +1 -1
  135. data/sassc.gemspec +1 -1
  136. data/test/native_test.rb +1 -1
  137. metadata +11 -4
@@ -1,6 +1,7 @@
1
1
  #ifndef SASS_AST_H
2
2
  #define SASS_AST_H
3
3
 
4
+ #include "sass.hpp"
4
5
  #include <set>
5
6
  #include <deque>
6
7
  #include <vector>
@@ -74,6 +75,9 @@ namespace Sass {
74
75
  // Note: most methods follow precision option
75
76
  const double NUMBER_EPSILON = 0.00000000000001;
76
77
 
78
+ // macro to test if numbers are equal within a small error margin
79
+ #define NEAR_EQUAL(lhs, rhs) std::fabs(lhs - rhs) < NUMBER_EPSILON
80
+
77
81
  // ToDo: where does this fit best?
78
82
  // We don't share this with C-API?
79
83
  class Operand {
@@ -120,12 +124,14 @@ namespace Sass {
120
124
  ATTACH_VIRTUAL_AST_OPERATIONS(AST_Node);
121
125
  virtual std::string inspect() const { return to_string({ INSPECT, 5 }); }
122
126
  virtual std::string to_sass() const { return to_string({ TO_SASS, 5 }); }
123
- virtual std::string to_string(Sass_Inspect_Options opt) const;
124
- virtual std::string to_string() const;
127
+ virtual const std::string to_string(Sass_Inspect_Options opt) const;
128
+ virtual const std::string to_string() const;
125
129
  virtual void cloneChildren() {};
130
+ // generic find function (not fully implemented yet)
131
+ // ToDo: add specific implementions to all children
132
+ virtual bool find ( bool (*f)(AST_Node_Obj) ) { return f(this); };
126
133
  public:
127
134
  void update_pstate(const ParserState& pstate);
128
- void set_pstate_offset(const Offset& offset);
129
135
  public:
130
136
  Offset off() { return pstate(); }
131
137
  Position pos() { return pstate(); }
@@ -133,6 +139,21 @@ namespace Sass {
133
139
  };
134
140
  inline AST_Node::~AST_Node() { }
135
141
 
142
+ //////////////////////////////////////////////////////////////////////
143
+ // define cast template now (need complete type)
144
+ //////////////////////////////////////////////////////////////////////
145
+
146
+ template<class T>
147
+ T* Cast(AST_Node* ptr) {
148
+ return ptr && typeid(T) == typeid(*ptr) ?
149
+ static_cast<T*>(ptr) : NULL;
150
+ };
151
+
152
+ template<class T>
153
+ const T* Cast(const AST_Node* ptr) {
154
+ return ptr && typeid(T) == typeid(*ptr) ?
155
+ static_cast<const T*>(ptr) : NULL;
156
+ };
136
157
 
137
158
  //////////////////////////////////////////////////////////////////////
138
159
  // Abstract base class for expressions. This side of the AST hierarchy
@@ -151,9 +172,11 @@ namespace Sass {
151
172
  MAP,
152
173
  SELECTOR,
153
174
  NULL_VAL,
175
+ FUNCTION_VAL,
154
176
  C_WARNING,
155
177
  C_ERROR,
156
178
  FUNCTION,
179
+ VARIABLE,
157
180
  NUM_TYPES
158
181
  };
159
182
  enum Simple_Type {
@@ -186,7 +209,7 @@ namespace Sass {
186
209
  { }
187
210
  virtual operator bool() { return true; }
188
211
  virtual ~Expression() { }
189
- virtual std::string type() { return ""; /* TODO: raise an error? */ }
212
+ virtual std::string type() const { return ""; /* TODO: raise an error? */ }
190
213
  virtual bool is_invisible() const { return false; }
191
214
  static std::string type_name() { return ""; }
192
215
  virtual bool is_false() { return false; }
@@ -343,8 +366,11 @@ namespace Sass {
343
366
  void reset_duplicate_key() { duplicate_key_ = 0; }
344
367
  virtual void adjust_after_pushing(std::pair<Expression_Obj, Expression_Obj> p) { }
345
368
  public:
346
- Hashed(size_t s = 0) : elements_(ExpressionMap(s)), list_(std::vector<Expression_Obj>())
347
- { elements_.reserve(s); list_.reserve(s); reset_duplicate_key(); }
369
+ Hashed(size_t s = 0)
370
+ : elements_(ExpressionMap(s)),
371
+ list_(std::vector<Expression_Obj>()),
372
+ hash_(0), duplicate_key_(NULL)
373
+ { elements_.reserve(s); list_.reserve(s); }
348
374
  virtual ~Hashed();
349
375
  size_t length() const { return list_.size(); }
350
376
  bool empty() const { return list_.empty(); }
@@ -454,7 +480,6 @@ namespace Sass {
454
480
  ////////////////////////
455
481
  class Block : public Statement, public Vectorized<Statement_Obj> {
456
482
  ADD_PROPERTY(bool, is_root)
457
- ADD_PROPERTY(bool, is_at_root);
458
483
  // needed for properly formatted CSS emission
459
484
  protected:
460
485
  void adjust_after_pushing(Statement_Obj s)
@@ -464,14 +489,12 @@ namespace Sass {
464
489
  Block(ParserState pstate, size_t s = 0, bool r = false)
465
490
  : Statement(pstate),
466
491
  Vectorized<Statement_Obj>(s),
467
- is_root_(r),
468
- is_at_root_(false)
492
+ is_root_(r)
469
493
  { }
470
494
  Block(const Block* ptr)
471
495
  : Statement(ptr),
472
496
  Vectorized<Statement_Obj>(*ptr),
473
- is_root_(ptr->is_root_),
474
- is_at_root_(ptr->is_at_root_)
497
+ is_root_(ptr->is_root_)
475
498
  { }
476
499
  virtual bool has_content()
477
500
  {
@@ -509,17 +532,15 @@ namespace Sass {
509
532
  // of style declarations.
510
533
  /////////////////////////////////////////////////////////////////////////////
511
534
  class Ruleset : public Has_Block {
512
- ADD_PROPERTY(Selector_Obj, selector)
513
- ADD_PROPERTY(bool, at_root);
535
+ ADD_PROPERTY(Selector_List_Obj, selector)
514
536
  ADD_PROPERTY(bool, is_root);
515
537
  public:
516
- Ruleset(ParserState pstate, Selector_Obj s = 0, Block_Obj b = 0)
517
- : Has_Block(pstate, b), selector_(s), at_root_(false), is_root_(false)
538
+ Ruleset(ParserState pstate, Selector_List_Obj s = 0, Block_Obj b = 0)
539
+ : Has_Block(pstate, b), selector_(s), is_root_(false)
518
540
  { statement_type(RULESET); }
519
541
  Ruleset(const Ruleset* ptr)
520
542
  : Has_Block(ptr),
521
543
  selector_(ptr->selector_),
522
- at_root_(ptr->at_root_),
523
544
  is_root_(ptr->is_root_)
524
545
  { statement_type(RULESET); }
525
546
  bool is_invisible() const;
@@ -551,13 +572,15 @@ namespace Sass {
551
572
  // Trace.
552
573
  /////////////////
553
574
  class Trace : public Has_Block {
554
- ADD_PROPERTY(std::string, name)
575
+ ADD_CONSTREF(char, type)
576
+ ADD_CONSTREF(std::string, name)
555
577
  public:
556
- Trace(ParserState pstate, std::string n, Block_Obj b = 0)
557
- : Has_Block(pstate, b), name_(n)
578
+ Trace(ParserState pstate, std::string n, Block_Obj b = 0, char type = 'm')
579
+ : Has_Block(pstate, b), type_(type), name_(n)
558
580
  { }
559
581
  Trace(const Trace* ptr)
560
582
  : Has_Block(ptr),
583
+ type_(ptr->type_),
561
584
  name_(ptr->name_)
562
585
  { }
563
586
  ATTACH_AST_OPERATIONS(Trace)
@@ -573,9 +596,6 @@ namespace Sass {
573
596
  Media_Block(ParserState pstate, List_Obj mqs, Block_Obj b)
574
597
  : Has_Block(pstate, b), media_queries_(mqs)
575
598
  { statement_type(MEDIA); }
576
- Media_Block(ParserState pstate, List_Obj mqs, Block_Obj b, Selector_Obj s)
577
- : Has_Block(pstate, b), media_queries_(mqs)
578
- { statement_type(MEDIA); }
579
599
  Media_Block(const Media_Block* ptr)
580
600
  : Has_Block(ptr), media_queries_(ptr->media_queries_)
581
601
  { statement_type(MEDIA); }
@@ -590,11 +610,11 @@ namespace Sass {
590
610
  // optional statement block.
591
611
  ///////////////////////////////////////////////////////////////////////
592
612
  class Directive : public Has_Block {
593
- ADD_PROPERTY(std::string, keyword)
594
- ADD_PROPERTY(Selector_Obj, selector)
613
+ ADD_CONSTREF(std::string, keyword)
614
+ ADD_PROPERTY(Selector_List_Obj, selector)
595
615
  ADD_PROPERTY(Expression_Obj, value)
596
616
  public:
597
- Directive(ParserState pstate, std::string kwd, Selector_Obj sel = 0, Block_Obj b = 0, Expression_Obj val = 0)
617
+ Directive(ParserState pstate, std::string kwd, Selector_List_Obj sel = 0, Block_Obj b = 0, Expression_Obj val = 0)
598
618
  : Has_Block(pstate, b), keyword_(kwd), selector_(sel), value_(val) // set value manually if needed
599
619
  { statement_type(DIRECTIVE); }
600
620
  Directive(const Directive* ptr)
@@ -626,7 +646,7 @@ namespace Sass {
626
646
  class Keyframe_Rule : public Has_Block {
627
647
  // according to css spec, this should be <keyframes-name>
628
648
  // <keyframes-name> = <custom-ident> | <string>
629
- ADD_PROPERTY(Selector_Obj, name)
649
+ ADD_PROPERTY(Selector_List_Obj, name)
630
650
  public:
631
651
  Keyframe_Rule(ParserState pstate, Block_Obj b)
632
652
  : Has_Block(pstate, b), name_()
@@ -645,19 +665,22 @@ namespace Sass {
645
665
  ADD_PROPERTY(String_Obj, property)
646
666
  ADD_PROPERTY(Expression_Obj, value)
647
667
  ADD_PROPERTY(bool, is_important)
668
+ ADD_PROPERTY(bool, is_custom_property)
648
669
  ADD_PROPERTY(bool, is_indented)
649
670
  public:
650
671
  Declaration(ParserState pstate,
651
- String_Obj prop, Expression_Obj val, bool i = false, Block_Obj b = 0)
652
- : Has_Block(pstate, b), property_(prop), value_(val), is_important_(i), is_indented_(false)
672
+ String_Obj prop, Expression_Obj val, bool i = false, bool c = false, Block_Obj b = 0)
673
+ : Has_Block(pstate, b), property_(prop), value_(val), is_important_(i), is_custom_property_(c), is_indented_(false)
653
674
  { statement_type(DECLARATION); }
654
675
  Declaration(const Declaration* ptr)
655
676
  : Has_Block(ptr),
656
677
  property_(ptr->property_),
657
678
  value_(ptr->value_),
658
679
  is_important_(ptr->is_important_),
680
+ is_custom_property_(ptr->is_custom_property_),
659
681
  is_indented_(ptr->is_indented_)
660
682
  { statement_type(DECLARATION); }
683
+ virtual bool is_invisible() const;
661
684
  ATTACH_AST_OPERATIONS(Declaration)
662
685
  ATTACH_OPERATIONS()
663
686
  };
@@ -666,7 +689,7 @@ namespace Sass {
666
689
  // Assignments -- variable and value.
667
690
  /////////////////////////////////////
668
691
  class Assignment : public Statement {
669
- ADD_PROPERTY(std::string, variable)
692
+ ADD_CONSTREF(std::string, variable)
670
693
  ADD_PROPERTY(Expression_Obj, value)
671
694
  ADD_PROPERTY(bool, is_default)
672
695
  ADD_PROPERTY(bool, is_global)
@@ -811,7 +834,7 @@ namespace Sass {
811
834
  ADD_PROPERTY(Block_Obj, alternative)
812
835
  public:
813
836
  If(ParserState pstate, Expression_Obj pred, Block_Obj con, Block_Obj alt = 0)
814
- : Has_Block(pstate, &con), predicate_(pred), alternative_(alt)
837
+ : Has_Block(pstate, con), predicate_(pred), alternative_(alt)
815
838
  { statement_type(IF); }
816
839
  If(const If* ptr)
817
840
  : Has_Block(ptr),
@@ -830,7 +853,7 @@ namespace Sass {
830
853
  // The Sass `@for` control directive.
831
854
  /////////////////////////////////////
832
855
  class For : public Has_Block {
833
- ADD_PROPERTY(std::string, variable)
856
+ ADD_CONSTREF(std::string, variable)
834
857
  ADD_PROPERTY(Expression_Obj, lower_bound)
835
858
  ADD_PROPERTY(Expression_Obj, upper_bound)
836
859
  ADD_PROPERTY(bool, is_inclusive)
@@ -904,9 +927,9 @@ namespace Sass {
904
927
  // The Sass `@extend` directive.
905
928
  ////////////////////////////////
906
929
  class Extension : public Statement {
907
- ADD_PROPERTY(Selector_Obj, selector)
930
+ ADD_PROPERTY(Selector_List_Obj, selector)
908
931
  public:
909
- Extension(ParserState pstate, Selector_Obj s)
932
+ Extension(ParserState pstate, Selector_List_Obj s)
910
933
  : Statement(pstate), selector_(s)
911
934
  { statement_type(EXTEND); }
912
935
  Extension(const Extension* ptr)
@@ -921,13 +944,12 @@ namespace Sass {
921
944
  // by a type tag.
922
945
  /////////////////////////////////////////////////////////////////////////////
923
946
  struct Backtrace;
924
- typedef Environment<AST_Node_Obj> Env;
925
947
  typedef const char* Signature;
926
- typedef Expression_Ptr (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtrace*, std::vector<Selector_List_Obj>);
948
+ typedef Expression_Ptr (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtraces, std::vector<Selector_List_Obj>);
927
949
  class Definition : public Has_Block {
928
950
  public:
929
951
  enum Type { MIXIN, FUNCTION };
930
- ADD_PROPERTY(std::string, name)
952
+ ADD_CONSTREF(std::string, name)
931
953
  ADD_PROPERTY(Parameters_Obj, parameters)
932
954
  ADD_PROPERTY(Env*, environment)
933
955
  ADD_PROPERTY(Type, type)
@@ -1009,7 +1031,7 @@ namespace Sass {
1009
1031
  // Mixin calls (i.e., `@include ...`).
1010
1032
  //////////////////////////////////////
1011
1033
  class Mixin_Call : public Has_Block {
1012
- ADD_PROPERTY(std::string, name)
1034
+ ADD_CONSTREF(std::string, name)
1013
1035
  ADD_PROPERTY(Arguments_Obj, arguments)
1014
1036
  public:
1015
1037
  Mixin_Call(ParserState pstate, std::string n, Arguments_Obj args, Block_Obj b = 0)
@@ -1028,11 +1050,15 @@ namespace Sass {
1028
1050
  // The @content directive for mixin content blocks.
1029
1051
  ///////////////////////////////////////////////////
1030
1052
  class Content : public Statement {
1031
- ADD_PROPERTY(Media_Block_Obj, media_block)
1053
+ ADD_PROPERTY(Media_Block_Ptr, media_block)
1032
1054
  public:
1033
- Content(ParserState pstate) : Statement(pstate)
1055
+ Content(ParserState pstate)
1056
+ : Statement(pstate),
1057
+ media_block_(NULL)
1034
1058
  { statement_type(CONTENT); }
1035
- Content(const Content* ptr) : Statement(ptr)
1059
+ Content(const Content* ptr)
1060
+ : Statement(ptr),
1061
+ media_block_(ptr->media_block_)
1036
1062
  { statement_type(CONTENT); }
1037
1063
  ATTACH_AST_OPERATIONS(Content)
1038
1064
  ATTACH_OPERATIONS()
@@ -1047,14 +1073,16 @@ namespace Sass {
1047
1073
  private:
1048
1074
  ADD_PROPERTY(enum Sass_Separator, separator)
1049
1075
  ADD_PROPERTY(bool, is_arglist)
1076
+ ADD_PROPERTY(bool, is_bracketed)
1050
1077
  ADD_PROPERTY(bool, from_selector)
1051
1078
  public:
1052
1079
  List(ParserState pstate,
1053
- size_t size = 0, enum Sass_Separator sep = SASS_SPACE, bool argl = false)
1080
+ size_t size = 0, enum Sass_Separator sep = SASS_SPACE, bool argl = false, bool bracket = false)
1054
1081
  : Value(pstate),
1055
1082
  Vectorized<Expression_Obj>(size),
1056
1083
  separator_(sep),
1057
1084
  is_arglist_(argl),
1085
+ is_bracketed_(bracket),
1058
1086
  from_selector_(false)
1059
1087
  { concrete_type(LIST); }
1060
1088
  List(const List* ptr)
@@ -1062,15 +1090,16 @@ namespace Sass {
1062
1090
  Vectorized<Expression_Obj>(*ptr),
1063
1091
  separator_(ptr->separator_),
1064
1092
  is_arglist_(ptr->is_arglist_),
1093
+ is_bracketed_(ptr->is_bracketed_),
1065
1094
  from_selector_(ptr->from_selector_)
1066
1095
  { concrete_type(LIST); }
1067
- std::string type() { return is_arglist_ ? "arglist" : "list"; }
1096
+ std::string type() const { return is_arglist_ ? "arglist" : "list"; }
1068
1097
  static std::string type_name() { return "list"; }
1069
1098
  const char* sep_string(bool compressed = false) const {
1070
1099
  return separator() == SASS_SPACE ?
1071
1100
  " " : (compressed ? "," : ", ");
1072
1101
  }
1073
- bool is_invisible() const { return empty(); }
1102
+ bool is_invisible() const { return empty() && !is_bracketed(); }
1074
1103
  Expression_Obj value_at_index(size_t i);
1075
1104
 
1076
1105
  virtual size_t size() const;
@@ -1079,6 +1108,7 @@ namespace Sass {
1079
1108
  {
1080
1109
  if (hash_ == 0) {
1081
1110
  hash_ = std::hash<std::string>()(sep_string());
1111
+ hash_combine(hash_, std::hash<bool>()(is_bracketed()));
1082
1112
  for (size_t i = 0, L = length(); i < L; ++i)
1083
1113
  hash_combine(hash_, (elements()[i])->hash());
1084
1114
  }
@@ -1112,10 +1142,10 @@ namespace Sass {
1112
1142
  : Value(ptr),
1113
1143
  Hashed(*ptr)
1114
1144
  { concrete_type(MAP); }
1115
- std::string type() { return "map"; }
1145
+ std::string type() const { return "map"; }
1116
1146
  static std::string type_name() { return "map"; }
1117
1147
  bool is_invisible() const { return empty(); }
1118
- List_Obj to_list(Context& ctx, ParserState& pstate);
1148
+ List_Obj to_list(ParserState& pstate);
1119
1149
 
1120
1150
  virtual size_t hash()
1121
1151
  {
@@ -1137,22 +1167,43 @@ namespace Sass {
1137
1167
 
1138
1168
  inline static const std::string sass_op_to_name(enum Sass_OP op) {
1139
1169
  switch (op) {
1140
- case AND: return "and"; break;
1141
- case OR: return "or"; break;
1142
- case EQ: return "eq"; break;
1143
- case NEQ: return "neq"; break;
1144
- case GT: return "gt"; break;
1145
- case GTE: return "gte"; break;
1146
- case LT: return "lt"; break;
1147
- case LTE: return "lte"; break;
1148
- case ADD: return "plus"; break;
1149
- case SUB: return "sub"; break;
1150
- case MUL: return "times"; break;
1151
- case DIV: return "div"; break;
1152
- case MOD: return "mod"; break;
1170
+ case AND: return "and";
1171
+ case OR: return "or";
1172
+ case EQ: return "eq";
1173
+ case NEQ: return "neq";
1174
+ case GT: return "gt";
1175
+ case GTE: return "gte";
1176
+ case LT: return "lt";
1177
+ case LTE: return "lte";
1178
+ case ADD: return "plus";
1179
+ case SUB: return "sub";
1180
+ case MUL: return "times";
1181
+ case DIV: return "div";
1182
+ case MOD: return "mod";
1183
+ // this is only used internally!
1184
+ case NUM_OPS: return "[OPS]";
1185
+ default: return "invalid";
1186
+ }
1187
+ }
1188
+
1189
+ inline static const std::string sass_op_separator(enum Sass_OP op) {
1190
+ switch (op) {
1191
+ case AND: return "&&";
1192
+ case OR: return "||";
1193
+ case EQ: return "==";
1194
+ case NEQ: return "!=";
1195
+ case GT: return ">";
1196
+ case GTE: return ">=";
1197
+ case LT: return "<";
1198
+ case LTE: return "<=";
1199
+ case ADD: return "+";
1200
+ case SUB: return "-";
1201
+ case MUL: return "*";
1202
+ case DIV: return "/";
1203
+ case MOD: return "%";
1153
1204
  // this is only used internally!
1154
- case NUM_OPS: return "[OPS]"; break;
1155
- default: return "invalid"; break;
1205
+ case NUM_OPS: return "[OPS]";
1206
+ default: return "invalid";
1156
1207
  }
1157
1208
  }
1158
1209
 
@@ -1163,9 +1214,9 @@ namespace Sass {
1163
1214
  //////////////////////////////////////////////////////////////////////////
1164
1215
  class Binary_Expression : public PreValue {
1165
1216
  private:
1166
- ADD_HASHED(Operand, op)
1167
- ADD_HASHED(Expression_Obj, left)
1168
- ADD_HASHED(Expression_Obj, right)
1217
+ HASH_PROPERTY(Operand, op)
1218
+ HASH_PROPERTY(Expression_Obj, left)
1219
+ HASH_PROPERTY(Expression_Obj, right)
1169
1220
  size_t hash_;
1170
1221
  public:
1171
1222
  Binary_Expression(ParserState pstate,
@@ -1180,44 +1231,10 @@ namespace Sass {
1180
1231
  hash_(ptr->hash_)
1181
1232
  { }
1182
1233
  const std::string type_name() {
1183
- switch (type()) {
1184
- case AND: return "and"; break;
1185
- case OR: return "or"; break;
1186
- case EQ: return "eq"; break;
1187
- case NEQ: return "neq"; break;
1188
- case GT: return "gt"; break;
1189
- case GTE: return "gte"; break;
1190
- case LT: return "lt"; break;
1191
- case LTE: return "lte"; break;
1192
- case ADD: return "add"; break;
1193
- case SUB: return "sub"; break;
1194
- case MUL: return "mul"; break;
1195
- case DIV: return "div"; break;
1196
- case MOD: return "mod"; break;
1197
- // this is only used internally!
1198
- case NUM_OPS: return "[OPS]"; break;
1199
- default: return "invalid"; break;
1200
- }
1234
+ return sass_op_to_name(optype());
1201
1235
  }
1202
1236
  const std::string separator() {
1203
- switch (type()) {
1204
- case AND: return "&&"; break;
1205
- case OR: return "||"; break;
1206
- case EQ: return "=="; break;
1207
- case NEQ: return "!="; break;
1208
- case GT: return ">"; break;
1209
- case GTE: return ">="; break;
1210
- case LT: return "<"; break;
1211
- case LTE: return "<="; break;
1212
- case ADD: return "+"; break;
1213
- case SUB: return "-"; break;
1214
- case MUL: return "*"; break;
1215
- case DIV: return "/"; break;
1216
- case MOD: return "%"; break;
1217
- // this is only used internally!
1218
- case NUM_OPS: return "[OPS]"; break;
1219
- default: return "invalid"; break;
1220
- }
1237
+ return sass_op_separator(optype());
1221
1238
  }
1222
1239
  bool is_left_interpolant(void) const;
1223
1240
  bool is_right_interpolant(void) const;
@@ -1236,11 +1253,11 @@ namespace Sass {
1236
1253
  {
1237
1254
  try
1238
1255
  {
1239
- Binary_Expression_Ptr_Const m = dynamic_cast<Binary_Expression_Ptr_Const>(&rhs);
1256
+ Binary_Expression_Ptr_Const m = Cast<Binary_Expression>(&rhs);
1240
1257
  if (m == 0) return false;
1241
1258
  return type() == m->type() &&
1242
- left() == m->left() &&
1243
- right() == m->right();
1259
+ *left() == *m->left() &&
1260
+ *right() == *m->right();
1244
1261
  }
1245
1262
  catch (std::bad_cast&)
1246
1263
  {
@@ -1251,13 +1268,13 @@ namespace Sass {
1251
1268
  virtual size_t hash()
1252
1269
  {
1253
1270
  if (hash_ == 0) {
1254
- hash_ = std::hash<size_t>()(type());
1271
+ hash_ = std::hash<size_t>()(optype());
1255
1272
  hash_combine(hash_, left()->hash());
1256
1273
  hash_combine(hash_, right()->hash());
1257
1274
  }
1258
1275
  return hash_;
1259
1276
  }
1260
- enum Sass_OP type() const { return op_.operand; }
1277
+ enum Sass_OP optype() const { return op_.operand; }
1261
1278
  ATTACH_AST_OPERATIONS(Binary_Expression)
1262
1279
  ATTACH_OPERATIONS()
1263
1280
  };
@@ -1267,37 +1284,38 @@ namespace Sass {
1267
1284
  ////////////////////////////////////////////////////////////////////////////
1268
1285
  class Unary_Expression : public Expression {
1269
1286
  public:
1270
- enum Type { PLUS, MINUS, NOT };
1287
+ enum Type { PLUS, MINUS, NOT, SLASH };
1271
1288
  private:
1272
- ADD_HASHED(Type, type)
1273
- ADD_HASHED(Expression_Obj, operand)
1289
+ HASH_PROPERTY(Type, optype)
1290
+ HASH_PROPERTY(Expression_Obj, operand)
1274
1291
  size_t hash_;
1275
1292
  public:
1276
1293
  Unary_Expression(ParserState pstate, Type t, Expression_Obj o)
1277
- : Expression(pstate), type_(t), operand_(o), hash_(0)
1294
+ : Expression(pstate), optype_(t), operand_(o), hash_(0)
1278
1295
  { }
1279
1296
  Unary_Expression(const Unary_Expression* ptr)
1280
1297
  : Expression(ptr),
1281
- type_(ptr->type_),
1298
+ optype_(ptr->optype_),
1282
1299
  operand_(ptr->operand_),
1283
1300
  hash_(ptr->hash_)
1284
1301
  { }
1285
1302
  const std::string type_name() {
1286
- switch (type_) {
1287
- case PLUS: return "plus"; break;
1288
- case MINUS: return "minus"; break;
1289
- case NOT: return "not"; break;
1290
- default: return "invalid"; break;
1303
+ switch (optype_) {
1304
+ case PLUS: return "plus";
1305
+ case MINUS: return "minus";
1306
+ case SLASH: return "slash";
1307
+ case NOT: return "not";
1308
+ default: return "invalid";
1291
1309
  }
1292
1310
  }
1293
1311
  virtual bool operator==(const Expression& rhs) const
1294
1312
  {
1295
1313
  try
1296
1314
  {
1297
- Unary_Expression_Ptr_Const m = dynamic_cast<Unary_Expression_Ptr_Const>(&rhs);
1315
+ Unary_Expression_Ptr_Const m = Cast<Unary_Expression>(&rhs);
1298
1316
  if (m == 0) return false;
1299
1317
  return type() == m->type() &&
1300
- operand() == m->operand();
1318
+ *operand() == *m->operand();
1301
1319
  }
1302
1320
  catch (std::bad_cast&)
1303
1321
  {
@@ -1308,7 +1326,7 @@ namespace Sass {
1308
1326
  virtual size_t hash()
1309
1327
  {
1310
1328
  if (hash_ == 0) {
1311
- hash_ = std::hash<size_t>()(type_);
1329
+ hash_ = std::hash<size_t>()(optype_);
1312
1330
  hash_combine(hash_, operand()->hash());
1313
1331
  };
1314
1332
  return hash_;
@@ -1321,8 +1339,8 @@ namespace Sass {
1321
1339
  // Individual argument objects for mixin and function calls.
1322
1340
  ////////////////////////////////////////////////////////////
1323
1341
  class Argument : public Expression {
1324
- ADD_HASHED(Expression_Obj, value)
1325
- ADD_HASHED(std::string, name)
1342
+ HASH_PROPERTY(Expression_Obj, value)
1343
+ HASH_CONSTREF(std::string, name)
1326
1344
  ADD_PROPERTY(bool, is_rest_argument)
1327
1345
  ADD_PROPERTY(bool, is_keyword_argument)
1328
1346
  size_t hash_;
@@ -1331,7 +1349,7 @@ namespace Sass {
1331
1349
  : Expression(pstate), value_(val), name_(n), is_rest_argument_(rest), is_keyword_argument_(keyword), hash_(0)
1332
1350
  {
1333
1351
  if (!name_.empty() && is_rest_argument_) {
1334
- error("variable-length argument may not be passed by name", pstate_);
1352
+ coreError("variable-length argument may not be passed by name", pstate_);
1335
1353
  }
1336
1354
  }
1337
1355
  Argument(const Argument* ptr)
@@ -1343,7 +1361,7 @@ namespace Sass {
1343
1361
  hash_(ptr->hash_)
1344
1362
  {
1345
1363
  if (!name_.empty() && is_rest_argument_) {
1346
- error("variable-length argument may not be passed by name", pstate_);
1364
+ coreError("variable-length argument may not be passed by name", pstate_);
1347
1365
  }
1348
1366
  }
1349
1367
 
@@ -1352,7 +1370,7 @@ namespace Sass {
1352
1370
  {
1353
1371
  try
1354
1372
  {
1355
- Argument_Ptr_Const m = dynamic_cast<Argument_Ptr_Const>(&rhs);
1373
+ Argument_Ptr_Const m = Cast<Argument>(&rhs);
1356
1374
  if (!(m && name() == m->name())) return false;
1357
1375
  return *value() == *m->value();
1358
1376
  }
@@ -1412,18 +1430,54 @@ namespace Sass {
1412
1430
  ATTACH_OPERATIONS()
1413
1431
  };
1414
1432
 
1433
+ ////////////////////////////////////////////////////
1434
+ // Function reference.
1435
+ ////////////////////////////////////////////////////
1436
+ class Function : public Value {
1437
+ public:
1438
+ ADD_PROPERTY(Definition_Obj, definition)
1439
+ ADD_PROPERTY(bool, is_css)
1440
+ public:
1441
+ Function(ParserState pstate, Definition_Obj def, bool css)
1442
+ : Value(pstate), definition_(def), is_css_(css)
1443
+ { concrete_type(FUNCTION_VAL); }
1444
+ Function(const Function* ptr)
1445
+ : Value(ptr), definition_(ptr->definition_), is_css_(ptr->is_css_)
1446
+ { concrete_type(FUNCTION_VAL); }
1447
+
1448
+ std::string type() const { return "function"; }
1449
+ static std::string type_name() { return "function"; }
1450
+ bool is_invisible() const { return true; }
1451
+
1452
+ std::string name() {
1453
+ if (definition_) {
1454
+ return definition_->name();
1455
+ }
1456
+ return "";
1457
+ }
1458
+
1459
+ virtual bool operator== (const Expression& rhs) const;
1460
+
1461
+ ATTACH_AST_OPERATIONS(Function)
1462
+ ATTACH_OPERATIONS()
1463
+ };
1464
+
1415
1465
  //////////////////
1416
1466
  // Function calls.
1417
1467
  //////////////////
1418
1468
  class Function_Call : public PreValue {
1419
- ADD_HASHED(std::string, name)
1420
- ADD_HASHED(Arguments_Obj, arguments)
1469
+ HASH_CONSTREF(std::string, name)
1470
+ HASH_PROPERTY(Arguments_Obj, arguments)
1471
+ HASH_PROPERTY(Function_Obj, func)
1421
1472
  ADD_PROPERTY(bool, via_call)
1422
1473
  ADD_PROPERTY(void*, cookie)
1423
1474
  size_t hash_;
1424
1475
  public:
1425
1476
  Function_Call(ParserState pstate, std::string n, Arguments_Obj args, void* cookie)
1426
- : PreValue(pstate), name_(n), arguments_(args), via_call_(false), cookie_(cookie), hash_(0)
1477
+ : PreValue(pstate), name_(n), arguments_(args), func_(0), via_call_(false), cookie_(cookie), hash_(0)
1478
+ { concrete_type(FUNCTION); }
1479
+ Function_Call(ParserState pstate, std::string n, Arguments_Obj args, Function_Obj func)
1480
+ : PreValue(pstate), name_(n), arguments_(args), func_(func), via_call_(false), cookie_(0), hash_(0)
1427
1481
  { concrete_type(FUNCTION); }
1428
1482
  Function_Call(ParserState pstate, std::string n, Arguments_Obj args)
1429
1483
  : PreValue(pstate), name_(n), arguments_(args), via_call_(false), cookie_(0), hash_(0)
@@ -1432,20 +1486,26 @@ namespace Sass {
1432
1486
  : PreValue(ptr),
1433
1487
  name_(ptr->name_),
1434
1488
  arguments_(ptr->arguments_),
1489
+ func_(ptr->func_),
1435
1490
  via_call_(ptr->via_call_),
1436
1491
  cookie_(ptr->cookie_),
1437
1492
  hash_(ptr->hash_)
1438
1493
  { concrete_type(FUNCTION); }
1439
1494
 
1495
+ bool is_css() {
1496
+ if (func_) return func_->is_css();
1497
+ return false;
1498
+ }
1499
+
1440
1500
  virtual bool operator==(const Expression& rhs) const
1441
1501
  {
1442
1502
  try
1443
1503
  {
1444
- Function_Call_Ptr_Const m = dynamic_cast<Function_Call_Ptr_Const>(&rhs);
1504
+ Function_Call_Ptr_Const m = Cast<Function_Call>(&rhs);
1445
1505
  if (!(m && name() == m->name())) return false;
1446
1506
  if (!(m && arguments()->length() == m->arguments()->length())) return false;
1447
1507
  for (size_t i =0, L = arguments()->length(); i < L; ++i)
1448
- if (!((*arguments())[i] == (*m->arguments())[i])) return false;
1508
+ if (!(*(*arguments())[i] == *(*m->arguments())[i])) return false;
1449
1509
  return true;
1450
1510
  }
1451
1511
  catch (std::bad_cast&)
@@ -1491,20 +1551,20 @@ namespace Sass {
1491
1551
  // Variable references.
1492
1552
  ///////////////////////
1493
1553
  class Variable : public PreValue {
1494
- ADD_PROPERTY(std::string, name)
1554
+ ADD_CONSTREF(std::string, name)
1495
1555
  public:
1496
1556
  Variable(ParserState pstate, std::string n)
1497
1557
  : PreValue(pstate), name_(n)
1498
- { }
1558
+ { concrete_type(VARIABLE); }
1499
1559
  Variable(const Variable* ptr)
1500
1560
  : PreValue(ptr), name_(ptr->name_)
1501
- { }
1561
+ { concrete_type(VARIABLE); }
1502
1562
 
1503
1563
  virtual bool operator==(const Expression& rhs) const
1504
1564
  {
1505
1565
  try
1506
1566
  {
1507
- Variable_Ptr_Const e = dynamic_cast<Variable_Ptr_Const>(&rhs);
1567
+ Variable_Ptr_Const e = Cast<Variable>(&rhs);
1508
1568
  return e && name() == e->name();
1509
1569
  }
1510
1570
  catch (std::bad_cast&)
@@ -1523,108 +1583,45 @@ namespace Sass {
1523
1583
  ATTACH_OPERATIONS()
1524
1584
  };
1525
1585
 
1526
- ////////////////////////////////////////////////////////////////////////////
1527
- // Textual (i.e., unevaluated) numeric data. Variants are distinguished with
1528
- // a type tag.
1529
- ////////////////////////////////////////////////////////////////////////////
1530
- class Textual : public Expression {
1531
- public:
1532
- enum Type { NUMBER, PERCENTAGE, DIMENSION, HEX };
1533
- private:
1534
- ADD_HASHED(Type, type)
1535
- ADD_HASHED(std::string, value)
1536
- size_t hash_;
1537
- public:
1538
- Textual(ParserState pstate, Type t, std::string val)
1539
- : Expression(pstate, DELAYED), type_(t), value_(val),
1540
- hash_(0)
1541
- { }
1542
- Textual(const Textual* ptr)
1543
- : Expression(ptr),
1544
- type_(ptr->type_),
1545
- value_(ptr->value_),
1546
- hash_(ptr->hash_)
1547
- { }
1548
-
1549
- virtual bool operator==(const Expression& rhs) const
1550
- {
1551
- try
1552
- {
1553
- Textual_Ptr_Const e = dynamic_cast<Textual_Ptr_Const>(&rhs);
1554
- return e && value() == e->value() && type() == e->type();
1555
- }
1556
- catch (std::bad_cast&)
1557
- {
1558
- return false;
1559
- }
1560
- catch (...) { throw; }
1561
- }
1562
-
1563
- virtual size_t hash()
1564
- {
1565
- if (hash_ == 0) {
1566
- hash_ = std::hash<std::string>()(value_);
1567
- hash_combine(hash_, std::hash<int>()(type_));
1568
- }
1569
- return hash_;
1570
- }
1571
-
1572
- ATTACH_AST_OPERATIONS(Textual)
1573
- ATTACH_OPERATIONS()
1574
- };
1575
-
1576
1586
  ////////////////////////////////////////////////
1577
1587
  // Numbers, percentages, dimensions, and colors.
1578
1588
  ////////////////////////////////////////////////
1579
- class Number : public Value {
1580
- ADD_HASHED(double, value)
1589
+ class Number : public Value, public Units {
1590
+ HASH_PROPERTY(double, value)
1581
1591
  ADD_PROPERTY(bool, zero)
1582
- std::vector<std::string> numerator_units_;
1583
- std::vector<std::string> denominator_units_;
1584
1592
  size_t hash_;
1585
1593
  public:
1586
1594
  Number(ParserState pstate, double val, std::string u = "", bool zero = true);
1587
1595
 
1588
1596
  Number(const Number* ptr)
1589
1597
  : Value(ptr),
1598
+ Units(ptr),
1590
1599
  value_(ptr->value_), zero_(ptr->zero_),
1591
- numerator_units_(ptr->numerator_units_),
1592
- denominator_units_(ptr->denominator_units_),
1593
1600
  hash_(ptr->hash_)
1594
1601
  { concrete_type(NUMBER); }
1595
1602
 
1596
1603
  bool zero() { return zero_; }
1597
- bool is_valid_css_unit() const;
1598
- std::vector<std::string>& numerator_units() { return numerator_units_; }
1599
- std::vector<std::string>& denominator_units() { return denominator_units_; }
1600
- const std::vector<std::string>& numerator_units() const { return numerator_units_; }
1601
- const std::vector<std::string>& denominator_units() const { return denominator_units_; }
1602
- std::string type() { return "number"; }
1604
+ std::string type() const { return "number"; }
1603
1605
  static std::string type_name() { return "number"; }
1604
- std::string unit() const;
1605
1606
 
1606
- bool is_unitless() const;
1607
- double convert_factor(const Number&) const;
1608
- bool convert(const std::string& unit = "", bool strict = false);
1609
- void normalize(const std::string& unit = "", bool strict = false);
1610
- // useful for making one number compatible with another
1611
- std::string find_convertible_unit() const;
1607
+ void reduce();
1608
+ void normalize();
1612
1609
 
1613
1610
  virtual size_t hash()
1614
1611
  {
1615
1612
  if (hash_ == 0) {
1616
1613
  hash_ = std::hash<double>()(value_);
1617
- for (const auto numerator : numerator_units())
1614
+ for (const auto numerator : numerators)
1618
1615
  hash_combine(hash_, std::hash<std::string>()(numerator));
1619
- for (const auto denominator : denominator_units())
1616
+ for (const auto denominator : denominators)
1620
1617
  hash_combine(hash_, std::hash<std::string>()(denominator));
1621
1618
  }
1622
1619
  return hash_;
1623
1620
  }
1624
1621
 
1625
1622
  virtual bool operator< (const Number& rhs) const;
1623
+ virtual bool operator== (const Number& rhs) const;
1626
1624
  virtual bool operator== (const Expression& rhs) const;
1627
- virtual bool eq(const Expression& rhs) const;
1628
1625
  ATTACH_AST_OPERATIONS(Number)
1629
1626
  ATTACH_OPERATIONS()
1630
1627
  };
@@ -1633,11 +1630,11 @@ namespace Sass {
1633
1630
  // Colors.
1634
1631
  //////////
1635
1632
  class Color : public Value {
1636
- ADD_HASHED(double, r)
1637
- ADD_HASHED(double, g)
1638
- ADD_HASHED(double, b)
1639
- ADD_HASHED(double, a)
1640
- ADD_PROPERTY(std::string, disp)
1633
+ HASH_PROPERTY(double, r)
1634
+ HASH_PROPERTY(double, g)
1635
+ HASH_PROPERTY(double, b)
1636
+ HASH_PROPERTY(double, a)
1637
+ ADD_CONSTREF(std::string, disp)
1641
1638
  size_t hash_;
1642
1639
  public:
1643
1640
  Color(ParserState pstate, double r, double g, double b, double a = 1, const std::string disp = "")
@@ -1653,7 +1650,7 @@ namespace Sass {
1653
1650
  disp_(ptr->disp_),
1654
1651
  hash_(ptr->hash_)
1655
1652
  { concrete_type(COLOR); }
1656
- std::string type() { return "color"; }
1653
+ std::string type() const { return "color"; }
1657
1654
  static std::string type_name() { return "color"; }
1658
1655
 
1659
1656
  virtual size_t hash()
@@ -1677,7 +1674,7 @@ namespace Sass {
1677
1674
  // Errors from Sass_Values.
1678
1675
  //////////////////////////////
1679
1676
  class Custom_Error : public Value {
1680
- ADD_PROPERTY(std::string, message)
1677
+ ADD_CONSTREF(std::string, message)
1681
1678
  public:
1682
1679
  Custom_Error(ParserState pstate, std::string msg)
1683
1680
  : Value(pstate), message_(msg)
@@ -1694,7 +1691,7 @@ namespace Sass {
1694
1691
  // Warnings from Sass_Values.
1695
1692
  //////////////////////////////
1696
1693
  class Custom_Warning : public Value {
1697
- ADD_PROPERTY(std::string, message)
1694
+ ADD_CONSTREF(std::string, message)
1698
1695
  public:
1699
1696
  Custom_Warning(ParserState pstate, std::string msg)
1700
1697
  : Value(pstate), message_(msg)
@@ -1711,7 +1708,7 @@ namespace Sass {
1711
1708
  // Booleans.
1712
1709
  ////////////
1713
1710
  class Boolean : public Value {
1714
- ADD_HASHED(bool, value)
1711
+ HASH_PROPERTY(bool, value)
1715
1712
  size_t hash_;
1716
1713
  public:
1717
1714
  Boolean(ParserState pstate, bool val)
@@ -1724,7 +1721,7 @@ namespace Sass {
1724
1721
  hash_(ptr->hash_)
1725
1722
  { concrete_type(BOOLEAN); }
1726
1723
  virtual operator bool() { return value_; }
1727
- std::string type() { return "bool"; }
1724
+ std::string type() const { return "bool"; }
1728
1725
  static std::string type_name() { return "bool"; }
1729
1726
  virtual bool is_false() { return !value_; }
1730
1727
 
@@ -1757,8 +1754,6 @@ namespace Sass {
1757
1754
  static std::string type_name() { return "string"; }
1758
1755
  virtual ~String() = 0;
1759
1756
  virtual void rtrim() = 0;
1760
- virtual void ltrim() = 0;
1761
- virtual void trim() = 0;
1762
1757
  virtual bool operator==(const Expression& rhs) const = 0;
1763
1758
  virtual bool operator<(const Expression& rhs) const {
1764
1759
  return this->to_string() < rhs.to_string();
@@ -1773,19 +1768,20 @@ namespace Sass {
1773
1768
  // evaluation phase.
1774
1769
  ///////////////////////////////////////////////////////////////////////
1775
1770
  class String_Schema : public String, public Vectorized<Expression_Obj> {
1776
- // ADD_PROPERTY(bool, has_interpolants)
1771
+ ADD_PROPERTY(bool, css)
1777
1772
  size_t hash_;
1778
1773
  public:
1779
- String_Schema(ParserState pstate, size_t size = 0, bool has_interpolants = false)
1780
- : String(pstate), Vectorized<Expression_Obj>(size), hash_(0)
1774
+ String_Schema(ParserState pstate, size_t size = 0, bool css = true)
1775
+ : String(pstate), Vectorized<Expression_Obj>(size), css_(css), hash_(0)
1781
1776
  { concrete_type(STRING); }
1782
1777
  String_Schema(const String_Schema* ptr)
1783
1778
  : String(ptr),
1784
1779
  Vectorized<Expression_Obj>(*ptr),
1780
+ css_(ptr->css_),
1785
1781
  hash_(ptr->hash_)
1786
1782
  { concrete_type(STRING); }
1787
1783
 
1788
- std::string type() { return "string"; }
1784
+ std::string type() const { return "string"; }
1789
1785
  static std::string type_name() { return "string"; }
1790
1786
 
1791
1787
  bool is_left_interpolant(void) const;
@@ -1798,8 +1794,6 @@ namespace Sass {
1798
1794
  return false;
1799
1795
  }
1800
1796
  virtual void rtrim();
1801
- virtual void ltrim();
1802
- virtual void trim();
1803
1797
 
1804
1798
  virtual size_t hash()
1805
1799
  {
@@ -1825,7 +1819,7 @@ namespace Sass {
1825
1819
  class String_Constant : public String {
1826
1820
  ADD_PROPERTY(char, quote_mark)
1827
1821
  ADD_PROPERTY(bool, can_compress_whitespace)
1828
- ADD_HASHED(std::string, value)
1822
+ HASH_CONSTREF(std::string, value)
1829
1823
  protected:
1830
1824
  size_t hash_;
1831
1825
  public:
@@ -1836,24 +1830,22 @@ namespace Sass {
1836
1830
  value_(ptr->value_),
1837
1831
  hash_(ptr->hash_)
1838
1832
  { }
1839
- String_Constant(ParserState pstate, std::string val)
1840
- : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(val)), hash_(0)
1833
+ String_Constant(ParserState pstate, std::string val, bool css = true)
1834
+ : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(val, css)), hash_(0)
1841
1835
  { }
1842
- String_Constant(ParserState pstate, const char* beg)
1843
- : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg))), hash_(0)
1836
+ String_Constant(ParserState pstate, const char* beg, bool css = true)
1837
+ : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg), css)), hash_(0)
1844
1838
  { }
1845
- String_Constant(ParserState pstate, const char* beg, const char* end)
1846
- : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg, end-beg))), hash_(0)
1839
+ String_Constant(ParserState pstate, const char* beg, const char* end, bool css = true)
1840
+ : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg, end-beg), css)), hash_(0)
1847
1841
  { }
1848
- String_Constant(ParserState pstate, const Token& tok)
1849
- : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(tok.begin, tok.end))), hash_(0)
1842
+ String_Constant(ParserState pstate, const Token& tok, bool css = true)
1843
+ : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(tok.begin, tok.end), css)), hash_(0)
1850
1844
  { }
1851
- std::string type() { return "string"; }
1845
+ std::string type() const { return "string"; }
1852
1846
  static std::string type_name() { return "string"; }
1853
1847
  virtual bool is_invisible() const;
1854
1848
  virtual void rtrim();
1855
- virtual void ltrim();
1856
- virtual void trim();
1857
1849
 
1858
1850
  virtual size_t hash()
1859
1851
  {
@@ -1881,8 +1873,8 @@ namespace Sass {
1881
1873
  public:
1882
1874
  String_Quoted(ParserState pstate, std::string val, char q = 0,
1883
1875
  bool keep_utf8_escapes = false, bool skip_unquoting = false,
1884
- bool strict_unquoting = true)
1885
- : String_Constant(pstate, val)
1876
+ bool strict_unquoting = true, bool css = true)
1877
+ : String_Constant(pstate, val, css)
1886
1878
  {
1887
1879
  if (skip_unquoting == false) {
1888
1880
  value_ = unquote(value_, &quote_mark_, keep_utf8_escapes, strict_unquoting);
@@ -2103,7 +2095,7 @@ namespace Sass {
2103
2095
 
2104
2096
  if (s->statement_type() == Statement::DIRECTIVE)
2105
2097
  {
2106
- if (Directive_Obj dir = SASS_MEMORY_CAST(Directive, s))
2098
+ if (Directive_Obj dir = Cast<Directive>(s))
2107
2099
  {
2108
2100
  std::string keyword(dir->keyword());
2109
2101
  if (keyword.length() > 0) keyword.erase(0, 1);
@@ -2122,7 +2114,7 @@ namespace Sass {
2122
2114
  {
2123
2115
  return expression()->exclude("supports");
2124
2116
  }
2125
- if (Directive_Obj dir = SASS_MEMORY_CAST(Directive, s))
2117
+ if (Directive_Obj dir = Cast<Directive>(s))
2126
2118
  {
2127
2119
  if (dir->is_keyframes()) return expression()->exclude("keyframes");
2128
2120
  }
@@ -2139,7 +2131,7 @@ namespace Sass {
2139
2131
  public:
2140
2132
  Null(ParserState pstate) : Value(pstate) { concrete_type(NULL_VAL); }
2141
2133
  Null(const Null* ptr) : Value(ptr) { concrete_type(NULL_VAL); }
2142
- std::string type() { return "null"; }
2134
+ std::string type() const { return "null"; }
2143
2135
  static std::string type_name() { return "null"; }
2144
2136
  bool is_invisible() const { return true; }
2145
2137
  operator bool() { return false; }
@@ -2172,7 +2164,7 @@ namespace Sass {
2172
2164
  // Individual parameter objects for mixins and functions.
2173
2165
  /////////////////////////////////////////////////////////
2174
2166
  class Parameter : public AST_Node {
2175
- ADD_PROPERTY(std::string, name)
2167
+ ADD_CONSTREF(std::string, name)
2176
2168
  ADD_PROPERTY(Expression_Obj, default_value)
2177
2169
  ADD_PROPERTY(bool, is_rest_parameter)
2178
2170
  public:
@@ -2180,9 +2172,11 @@ namespace Sass {
2180
2172
  std::string n, Expression_Obj def = 0, bool rest = false)
2181
2173
  : AST_Node(pstate), name_(n), default_value_(def), is_rest_parameter_(rest)
2182
2174
  {
2183
- if (default_value_ && is_rest_parameter_) {
2184
- error("variable-length parameter may not have a default value", pstate_);
2185
- }
2175
+ // tried to come up with a spec test for this, but it does no longer
2176
+ // get past the parser (it error out earlier). A spec test was added!
2177
+ // if (default_value_ && is_rest_parameter_) {
2178
+ // error("variable-length parameter may not have a default value", pstate_);
2179
+ // }
2186
2180
  }
2187
2181
  Parameter(const Parameter* ptr)
2188
2182
  : AST_Node(ptr),
@@ -2190,9 +2184,11 @@ namespace Sass {
2190
2184
  default_value_(ptr->default_value_),
2191
2185
  is_rest_parameter_(ptr->is_rest_parameter_)
2192
2186
  {
2193
- if (default_value_ && is_rest_parameter_) {
2194
- error("variable-length parameter may not have a default value", pstate_);
2195
- }
2187
+ // tried to come up with a spec test for this, but it does no longer
2188
+ // get past the parser (it error out earlier). A spec test was added!
2189
+ // if (default_value_ && is_rest_parameter_) {
2190
+ // error("variable-length parameter may not have a default value", pstate_);
2191
+ // }
2196
2192
  }
2197
2193
  ATTACH_AST_OPERATIONS(Parameter)
2198
2194
  ATTACH_OPERATIONS()
@@ -2210,23 +2206,23 @@ namespace Sass {
2210
2206
  void adjust_after_pushing(Parameter_Obj p)
2211
2207
  {
2212
2208
  if (p->default_value()) {
2213
- if (has_rest_parameter_) {
2214
- error("optional parameters may not be combined with variable-length parameters", p->pstate());
2209
+ if (has_rest_parameter()) {
2210
+ coreError("optional parameters may not be combined with variable-length parameters", p->pstate());
2215
2211
  }
2216
- has_optional_parameters_ = true;
2212
+ has_optional_parameters(true);
2217
2213
  }
2218
2214
  else if (p->is_rest_parameter()) {
2219
- if (has_rest_parameter_) {
2220
- error("functions and mixins cannot have more than one variable-length parameter", p->pstate());
2215
+ if (has_rest_parameter()) {
2216
+ coreError("functions and mixins cannot have more than one variable-length parameter", p->pstate());
2221
2217
  }
2222
- has_rest_parameter_ = true;
2218
+ has_rest_parameter(true);
2223
2219
  }
2224
2220
  else {
2225
- if (has_rest_parameter_) {
2226
- error("required parameters must precede variable-length parameters", p->pstate());
2221
+ if (has_rest_parameter()) {
2222
+ coreError("required parameters must precede variable-length parameters", p->pstate());
2227
2223
  }
2228
- if (has_optional_parameters_) {
2229
- error("required parameters must precede optional parameters", p->pstate());
2224
+ if (has_optional_parameters()) {
2225
+ coreError("required parameters must precede optional parameters", p->pstate());
2230
2226
  }
2231
2227
  }
2232
2228
  }
@@ -2266,9 +2262,8 @@ namespace Sass {
2266
2262
  protected:
2267
2263
  size_t hash_;
2268
2264
  public:
2269
- Selector(ParserState pstate, bool r = false, bool h = false)
2265
+ Selector(ParserState pstate)
2270
2266
  : Expression(pstate),
2271
- // has_reference_(r),
2272
2267
  has_line_feed_(false),
2273
2268
  has_line_break_(false),
2274
2269
  is_optional_(false),
@@ -2286,21 +2281,19 @@ namespace Sass {
2286
2281
  { concrete_type(SELECTOR); }
2287
2282
  virtual ~Selector() = 0;
2288
2283
  virtual size_t hash() = 0;
2289
- virtual unsigned long specificity() {
2290
- return 0;
2291
- }
2284
+ virtual unsigned long specificity() const = 0;
2292
2285
  virtual void set_media_block(Media_Block_Ptr mb) {
2293
2286
  media_block(mb);
2294
2287
  }
2295
- virtual bool has_parent_ref() {
2288
+ virtual bool has_parent_ref() const {
2296
2289
  return false;
2297
2290
  }
2298
- virtual bool has_real_parent_ref() {
2291
+ virtual bool has_real_parent_ref() const {
2299
2292
  return false;
2300
2293
  }
2301
2294
  // dispatch to correct handlers
2302
- virtual bool operator<(const Selector& rhs) const;
2303
- virtual bool operator==(const Selector& rhs) const;
2295
+ virtual bool operator<(const Selector& rhs) const = 0;
2296
+ virtual bool operator==(const Selector& rhs) const = 0;
2304
2297
  ATTACH_VIRTUAL_AST_OPERATIONS(Selector);
2305
2298
  };
2306
2299
  inline Selector::~Selector() { }
@@ -2309,20 +2302,36 @@ namespace Sass {
2309
2302
  // Interpolated selectors -- the interpolated String will be expanded and
2310
2303
  // re-parsed into a normal selector class.
2311
2304
  /////////////////////////////////////////////////////////////////////////
2312
- class Selector_Schema : public Selector {
2305
+ class Selector_Schema : public AST_Node {
2313
2306
  ADD_PROPERTY(String_Obj, contents)
2314
- ADD_PROPERTY(bool, at_root);
2307
+ ADD_PROPERTY(bool, connect_parent);
2308
+ // must not be a reference counted object
2309
+ // otherwise we create circular references
2310
+ ADD_PROPERTY(Media_Block_Ptr, media_block)
2311
+ // store computed hash
2312
+ size_t hash_;
2315
2313
  public:
2316
2314
  Selector_Schema(ParserState pstate, String_Obj c)
2317
- : Selector(pstate), contents_(c), at_root_(false)
2315
+ : AST_Node(pstate),
2316
+ contents_(c),
2317
+ connect_parent_(true),
2318
+ media_block_(NULL),
2319
+ hash_(0)
2318
2320
  { }
2319
2321
  Selector_Schema(const Selector_Schema* ptr)
2320
- : Selector(ptr),
2322
+ : AST_Node(ptr),
2321
2323
  contents_(ptr->contents_),
2322
- at_root_(ptr->at_root_)
2324
+ connect_parent_(ptr->connect_parent_),
2325
+ media_block_(ptr->media_block_),
2326
+ hash_(ptr->hash_)
2323
2327
  { }
2324
- virtual bool has_parent_ref();
2325
- virtual bool has_real_parent_ref();
2328
+ virtual bool has_parent_ref() const;
2329
+ virtual bool has_real_parent_ref() const;
2330
+ virtual bool operator<(const Selector& rhs) const;
2331
+ virtual bool operator==(const Selector& rhs) const;
2332
+ // selector schema is not yet a final selector, so we do not
2333
+ // have a specificity for it yet. We need to
2334
+ virtual unsigned long specificity() const { return 0; }
2326
2335
  virtual size_t hash() {
2327
2336
  if (hash_ == 0) {
2328
2337
  hash_combine(hash_, contents_->hash());
@@ -2337,8 +2346,8 @@ namespace Sass {
2337
2346
  // Abstract base class for simple selectors.
2338
2347
  ////////////////////////////////////////////
2339
2348
  class Simple_Selector : public Selector {
2340
- ADD_PROPERTY(std::string, ns)
2341
- ADD_PROPERTY(std::string, name)
2349
+ ADD_CONSTREF(std::string, ns)
2350
+ ADD_CONSTREF(std::string, name)
2342
2351
  ADD_PROPERTY(Simple_Type, simple_type)
2343
2352
  ADD_PROPERTY(bool, has_ns)
2344
2353
  public:
@@ -2360,10 +2369,6 @@ namespace Sass {
2360
2369
  name_(ptr->name_),
2361
2370
  has_ns_(ptr->has_ns_)
2362
2371
  { simple_type(SIMPLE); }
2363
- virtual bool unique() const
2364
- {
2365
- return false;
2366
- }
2367
2372
  virtual std::string ns_name() const
2368
2373
  {
2369
2374
  std::string name("");
@@ -2380,6 +2385,8 @@ namespace Sass {
2380
2385
  }
2381
2386
  return hash_;
2382
2387
  }
2388
+ // namespace compare functions
2389
+ bool is_ns_eq(const Simple_Selector& r) const;
2383
2390
  // namespace query functions
2384
2391
  bool is_universal_ns() const
2385
2392
  {
@@ -2412,11 +2419,10 @@ namespace Sass {
2412
2419
  }
2413
2420
 
2414
2421
  virtual ~Simple_Selector() = 0;
2415
- virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&);
2416
- virtual bool has_parent_ref() { return false; };
2417
- virtual bool has_real_parent_ref() { return false; };
2418
- virtual bool is_pseudo_element() { return false; }
2419
- virtual bool is_pseudo_class() { return false; }
2422
+ virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
2423
+ virtual bool has_parent_ref() const { return false; };
2424
+ virtual bool has_real_parent_ref() const { return false; };
2425
+ virtual bool is_pseudo_element() const { return false; }
2420
2426
 
2421
2427
  virtual bool is_superselector_of(Compound_Selector_Obj sub) { return false; }
2422
2428
 
@@ -2448,14 +2454,14 @@ namespace Sass {
2448
2454
  Parent_Selector(const Parent_Selector* ptr)
2449
2455
  : Simple_Selector(ptr), real_(ptr->real_)
2450
2456
  { /* has_reference(true); */ }
2451
- bool is_real_parent_ref() { return real(); };
2452
- virtual bool has_parent_ref() { return true; };
2453
- virtual bool has_real_parent_ref() { return is_real_parent_ref(); };
2454
- virtual unsigned long specificity()
2457
+ bool is_real_parent_ref() const { return real(); };
2458
+ virtual bool has_parent_ref() const { return true; };
2459
+ virtual bool has_real_parent_ref() const { return is_real_parent_ref(); };
2460
+ virtual unsigned long specificity() const
2455
2461
  {
2456
2462
  return 0;
2457
2463
  }
2458
- std::string type() { return "selector"; }
2464
+ std::string type() const { return "selector"; }
2459
2465
  static std::string type_name() { return "selector"; }
2460
2466
  ATTACH_AST_OPERATIONS(Parent_Selector)
2461
2467
  ATTACH_OPERATIONS()
@@ -2472,7 +2478,7 @@ namespace Sass {
2472
2478
  Placeholder_Selector(const Placeholder_Selector* ptr)
2473
2479
  : Simple_Selector(ptr)
2474
2480
  { }
2475
- virtual unsigned long specificity()
2481
+ virtual unsigned long specificity() const
2476
2482
  {
2477
2483
  return Constants::Specificity_Base;
2478
2484
  }
@@ -2495,13 +2501,17 @@ namespace Sass {
2495
2501
  Element_Selector(const Element_Selector* ptr)
2496
2502
  : Simple_Selector(ptr)
2497
2503
  { }
2498
- virtual unsigned long specificity()
2504
+ virtual unsigned long specificity() const
2499
2505
  {
2500
2506
  if (name() == "*") return 0;
2501
2507
  else return Constants::Specificity_Element;
2502
2508
  }
2503
- virtual Simple_Selector_Ptr unify_with(Simple_Selector_Ptr, Context&);
2504
- virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&);
2509
+ virtual Simple_Selector_Ptr unify_with(Simple_Selector_Ptr);
2510
+ virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
2511
+ virtual bool operator==(const Simple_Selector& rhs) const;
2512
+ virtual bool operator==(const Element_Selector& rhs) const;
2513
+ virtual bool operator<(const Simple_Selector& rhs) const;
2514
+ virtual bool operator<(const Element_Selector& rhs) const;
2505
2515
  ATTACH_AST_OPERATIONS(Element_Selector)
2506
2516
  ATTACH_OPERATIONS()
2507
2517
  };
@@ -2517,15 +2527,11 @@ namespace Sass {
2517
2527
  Class_Selector(const Class_Selector* ptr)
2518
2528
  : Simple_Selector(ptr)
2519
2529
  { }
2520
- virtual bool unique() const
2521
- {
2522
- return false;
2523
- }
2524
- virtual unsigned long specificity()
2530
+ virtual unsigned long specificity() const
2525
2531
  {
2526
2532
  return Constants::Specificity_Class;
2527
2533
  }
2528
- virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&);
2534
+ virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
2529
2535
  ATTACH_AST_OPERATIONS(Class_Selector)
2530
2536
  ATTACH_OPERATIONS()
2531
2537
  };
@@ -2541,15 +2547,11 @@ namespace Sass {
2541
2547
  Id_Selector(const Id_Selector* ptr)
2542
2548
  : Simple_Selector(ptr)
2543
2549
  { }
2544
- virtual bool unique() const
2545
- {
2546
- return true;
2547
- }
2548
- virtual unsigned long specificity()
2550
+ virtual unsigned long specificity() const
2549
2551
  {
2550
2552
  return Constants::Specificity_ID;
2551
2553
  }
2552
- virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&);
2554
+ virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
2553
2555
  ATTACH_AST_OPERATIONS(Id_Selector)
2554
2556
  ATTACH_OPERATIONS()
2555
2557
  };
@@ -2558,17 +2560,19 @@ namespace Sass {
2558
2560
  // Attribute selectors -- e.g., [src*=".jpg"], etc.
2559
2561
  ///////////////////////////////////////////////////
2560
2562
  class Attribute_Selector : public Simple_Selector {
2561
- ADD_PROPERTY(std::string, matcher)
2563
+ ADD_CONSTREF(std::string, matcher)
2562
2564
  // this cannot be changed to obj atm!!!!!!????!!!!!!!
2563
2565
  ADD_PROPERTY(String_Obj, value) // might be interpolated
2566
+ ADD_PROPERTY(char, modifier);
2564
2567
  public:
2565
- Attribute_Selector(ParserState pstate, std::string n, std::string m, String_Obj v)
2566
- : Simple_Selector(pstate, n), matcher_(m), value_(v)
2568
+ Attribute_Selector(ParserState pstate, std::string n, std::string m, String_Obj v, char o = 0)
2569
+ : Simple_Selector(pstate, n), matcher_(m), value_(v), modifier_(o)
2567
2570
  { simple_type(ATTR_SEL); }
2568
2571
  Attribute_Selector(const Attribute_Selector* ptr)
2569
2572
  : Simple_Selector(ptr),
2570
2573
  matcher_(ptr->matcher_),
2571
- value_(ptr->value_)
2574
+ value_(ptr->value_),
2575
+ modifier_(ptr->modifier_)
2572
2576
  { simple_type(ATTR_SEL); }
2573
2577
  virtual size_t hash()
2574
2578
  {
@@ -2579,7 +2583,7 @@ namespace Sass {
2579
2583
  }
2580
2584
  return hash_;
2581
2585
  }
2582
- virtual unsigned long specificity()
2586
+ virtual unsigned long specificity() const
2583
2587
  {
2584
2588
  return Constants::Specificity_Attr;
2585
2589
  }
@@ -2617,14 +2621,6 @@ namespace Sass {
2617
2621
  : Simple_Selector(ptr), expression_(ptr->expression_)
2618
2622
  { simple_type(PSEUDO_SEL); }
2619
2623
 
2620
- // A pseudo-class always consists of a "colon" (:) followed by the name
2621
- // of the pseudo-class and optionally by a value between parentheses.
2622
- virtual bool is_pseudo_class()
2623
- {
2624
- return (name_[0] == ':' && name_[1] != ':')
2625
- && ! is_pseudo_class_element(name_);
2626
- }
2627
-
2628
2624
  // A pseudo-element is made of two colons (::) followed by the name.
2629
2625
  // The `::` notation is introduced by the current document in order to
2630
2626
  // establish a discrimination between pseudo-classes and pseudo-elements.
@@ -2633,7 +2629,7 @@ namespace Sass {
2633
2629
  // in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and
2634
2630
  // :after). This compatibility is not allowed for the new pseudo-elements
2635
2631
  // introduced in this specification.
2636
- virtual bool is_pseudo_element()
2632
+ virtual bool is_pseudo_element() const
2637
2633
  {
2638
2634
  return (name_[0] == ':' && name_[1] == ':')
2639
2635
  || is_pseudo_class_element(name_);
@@ -2646,7 +2642,7 @@ namespace Sass {
2646
2642
  }
2647
2643
  return hash_;
2648
2644
  }
2649
- virtual unsigned long specificity()
2645
+ virtual unsigned long specificity() const
2650
2646
  {
2651
2647
  if (is_pseudo_element())
2652
2648
  return Constants::Specificity_Element;
@@ -2656,7 +2652,7 @@ namespace Sass {
2656
2652
  virtual bool operator==(const Pseudo_Selector& rhs) const;
2657
2653
  virtual bool operator<(const Simple_Selector& rhs) const;
2658
2654
  virtual bool operator<(const Pseudo_Selector& rhs) const;
2659
- virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&);
2655
+ virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
2660
2656
  ATTACH_AST_OPERATIONS(Pseudo_Selector)
2661
2657
  ATTACH_OPERATIONS()
2662
2658
  };
@@ -2665,9 +2661,9 @@ namespace Sass {
2665
2661
  // Wrapped selector -- pseudo selector that takes a list of selectors as argument(s) e.g., :not(:first-of-type), :-moz-any(ol p.blah, ul, menu, dir)
2666
2662
  /////////////////////////////////////////////////
2667
2663
  class Wrapped_Selector : public Simple_Selector {
2668
- ADD_PROPERTY(Selector_Obj, selector)
2664
+ ADD_PROPERTY(Selector_List_Obj, selector)
2669
2665
  public:
2670
- Wrapped_Selector(ParserState pstate, std::string n, Selector_Obj sel)
2666
+ Wrapped_Selector(ParserState pstate, std::string n, Selector_List_Obj sel)
2671
2667
  : Simple_Selector(pstate, n), selector_(sel)
2672
2668
  { simple_type(WRAPPED_SEL); }
2673
2669
  Wrapped_Selector(const Wrapped_Selector* ptr)
@@ -2676,28 +2672,11 @@ namespace Sass {
2676
2672
  virtual bool is_superselector_of(Wrapped_Selector_Obj sub);
2677
2673
  // Selectors inside the negation pseudo-class are counted like any
2678
2674
  // other, but the negation itself does not count as a pseudo-class.
2679
- virtual size_t hash()
2680
- {
2681
- if (hash_ == 0) {
2682
- hash_combine(hash_, Simple_Selector::hash());
2683
- if (selector_) hash_combine(hash_, selector_->hash());
2684
- }
2685
- return hash_;
2686
- }
2687
- virtual bool has_parent_ref() {
2688
- // if (has_reference()) return true;
2689
- if (!selector()) return false;
2690
- return selector()->has_parent_ref();
2691
- }
2692
- virtual bool has_real_parent_ref() {
2693
- // if (has_reference()) return true;
2694
- if (!selector()) return false;
2695
- return selector()->has_real_parent_ref();
2696
- }
2697
- virtual unsigned long specificity()
2698
- {
2699
- return selector_ ? selector_->specificity() : 0;
2700
- }
2675
+ virtual size_t hash();
2676
+ virtual bool has_parent_ref() const;
2677
+ virtual bool has_real_parent_ref() const;
2678
+ virtual unsigned long specificity() const;
2679
+ virtual bool find ( bool (*f)(AST_Node_Obj) );
2701
2680
  virtual bool operator==(const Simple_Selector& rhs) const;
2702
2681
  virtual bool operator==(const Wrapped_Selector& rhs) const;
2703
2682
  virtual bool operator<(const Simple_Selector& rhs) const;
@@ -2707,18 +2686,13 @@ namespace Sass {
2707
2686
  ATTACH_OPERATIONS()
2708
2687
  };
2709
2688
 
2710
- struct Complex_Selector_Pointer_Compare {
2711
- bool operator() (const Complex_Selector_Obj& pLeft, const Complex_Selector_Obj& pRight) const;
2712
- };
2713
-
2714
2689
  ////////////////////////////////////////////////////////////////////////////
2715
2690
  // Simple selector sequences. Maintains flags indicating whether it contains
2716
2691
  // any parent references or placeholders, to simplify expansion.
2717
2692
  ////////////////////////////////////////////////////////////////////////////
2718
- typedef std::set<Complex_Selector_Obj, Complex_Selector_Pointer_Compare> SourcesSet;
2719
2693
  class Compound_Selector : public Selector, public Vectorized<Simple_Selector_Obj> {
2720
2694
  private:
2721
- SourcesSet sources_;
2695
+ ComplexSelectorSet sources_;
2722
2696
  ADD_PROPERTY(bool, extended);
2723
2697
  ADD_PROPERTY(bool, has_parent_reference);
2724
2698
  protected:
@@ -2755,20 +2729,15 @@ namespace Sass {
2755
2729
  }
2756
2730
 
2757
2731
  Complex_Selector_Obj to_complex();
2758
- Compound_Selector_Ptr unify_with(Compound_Selector_Ptr rhs, Context& ctx);
2732
+ Compound_Selector_Ptr unify_with(Compound_Selector_Ptr rhs);
2759
2733
  // virtual Placeholder_Selector_Ptr find_placeholder();
2760
- virtual bool has_parent_ref();
2761
- virtual bool has_real_parent_ref();
2762
- Simple_Selector_Ptr base()
2763
- {
2764
- // Implement non-const in terms of const. Safe to const_cast since this method is non-const
2765
- return const_cast<Simple_Selector_Ptr>(static_cast<Compound_Selector_Ptr_Const>(this)->base());
2766
- }
2767
- Simple_Selector_Ptr_Const base() const {
2734
+ virtual bool has_parent_ref() const;
2735
+ virtual bool has_real_parent_ref() const;
2736
+ Simple_Selector_Ptr base() const {
2768
2737
  if (length() == 0) return 0;
2769
2738
  // ToDo: why is this needed?
2770
- if (SASS_MEMORY_CAST(Element_Selector, (*this)[0]))
2771
- return &(*this)[0];
2739
+ if (Cast<Element_Selector>((*this)[0]))
2740
+ return (*this)[0];
2772
2741
  return 0;
2773
2742
  }
2774
2743
  virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapped = "");
@@ -2782,7 +2751,7 @@ namespace Sass {
2782
2751
  }
2783
2752
  return Selector::hash_;
2784
2753
  }
2785
- virtual unsigned long specificity()
2754
+ virtual unsigned long specificity() const
2786
2755
  {
2787
2756
  int sum = 0;
2788
2757
  for (size_t i = 0, L = length(); i < L; ++i)
@@ -2802,19 +2771,21 @@ namespace Sass {
2802
2771
  bool is_empty_reference()
2803
2772
  {
2804
2773
  return length() == 1 &&
2805
- SASS_MEMORY_CAST(Parent_Selector, (*this)[0]);
2774
+ Cast<Parent_Selector>((*this)[0]);
2806
2775
  }
2807
- std::vector<Subset_Map_Key> to_str_vec(); // sometimes need to convert to a flat "by-value" data structure
2808
2776
 
2777
+ virtual bool find ( bool (*f)(AST_Node_Obj) );
2778
+ virtual bool operator<(const Selector& rhs) const;
2779
+ virtual bool operator==(const Selector& rhs) const;
2809
2780
  virtual bool operator<(const Compound_Selector& rhs) const;
2810
2781
  virtual bool operator==(const Compound_Selector& rhs) const;
2811
2782
  inline bool operator!=(const Compound_Selector& rhs) const { return !(*this == rhs); }
2812
2783
 
2813
- SourcesSet& sources() { return sources_; }
2784
+ ComplexSelectorSet& sources() { return sources_; }
2814
2785
  void clearSources() { sources_.clear(); }
2815
- void mergeSources(SourcesSet& sources, Context& ctx);
2786
+ void mergeSources(ComplexSelectorSet& sources);
2816
2787
 
2817
- Compound_Selector_Ptr minus(Compound_Selector_Ptr rhs, Context& ctx);
2788
+ Compound_Selector_Ptr minus(Compound_Selector_Ptr rhs);
2818
2789
  virtual void cloneChildren();
2819
2790
  ATTACH_AST_OPERATIONS(Compound_Selector)
2820
2791
  ATTACH_OPERATIONS()
@@ -2829,10 +2800,10 @@ namespace Sass {
2829
2800
  public:
2830
2801
  enum Combinator { ANCESTOR_OF, PARENT_OF, PRECEDES, ADJACENT_TO, REFERENCE };
2831
2802
  private:
2832
- ADD_PROPERTY(Combinator, combinator)
2833
- ADD_PROPERTY(Compound_Selector_Obj, head)
2834
- ADD_PROPERTY(Complex_Selector_Obj, tail)
2835
- ADD_PROPERTY(String_Obj, reference);
2803
+ HASH_CONSTREF(Combinator, combinator)
2804
+ HASH_PROPERTY(Compound_Selector_Obj, head)
2805
+ HASH_PROPERTY(Complex_Selector_Obj, tail)
2806
+ HASH_PROPERTY(String_Obj, reference);
2836
2807
  public:
2837
2808
  bool contains_placeholder() {
2838
2809
  if (head() && head()->contains_placeholder()) return true;
@@ -2855,8 +2826,8 @@ namespace Sass {
2855
2826
  head_(ptr->head_), tail_(ptr->tail_),
2856
2827
  reference_(ptr->reference_)
2857
2828
  {};
2858
- virtual bool has_parent_ref();
2859
- virtual bool has_real_parent_ref();
2829
+ virtual bool has_parent_ref() const;
2830
+ virtual bool has_real_parent_ref() const;
2860
2831
 
2861
2832
  Complex_Selector_Obj skip_empty_reference()
2862
2833
  {
@@ -2878,10 +2849,7 @@ namespace Sass {
2878
2849
  combinator() == Combinator::ANCESTOR_OF;
2879
2850
  }
2880
2851
 
2881
- Complex_Selector_Obj context(Context&);
2882
-
2883
-
2884
- Selector_List_Ptr tails(Context& ctx, Selector_List_Ptr tails);
2852
+ Selector_List_Ptr tails(Selector_List_Ptr tails);
2885
2853
 
2886
2854
  // front returns the first real tail
2887
2855
  // skips over parent and empty ones
@@ -2893,13 +2861,13 @@ namespace Sass {
2893
2861
  Complex_Selector_Obj innermost() { return last(); };
2894
2862
 
2895
2863
  size_t length() const;
2896
- Selector_List_Ptr resolve_parent_refs(Context& ctx, std::vector<Selector_List_Obj>& pstack, bool implicit_parent = true);
2864
+ Selector_List_Ptr resolve_parent_refs(std::vector<Selector_List_Obj>& pstack, Backtraces& traces, bool implicit_parent = true);
2897
2865
  virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapping = "");
2898
2866
  virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapping = "");
2899
2867
  virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapping = "");
2900
- Selector_List_Ptr unify_with(Complex_Selector_Ptr rhs, Context& ctx);
2868
+ Selector_List_Ptr unify_with(Complex_Selector_Ptr rhs);
2901
2869
  Combinator clear_innermost();
2902
- void append(Context&, Complex_Selector_Obj);
2870
+ void append(Complex_Selector_Obj, Backtraces& traces);
2903
2871
  void set_innermost(Complex_Selector_Obj, Combinator);
2904
2872
  virtual size_t hash()
2905
2873
  {
@@ -2928,55 +2896,58 @@ namespace Sass {
2928
2896
  if (tail_ && tail_->has_placeholder()) return true;
2929
2897
  return false;
2930
2898
  }
2899
+ virtual bool find ( bool (*f)(AST_Node_Obj) );
2900
+ virtual bool operator<(const Selector& rhs) const;
2901
+ virtual bool operator==(const Selector& rhs) const;
2931
2902
  virtual bool operator<(const Complex_Selector& rhs) const;
2932
2903
  virtual bool operator==(const Complex_Selector& rhs) const;
2933
2904
  inline bool operator!=(const Complex_Selector& rhs) const { return !(*this == rhs); }
2934
- SourcesSet sources()
2905
+ const ComplexSelectorSet sources()
2935
2906
  {
2936
2907
  //s = Set.new
2937
2908
  //seq.map {|sseq_or_op| s.merge sseq_or_op.sources if sseq_or_op.is_a?(SimpleSequence)}
2938
2909
  //s
2939
2910
 
2940
- SourcesSet srcs;
2911
+ ComplexSelectorSet srcs;
2941
2912
 
2942
2913
  Compound_Selector_Obj pHead = head();
2943
2914
  Complex_Selector_Obj pTail = tail();
2944
2915
 
2945
2916
  if (pHead) {
2946
- SourcesSet& headSources = pHead->sources();
2917
+ const ComplexSelectorSet& headSources = pHead->sources();
2947
2918
  srcs.insert(headSources.begin(), headSources.end());
2948
2919
  }
2949
2920
 
2950
2921
  if (pTail) {
2951
- SourcesSet tailSources = pTail->sources();
2922
+ const ComplexSelectorSet& tailSources = pTail->sources();
2952
2923
  srcs.insert(tailSources.begin(), tailSources.end());
2953
2924
  }
2954
2925
 
2955
2926
  return srcs;
2956
2927
  }
2957
- void addSources(SourcesSet& sources, Context& ctx) {
2928
+ void addSources(ComplexSelectorSet& sources) {
2958
2929
  // members.map! {|m| m.is_a?(SimpleSequence) ? m.with_more_sources(sources) : m}
2959
2930
  Complex_Selector_Ptr pIter = this;
2960
2931
  while (pIter) {
2961
- Compound_Selector_Ptr pHead = &pIter->head();
2932
+ Compound_Selector_Ptr pHead = pIter->head();
2962
2933
 
2963
2934
  if (pHead) {
2964
- pHead->mergeSources(sources, ctx);
2935
+ pHead->mergeSources(sources);
2965
2936
  }
2966
2937
 
2967
- pIter = &pIter->tail();
2938
+ pIter = pIter->tail();
2968
2939
  }
2969
2940
  }
2970
2941
  void clearSources() {
2971
2942
  Complex_Selector_Ptr pIter = this;
2972
2943
  while (pIter) {
2973
- Compound_Selector_Ptr pHead = &pIter->head();
2944
+ Compound_Selector_Ptr pHead = pIter->head();
2974
2945
 
2975
2946
  if (pHead) {
2976
2947
  pHead->clearSources();
2977
2948
  }
2978
2949
 
2979
- pIter = &pIter->tail();
2950
+ pIter = pIter->tail();
2980
2951
  }
2981
2952
  }
2982
2953
 
@@ -2985,36 +2956,40 @@ namespace Sass {
2985
2956
  ATTACH_OPERATIONS()
2986
2957
  };
2987
2958
 
2988
- typedef std::deque<Complex_Selector_Obj> ComplexSelectorDeque;
2989
-
2990
2959
  ///////////////////////////////////
2991
2960
  // Comma-separated selector groups.
2992
2961
  ///////////////////////////////////
2993
2962
  class Selector_List : public Selector, public Vectorized<Complex_Selector_Obj> {
2994
- ADD_PROPERTY(std::vector<std::string>, wspace)
2963
+ ADD_PROPERTY(Selector_Schema_Obj, schema)
2964
+ ADD_CONSTREF(std::vector<std::string>, wspace)
2995
2965
  protected:
2996
2966
  void adjust_after_pushing(Complex_Selector_Obj c);
2997
2967
  public:
2998
2968
  Selector_List(ParserState pstate, size_t s = 0)
2999
- : Selector(pstate), Vectorized<Complex_Selector_Obj>(s), wspace_(0)
2969
+ : Selector(pstate),
2970
+ Vectorized<Complex_Selector_Obj>(s),
2971
+ schema_(NULL),
2972
+ wspace_(0)
3000
2973
  { }
3001
2974
  Selector_List(const Selector_List* ptr)
3002
2975
  : Selector(ptr),
3003
2976
  Vectorized<Complex_Selector_Obj>(*ptr),
2977
+ schema_(ptr->schema_),
3004
2978
  wspace_(ptr->wspace_)
3005
2979
  { }
3006
- std::string type() { return "list"; }
2980
+ std::string type() const { return "list"; }
3007
2981
  // remove parent selector references
3008
2982
  // basically unwraps parsed selectors
3009
- virtual bool has_parent_ref();
3010
- virtual bool has_real_parent_ref();
2983
+ virtual bool has_parent_ref() const;
2984
+ virtual bool has_real_parent_ref() const;
3011
2985
  void remove_parent_selectors();
3012
- Selector_List_Ptr resolve_parent_refs(Context& ctx, std::vector<Selector_List_Obj>& pstack, bool implicit_parent = true);
2986
+ Selector_List_Ptr resolve_parent_refs(std::vector<Selector_List_Obj>& pstack, Backtraces& traces, bool implicit_parent = true);
3013
2987
  virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapping = "");
3014
2988
  virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapping = "");
3015
2989
  virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapping = "");
3016
- Selector_List_Ptr unify_with(Selector_List_Ptr, Context&);
3017
- void populate_extends(Selector_List_Obj, Context&, Subset_Map&);
2990
+ Selector_List_Ptr unify_with(Selector_List_Ptr);
2991
+ void populate_extends(Selector_List_Obj, Subset_Map&);
2992
+ Selector_List_Obj eval(Eval& eval);
3018
2993
  virtual size_t hash()
3019
2994
  {
3020
2995
  if (Selector::hash_ == 0) {
@@ -3023,10 +2998,10 @@ namespace Sass {
3023
2998
  }
3024
2999
  return Selector::hash_;
3025
3000
  }
3026
- virtual unsigned long specificity()
3001
+ virtual unsigned long specificity() const
3027
3002
  {
3028
3003
  unsigned long sum = 0;
3029
- unsigned long specificity = 0;
3004
+ unsigned long specificity;
3030
3005
  for (size_t i = 0, L = length(); i < L; ++i)
3031
3006
  {
3032
3007
  specificity = (*this)[i]->specificity();
@@ -3046,6 +3021,7 @@ namespace Sass {
3046
3021
  }
3047
3022
  return false;
3048
3023
  }
3024
+ virtual bool find ( bool (*f)(AST_Node_Obj) );
3049
3025
  virtual bool operator<(const Selector& rhs) const;
3050
3026
  virtual bool operator==(const Selector& rhs) const;
3051
3027
  virtual bool operator<(const Selector_List& rhs) const;
@@ -3057,24 +3033,6 @@ namespace Sass {
3057
3033
  ATTACH_OPERATIONS()
3058
3034
  };
3059
3035
 
3060
- template<typename SelectorType>
3061
- bool selectors_equal(const SelectorType& one, const SelectorType& two, bool simpleSelectorOrderDependent) {
3062
- // Test for equality among selectors while differentiating between checks that demand the underlying Simple_Selector
3063
- // ordering to be the same or not. This works because operator< (which doesn't make a whole lot of sense for selectors, but
3064
- // is required for proper stl collection ordering) is implemented using string comparision. This gives stable sorting
3065
- // behavior, and can be used to determine if the selectors would have exactly idential output. operator== matches the
3066
- // ruby sass implementations for eql, which sometimes perform order independent comparisions (like set comparisons of the
3067
- // members of a SimpleSequence (Compound_Selector)).
3068
- //
3069
- // Due to the reliance on operator== and operater< behavior, this templated method is currently only intended for
3070
- // use with Compound_Selector and Complex_Selector objects.
3071
- if (simpleSelectorOrderDependent) {
3072
- return !(one < two) && !(two < one);
3073
- } else {
3074
- return one == two;
3075
- }
3076
- }
3077
-
3078
3036
  // compare function for sorting and probably other other uses
3079
3037
  struct cmp_complex_selector { inline bool operator() (const Complex_Selector_Obj l, const Complex_Selector_Obj r) { return (*l < *r); } };
3080
3038
  struct cmp_compound_selector { inline bool operator() (const Compound_Selector_Obj l, const Compound_Selector_Obj r) { return (*l < *r); } };