sassc 1.11.4 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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); } };