sassc 0.0.10 → 0.0.11

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/libsass/.gitignore +6 -0
  4. data/ext/libsass/.travis.yml +5 -1
  5. data/ext/libsass/Makefile +12 -3
  6. data/ext/libsass/Makefile.am +16 -28
  7. data/ext/libsass/Readme.md +1 -0
  8. data/ext/libsass/appveyor.yml +1 -2
  9. data/ext/libsass/ast.cpp +9 -0
  10. data/ext/libsass/ast.hpp +152 -55
  11. data/ext/libsass/ast_factory.hpp +2 -0
  12. data/ext/libsass/ast_fwd_decl.hpp +1 -0
  13. data/ext/libsass/backtrace.hpp +2 -2
  14. data/ext/libsass/bind.cpp +15 -13
  15. data/ext/libsass/configure.ac +17 -5
  16. data/ext/libsass/constants.cpp +22 -2
  17. data/ext/libsass/constants.hpp +21 -2
  18. data/ext/libsass/context.cpp +79 -57
  19. data/ext/libsass/context.hpp +23 -9
  20. data/ext/libsass/contextualize.cpp +2 -28
  21. data/ext/libsass/contextualize.hpp +6 -10
  22. data/ext/libsass/contextualize_eval.cpp +93 -0
  23. data/ext/libsass/contextualize_eval.hpp +44 -0
  24. data/ext/libsass/contrib/plugin.cpp +57 -0
  25. data/ext/libsass/cssize.cpp +3 -1
  26. data/ext/libsass/debugger.hpp +242 -83
  27. data/ext/libsass/emitter.cpp +1 -1
  28. data/ext/libsass/emitter.hpp +1 -1
  29. data/ext/libsass/environment.hpp +109 -25
  30. data/ext/libsass/error_handling.cpp +3 -3
  31. data/ext/libsass/error_handling.hpp +0 -1
  32. data/ext/libsass/eval.cpp +145 -61
  33. data/ext/libsass/eval.hpp +9 -1
  34. data/ext/libsass/expand.cpp +134 -60
  35. data/ext/libsass/expand.hpp +5 -2
  36. data/ext/libsass/extend.cpp +7 -5
  37. data/ext/libsass/file.cpp +176 -123
  38. data/ext/libsass/file.hpp +44 -7
  39. data/ext/libsass/functions.cpp +36 -17
  40. data/ext/libsass/functions.hpp +2 -2
  41. data/ext/libsass/inspect.cpp +23 -14
  42. data/ext/libsass/inspect.hpp +1 -0
  43. data/ext/libsass/json.cpp +132 -135
  44. data/ext/libsass/lexer.cpp +133 -0
  45. data/ext/libsass/lexer.hpp +239 -0
  46. data/ext/libsass/listize.cpp +83 -0
  47. data/ext/libsass/listize.hpp +41 -0
  48. data/ext/libsass/operation.hpp +2 -0
  49. data/ext/libsass/output.cpp +5 -6
  50. data/ext/libsass/parser.cpp +426 -388
  51. data/ext/libsass/parser.hpp +97 -109
  52. data/ext/libsass/plugins.cpp +15 -2
  53. data/ext/libsass/plugins.hpp +6 -4
  54. data/ext/libsass/position.cpp +52 -17
  55. data/ext/libsass/position.hpp +19 -17
  56. data/ext/libsass/prelexer.cpp +202 -235
  57. data/ext/libsass/prelexer.hpp +73 -333
  58. data/ext/libsass/sass.cpp +21 -11
  59. data/ext/libsass/sass.h +6 -6
  60. data/ext/libsass/sass_context.cpp +167 -81
  61. data/ext/libsass/sass_context.h +26 -6
  62. data/ext/libsass/sass_functions.cpp +49 -40
  63. data/ext/libsass/sass_functions.h +55 -43
  64. data/ext/libsass/sass_interface.cpp +9 -8
  65. data/ext/libsass/sass_interface.h +3 -3
  66. data/ext/libsass/sass_version.h +8 -0
  67. data/ext/libsass/sass_version.h.in +8 -0
  68. data/ext/libsass/script/ci-build-libsass +3 -3
  69. data/ext/libsass/script/ci-report-coverage +2 -1
  70. data/ext/libsass/source_map.cpp +2 -2
  71. data/ext/libsass/util.cpp +60 -11
  72. data/ext/libsass/util.hpp +6 -1
  73. data/ext/libsass/win/libsass.filters +12 -0
  74. data/ext/libsass/win/libsass.vcxproj +10 -0
  75. data/lib/sassc.rb +3 -1
  76. data/lib/sassc/cache_stores/base.rb +2 -0
  77. data/lib/sassc/dependency.rb +3 -1
  78. data/lib/sassc/engine.rb +31 -16
  79. data/lib/sassc/error.rb +3 -2
  80. data/lib/sassc/functions_handler.rb +54 -0
  81. data/lib/sassc/import_handler.rb +41 -0
  82. data/lib/sassc/importer.rb +4 -31
  83. data/lib/sassc/native.rb +1 -1
  84. data/lib/sassc/native/native_context_api.rb +3 -2
  85. data/lib/sassc/script.rb +0 -51
  86. data/lib/sassc/version.rb +1 -1
  87. data/sassc.gemspec +1 -0
  88. data/test/custom_importer_test.rb +72 -69
  89. data/test/engine_test.rb +53 -54
  90. data/test/functions_test.rb +40 -39
  91. data/test/native_test.rb +145 -149
  92. data/test/output_style_test.rb +98 -0
  93. data/test/test_helper.rb +21 -7
  94. metadata +28 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 84e3ac644262800f310def2ddd6a33b788173644
4
- data.tar.gz: 60a9b9684751c114079664615eac210ca91b50f3
3
+ metadata.gz: 0c834fe7f6b0359169fc1f6ba7d1cab0e98c90db
4
+ data.tar.gz: fb01c0beb052582b9b7f642b0c723d9c12754c22
5
5
  SHA512:
6
- metadata.gz: 447d7bf985003fb37bf86ae08e9b7f2aca73b440ff073926f809225eec7ccb152a9a8361111e2349f3894bda5b4c6f2c2a52a781ebb5cebe9873f37ebe90edfc
7
- data.tar.gz: d5f9074a354e20f40b43cb48ae8ce8cae436f6c9b1a7cf7a5c3f3b8f6b6ba81bdd4ca5dd375ac921f565786e44e316885a6596ffab7f13f9173873b467d12a26
6
+ metadata.gz: 76ac15bb37435e1979a62a05fdd90ab3eaa017e7bce9726e386ee01718f7989929554f878f73924aa5d94d0fbea742503a8d2ee46421a5916e7c6e85c4fde7a1
7
+ data.tar.gz: 5838c775f6078cd2be03c47f2ef5637fcea57e521f7d2bbc6af1f78d8aa3c1e42bfe3b165f5ce1ea5ace1b22e6d17d33f8759bf65333a49df74f56b92642aa7f
data/README.md CHANGED
@@ -6,7 +6,7 @@ This gem combines the speed of `libsass`, the [Sass C implementation](https://gi
6
6
 
7
7
  ### libsass Version
8
8
 
9
- [3.1.0](https://github.com/sass/libsass/releases/tag/3.1.0)
9
+ [3.2.0-beta.6](https://github.com/sass/libsass/releases/tag/3.2.0-beta.6)
10
10
 
11
11
  ## Contributing
12
12
 
@@ -1,5 +1,6 @@
1
1
  # Miscellaneous stuff
2
2
 
3
+ VERSION
3
4
  .DS_Store
4
5
  .sass-cache
5
6
  *.gem
@@ -19,12 +20,14 @@ Makefile.in
19
20
  /config.log
20
21
  /config.status
21
22
  /configure
23
+ include/
22
24
  /libtool
23
25
  /m4/libtool.m4
24
26
  /m4/ltoptions.m4
25
27
  /m4/ltsugar.m4
26
28
  /m4/ltversion.m4
27
29
  /m4/lt~obsolete.m4
30
+ /script/ar-lib
28
31
  /script/compile
29
32
  /script/config.guess
30
33
  /script/config.sub
@@ -44,6 +47,9 @@ libsass/*
44
47
  *.so
45
48
  *.dll
46
49
  *.a
50
+ *.suo
51
+ *.sdf
52
+ *.opensdf
47
53
  a.out
48
54
  libsass.js
49
55
  tester
@@ -2,7 +2,7 @@ language: cpp
2
2
 
3
3
  os:
4
4
  - linux
5
- # - osx
5
+ - osx
6
6
 
7
7
  compiler:
8
8
  - gcc
@@ -31,6 +31,10 @@ matrix:
31
31
  exclude:
32
32
  - compiler: clang
33
33
  env: AUTOTOOLS=yes COVERAGE=yes BUILD=static
34
+ - os: osx
35
+ compiler: gcc
36
+ - os: osx
37
+ env: AUTOTOOLS=no COVERAGE=yes BUILD=static
34
38
 
35
39
  script: ./script/ci-build-libsass
36
40
  before_install: ./script/ci-install-deps
@@ -4,9 +4,15 @@ RM ?= rm -f
4
4
  CP ?= cp -a
5
5
  MKDIR ?= mkdir
6
6
  WINDRES ?= windres
7
- CFLAGS ?= -Wall -O2
8
- CXXFLAGS ?= -Wall -O2
9
- LDFLAGS ?= -Wall -O2 -Wl,--no-undefined
7
+ CFLAGS ?= -Wall
8
+ CXXFLAGS ?= -Wall
9
+ LDFLAGS ?= -Wall
10
+ ifneq "$(COVERAGE)" "yes"
11
+ CFLAGS += -O2
12
+ CXXFLAGS += -O2
13
+ LDFLAGS += -O2
14
+ endif
15
+ LDFLAGS += -Wl,-undefined,error
10
16
  CAT ?= $(if $(filter $(OS),Windows_NT),type,cat)
11
17
 
12
18
  ifneq (,$(findstring /cygdrive/,$(PATH)))
@@ -112,7 +118,9 @@ SOURCES = \
112
118
  constants.cpp \
113
119
  context.cpp \
114
120
  contextualize.cpp \
121
+ contextualize_eval.cpp \
115
122
  cssize.cpp \
123
+ listize.cpp \
116
124
  error_handling.cpp \
117
125
  eval.cpp \
118
126
  expand.cpp \
@@ -120,6 +128,7 @@ SOURCES = \
120
128
  file.cpp \
121
129
  functions.cpp \
122
130
  inspect.cpp \
131
+ lexer.cpp \
123
132
  node.cpp \
124
133
  json.cpp \
125
134
  emitter.cpp \
@@ -1,29 +1,21 @@
1
1
  ACLOCAL_AMFLAGS = -I m4
2
2
 
3
- AM_LDFLAGS = -lstdc++ -lm
4
- AM_CFLAGS = -Wall
5
- AM_CXXFLAGS = -Wall
3
+ AM_COPT = -Wall -O2
4
+ AM_COVLDFLAGS =
6
5
 
7
- if COMPILER_IS_MINGW32
8
- AM_CXXFLAGS += -std=gnu++0x
9
- else
10
- AM_CFLAGS += -fPIC
11
- AM_CXXFLAGS += -fPIC
12
- AM_CXXFLAGS += -std=c++0x
13
- AM_LDFLAGS += -ldl
6
+ if ENABLE_COVERAGE
7
+ AM_COPT = -O0 --coverage
8
+ AM_COVLDFLAGS += -lgcov
14
9
  endif
15
10
 
16
- AM_CFLAGS += -DLIBSASS_VERSION="\"$(VERSION)\""
17
- AM_CXXFLAGS += -DLIBSASS_VERSION="\"$(VERSION)\""
11
+ AM_CFLAGS = $(AM_COPT)
12
+ AM_CXXFLAGS = $(AM_COPT)
13
+ AM_LDFLAGS = $(AM_COPT) $(AM_COVLDFLAGS)
18
14
 
19
- if ENABLE_COVERAGE
20
- AM_CFLAGS += -O0 --coverage
21
- AM_CXXFLAGS += -O0 --coverage
22
- AM_LDFLAGS += -O0 --coverage -lgcov
15
+ if COMPILER_IS_MINGW32
16
+ AM_CXXFLAGS += -std=gnu++0x
23
17
  else
24
- AM_CFLAGS += -O2
25
- AM_CXXFLAGS += -O2
26
- AM_LDFLAGS += -O2
18
+ AM_CXXFLAGS += -std=c++0x
27
19
  endif
28
20
 
29
21
  EXTRA_DIST = \
@@ -55,14 +47,17 @@ libsass_la_SOURCES = \
55
47
  constants.cpp constants.hpp \
56
48
  context.cpp context.hpp \
57
49
  contextualize.cpp contextualize.hpp \
50
+ contextualize_eval.cpp contextualize_eval.hpp \
58
51
  error_handling.cpp error_handling.hpp \
59
52
  eval.cpp eval.hpp \
60
53
  expand.cpp expand.hpp \
61
54
  extend.cpp extend.hpp \
62
55
  cssize.cpp cssize.hpp \
56
+ listize.cpp listize.hpp \
63
57
  file.cpp file.hpp \
64
58
  functions.cpp functions.hpp \
65
59
  inspect.cpp inspect.hpp \
60
+ lexer.cpp lexer.hpp \
66
61
  node.cpp node.hpp \
67
62
  json.cpp json.hpp \
68
63
  emitter.cpp emitter.hpp \
@@ -85,11 +80,9 @@ libsass_la_SOURCES = \
85
80
  utf8_string.cpp utf8_string.hpp \
86
81
  util.cpp util.hpp
87
82
 
88
- libsass_la_CFLAGS = $(AM_CFLAGS)
89
- libsass_la_CXXFLAGS = $(AM_CXXFLAGS)
90
83
  libsass_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-info 0:9:0
91
84
 
92
- include_HEADERS = sass2scss.h sass_context.h sass_functions.h sass_values.h sass.h
85
+ include_HEADERS = sass2scss.h sass_context.h sass_functions.h sass_values.h sass.h sass_version.h
93
86
 
94
87
  if ENABLE_TESTS
95
88
 
@@ -136,12 +129,7 @@ else
136
129
  endif
137
130
 
138
131
  SASS_TESTER = $(RUBY) $(SASS_SPEC_PATH)/sass-spec.rb
139
-
140
- if COMPILER_IS_MINGW32
141
- SASS_TESTER += -c $(SASS_LIBSASS_PATH)/tester.exe
142
- else
143
- SASS_TESTER += -c $(SASS_LIBSASS_PATH)/tester
144
- endif
132
+ SASS_TESTER += -c $(SASS_LIBSASS_PATH)/tester$(EXEEXT)
145
133
 
146
134
  test:
147
135
  $(SASS_TESTER) --ignore-todo $(LOG_FLAGS) $(SASS_SPEC_PATH) $(SASS_TEST_FLAGS)
@@ -7,6 +7,7 @@ by Aaron Leung ([@akhleung]) and Hampton Catlin ([@hcatlin])
7
7
  [![Windows CI](https://ci.appveyor.com/api/projects/status/github/sass/libsass?svg=true)](https://ci.appveyor.com/project/sass/libsass/branch/master)
8
8
  [![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=283068)](https://www.bountysource.com/trackers/283068-libsass?utm_source=283068&utm_medium=shield&utm_campaign=TRACKER_BADGE)
9
9
  [![Coverage Status](https://img.shields.io/coveralls/sass/libsass.svg)](https://coveralls.io/r/sass/libsass?branch=feature%2Ftest-travis-ci-3)
10
+ [![Join us](https://still-ridge-9421.herokuapp.com/badge.svg)](https://still-ridge-9421.herokuapp.com/)
10
11
 
11
12
  https://github.com/sass/libsass
12
13
 
@@ -15,7 +15,6 @@ environment:
15
15
  ruby_version: "21-x64"
16
16
 
17
17
  cache:
18
- - C:\mingw64
19
18
  - C:\Ruby%ruby_version%\lib\ruby\gems
20
19
 
21
20
  install:
@@ -64,7 +63,7 @@ test_script:
64
63
  ruby sass-spec\sass-spec.rb -c sassc\bin\sassc.exe -s --ignore-todo sass-spec/spec
65
64
  } else {
66
65
  if ($env:Config -eq "Debug") {
67
- echo test runner in debug mode build via msvc will throw debug assertions
66
+ echo "test runner in debug mode build via msvc will throw debug assertions"
68
67
  echo ruby sass-spec\sass-spec.rb -c win\bin\Debug\sassc.exe -s --ignore-todo sass-spec/spec
69
68
  } else {
70
69
  ruby sass-spec\sass-spec.rb -c win\bin\sassc.exe -s --ignore-todo sass-spec/spec
@@ -8,6 +8,8 @@
8
8
  namespace Sass {
9
9
  using namespace std;
10
10
 
11
+ static Null sass_null(Sass::Null(ParserState("null")));
12
+
11
13
  bool Compound_Selector::operator<(const Compound_Selector& rhs) const
12
14
  {
13
15
  To_String to_string;
@@ -587,5 +589,12 @@ namespace Sass {
587
589
  return result;
588
590
  }*/
589
591
 
592
+ Expression* Hashed::at(Expression* k) const
593
+ {
594
+ if (elements_.count(k))
595
+ { return elements_.at(k); }
596
+ else { return &sass_null; }
597
+ }
598
+
590
599
  }
591
600
 
@@ -87,6 +87,7 @@ namespace Sass {
87
87
  STRING,
88
88
  LIST,
89
89
  MAP,
90
+ SELECTOR,
90
91
  NULL_VAL,
91
92
  NUM_TYPES
92
93
  };
@@ -209,9 +210,10 @@ namespace Sass {
209
210
  size_t length() const { return list_.size(); }
210
211
  bool empty() const { return list_.empty(); }
211
212
  bool has(Expression* k) const { return elements_.count(k) == 1; }
212
- Expression* at(Expression* k) const { return elements_.at(k); }
213
+ Expression* at(Expression* k) const;
213
214
  bool has_duplicate_key() const { return duplicate_key_ != 0; }
214
215
  Expression* get_duplicate_key() const { return duplicate_key_; }
216
+ const unordered_map<Expression*, Expression*> elements() { return elements_; }
215
217
  Hashed& operator<<(pair<Expression*, Expression*> p)
216
218
  {
217
219
  reset_hash();
@@ -430,10 +432,10 @@ namespace Sass {
430
432
  // Keyframe-rules -- the child blocks of "@keyframes" nodes.
431
433
  ///////////////////////////////////////////////////////////////////////
432
434
  class Keyframe_Rule : public Has_Block {
433
- ADD_PROPERTY(String*, rules);
435
+ ADD_PROPERTY(Selector*, selector);
434
436
  public:
435
437
  Keyframe_Rule(ParserState pstate, Block* b)
436
- : Has_Block(pstate, b), rules_(0)
438
+ : Has_Block(pstate, b), selector_(0)
437
439
  { statement_type(KEYFRAMERULE); }
438
440
  ATTACH_OPERATIONS();
439
441
  };
@@ -459,14 +461,14 @@ namespace Sass {
459
461
  class Assignment : public Statement {
460
462
  ADD_PROPERTY(string, variable);
461
463
  ADD_PROPERTY(Expression*, value);
462
- ADD_PROPERTY(bool, is_guarded);
464
+ ADD_PROPERTY(bool, is_default);
463
465
  ADD_PROPERTY(bool, is_global);
464
466
  public:
465
467
  Assignment(ParserState pstate,
466
468
  string var, Expression* val,
467
- bool guarded = false,
468
- bool global = false)
469
- : Statement(pstate), variable_(var), value_(val), is_guarded_(guarded), is_global_(global)
469
+ bool is_default = false,
470
+ bool is_global = false)
471
+ : Statement(pstate), variable_(var), value_(val), is_default_(is_default), is_global_(is_global)
470
472
  { }
471
473
  ATTACH_OPERATIONS();
472
474
  };
@@ -643,8 +645,9 @@ namespace Sass {
643
645
  ADD_PROPERTY(Env*, environment);
644
646
  ADD_PROPERTY(Type, type);
645
647
  ADD_PROPERTY(Native_Function, native_function);
646
- ADD_PROPERTY(Sass_C_Function, c_function);
648
+ ADD_PROPERTY(Sass_Function_Entry, c_function);
647
649
  ADD_PROPERTY(void*, cookie);
650
+ ADD_PROPERTY(Context*, ctx);
648
651
  ADD_PROPERTY(bool, is_overload_stub);
649
652
  ADD_PROPERTY(Signature, signature);
650
653
  public:
@@ -652,6 +655,7 @@ namespace Sass {
652
655
  string n,
653
656
  Parameters* params,
654
657
  Block* b,
658
+ Context* ctx,
655
659
  Type t)
656
660
  : Has_Block(pstate, b),
657
661
  name_(n),
@@ -661,6 +665,7 @@ namespace Sass {
661
665
  native_function_(0),
662
666
  c_function_(0),
663
667
  cookie_(0),
668
+ ctx_(ctx),
664
669
  is_overload_stub_(false),
665
670
  signature_(0)
666
671
  { }
@@ -669,6 +674,7 @@ namespace Sass {
669
674
  string n,
670
675
  Parameters* params,
671
676
  Native_Function func_ptr,
677
+ Context* ctx,
672
678
  bool overload_stub = false)
673
679
  : Has_Block(pstate, 0),
674
680
  name_(n),
@@ -678,6 +684,7 @@ namespace Sass {
678
684
  native_function_(func_ptr),
679
685
  c_function_(0),
680
686
  cookie_(0),
687
+ ctx_(ctx),
681
688
  is_overload_stub_(overload_stub),
682
689
  signature_(sig)
683
690
  { }
@@ -685,8 +692,8 @@ namespace Sass {
685
692
  Signature sig,
686
693
  string n,
687
694
  Parameters* params,
688
- Sass_C_Function func_ptr,
689
- void* cookie,
695
+ Sass_Function_Entry c_func,
696
+ Context* ctx,
690
697
  bool whatever,
691
698
  bool whatever2)
692
699
  : Has_Block(pstate, 0),
@@ -695,8 +702,9 @@ namespace Sass {
695
702
  environment_(0),
696
703
  type_(FUNCTION),
697
704
  native_function_(0),
698
- c_function_(func_ptr),
699
- cookie_(cookie),
705
+ c_function_(c_func),
706
+ cookie_(sass_function_get_cookie(c_func)),
707
+ ctx_(ctx),
700
708
  is_overload_stub_(false),
701
709
  signature_(sig)
702
710
  { }
@@ -843,11 +851,34 @@ namespace Sass {
843
851
  ADD_PROPERTY(Type, type);
844
852
  ADD_PROPERTY(Expression*, left);
845
853
  ADD_PROPERTY(Expression*, right);
854
+ size_t hash_;
846
855
  public:
847
856
  Binary_Expression(ParserState pstate,
848
857
  Type t, Expression* lhs, Expression* rhs)
849
- : Expression(pstate), type_(t), left_(lhs), right_(rhs)
858
+ : Expression(pstate), type_(t), left_(lhs), right_(rhs), hash_(0)
850
859
  { }
860
+ virtual bool operator==(Expression& rhs) const
861
+ {
862
+ try
863
+ {
864
+ Binary_Expression& m = dynamic_cast<Binary_Expression&>(rhs);
865
+ if (m == 0) return false;
866
+ return type() == m.type() &&
867
+ left() == m.left() &&
868
+ right() == m.right();
869
+ }
870
+ catch (std::bad_cast&)
871
+ {
872
+ return false;
873
+ }
874
+ catch (...) { throw; }
875
+ }
876
+ virtual size_t hash()
877
+ {
878
+ if (hash_ > 0) return hash_;
879
+ hash_ = left()->hash() ^ right()->hash() ^ std::hash<size_t>()(type_);
880
+ return hash_;
881
+ }
851
882
  ATTACH_OPERATIONS();
852
883
  };
853
884
 
@@ -860,10 +891,32 @@ namespace Sass {
860
891
  private:
861
892
  ADD_PROPERTY(Type, type);
862
893
  ADD_PROPERTY(Expression*, operand);
894
+ size_t hash_;
863
895
  public:
864
896
  Unary_Expression(ParserState pstate, Type t, Expression* o)
865
- : Expression(pstate), type_(t), operand_(o)
897
+ : Expression(pstate), type_(t), operand_(o), hash_(0)
866
898
  { }
899
+ virtual bool operator==(Expression& rhs) const
900
+ {
901
+ try
902
+ {
903
+ Unary_Expression& m = dynamic_cast<Unary_Expression&>(rhs);
904
+ if (m == 0) return false;
905
+ return type() == m.type() &&
906
+ operand() == m.operand();
907
+ }
908
+ catch (std::bad_cast&)
909
+ {
910
+ return false;
911
+ }
912
+ catch (...) { throw; }
913
+ }
914
+ virtual size_t hash()
915
+ {
916
+ if (hash_ > 0) return hash_;
917
+ hash_ = operand()->hash() ^ std::hash<size_t>()(type_);
918
+ return hash_;
919
+ }
867
920
  ATTACH_OPERATIONS();
868
921
  };
869
922
 
@@ -891,7 +944,7 @@ namespace Sass {
891
944
  {
892
945
  Argument& m = dynamic_cast<Argument&>(rhs);
893
946
  if (!(m && name() == m.name())) return false;
894
- return *value() == *value();
947
+ return *value() == *m.value();
895
948
  }
896
949
  catch (std::bad_cast&)
897
950
  {
@@ -1392,16 +1445,16 @@ namespace Sass {
1392
1445
  size_t hash_;
1393
1446
  public:
1394
1447
  String_Constant(ParserState pstate, string val)
1395
- : String(pstate), quote_mark_(0), value_(val), hash_(0)
1448
+ : String(pstate), quote_mark_(0), value_(read_css_string(val)), hash_(0)
1396
1449
  { }
1397
1450
  String_Constant(ParserState pstate, const char* beg)
1398
- : String(pstate), quote_mark_(0), value_(string(beg)), hash_(0)
1451
+ : String(pstate), quote_mark_(0), value_(read_css_string(string(beg))), hash_(0)
1399
1452
  { }
1400
1453
  String_Constant(ParserState pstate, const char* beg, const char* end)
1401
- : String(pstate), quote_mark_(0), value_(string(beg, end-beg)), hash_(0)
1454
+ : String(pstate), quote_mark_(0), value_(read_css_string(string(beg, end-beg))), hash_(0)
1402
1455
  { }
1403
1456
  String_Constant(ParserState pstate, const Token& tok)
1404
- : String(pstate), quote_mark_(0), value_(string(tok.begin, tok.end)), hash_(0)
1457
+ : String(pstate), quote_mark_(0), value_(read_css_string(string(tok.begin, tok.end))), hash_(0)
1405
1458
  { }
1406
1459
  string type() { return "string"; }
1407
1460
  static string type_name() { return "string"; }
@@ -1666,9 +1719,6 @@ namespace Sass {
1666
1719
  if (has_rest_parameter_) {
1667
1720
  error("functions and mixins cannot have more than one variable-length parameter", p->pstate());
1668
1721
  }
1669
- if (has_optional_parameters_) {
1670
- error("optional parameters may not be combined with variable-length parameters", p->pstate());
1671
- }
1672
1722
  has_rest_parameter_ = true;
1673
1723
  }
1674
1724
  else {
@@ -1695,6 +1745,22 @@ namespace Sass {
1695
1745
  //////////////////////////////////////////////////////////////////////////////////////////
1696
1746
  inline Expression* List::value_at_index(size_t i) { return is_arglist_ ? ((Argument*)(*this)[i])->value() : (*this)[i]; }
1697
1747
 
1748
+ ////////////
1749
+ // The Parent Selector Expression.
1750
+ ////////////
1751
+ class Parent_Selector : public Expression {
1752
+ ADD_PROPERTY(Selector*, selector);
1753
+ public:
1754
+ Parent_Selector(ParserState pstate, Selector* r = 0)
1755
+ : Expression(pstate), selector_(r)
1756
+ { concrete_type(SELECTOR); }
1757
+ virtual Selector* selector() { return selector_; }
1758
+ string type() { return "selector"; }
1759
+ static string type_name() { return "selector"; }
1760
+
1761
+ ATTACH_OPERATIONS();
1762
+ };
1763
+
1698
1764
  /////////////////////////////////////////
1699
1765
  // Abstract base class for CSS selectors.
1700
1766
  /////////////////////////////////////////
@@ -1722,7 +1788,9 @@ namespace Sass {
1722
1788
  { }
1723
1789
  virtual ~Selector() = 0;
1724
1790
  // virtual Selector_Placeholder* find_placeholder();
1725
- virtual int specificity() { return Constants::SPECIFICITY_BASE; }
1791
+ virtual unsigned long specificity() {
1792
+ return Constants::Specificity_Universal;
1793
+ };
1726
1794
  };
1727
1795
  inline Selector::~Selector() { }
1728
1796
 
@@ -1750,6 +1818,7 @@ namespace Sass {
1750
1818
  virtual ~Simple_Selector() = 0;
1751
1819
  virtual Compound_Selector* unify_with(Compound_Selector*, Context&);
1752
1820
  virtual bool is_pseudo_element() { return false; }
1821
+ virtual bool is_pseudo_class() { return false; }
1753
1822
 
1754
1823
  bool operator==(const Simple_Selector& rhs) const;
1755
1824
  inline bool operator!=(const Simple_Selector& rhs) const { return !(*this == rhs); }
@@ -1767,10 +1836,10 @@ namespace Sass {
1767
1836
  Selector_Reference(ParserState pstate, Selector* r = 0)
1768
1837
  : Simple_Selector(pstate), selector_(r)
1769
1838
  { has_reference(true); }
1770
- virtual int specificity()
1839
+ virtual unsigned long specificity()
1771
1840
  {
1772
- if (selector()) return selector()->specificity();
1773
- else return 0;
1841
+ if (!selector()) return 0;
1842
+ return selector()->specificity();
1774
1843
  }
1775
1844
  ATTACH_OPERATIONS();
1776
1845
  };
@@ -1797,10 +1866,11 @@ namespace Sass {
1797
1866
  Type_Selector(ParserState pstate, string n)
1798
1867
  : Simple_Selector(pstate), name_(n)
1799
1868
  { }
1800
- virtual int specificity()
1869
+ virtual unsigned long specificity()
1801
1870
  {
1802
- if (name() == "*") return 0;
1803
- else return 1;
1871
+ // ToDo: What is the specificity of the star selector?
1872
+ if (name() == "*") return Constants::Specificity_Universal;
1873
+ else return Constants::Specificity_Type;
1804
1874
  }
1805
1875
  virtual Compound_Selector* unify_with(Compound_Selector*, Context&);
1806
1876
  ATTACH_OPERATIONS();
@@ -1815,10 +1885,11 @@ namespace Sass {
1815
1885
  Selector_Qualifier(ParserState pstate, string n)
1816
1886
  : Simple_Selector(pstate), name_(n)
1817
1887
  { }
1818
- virtual int specificity()
1888
+ virtual unsigned long specificity()
1819
1889
  {
1820
- if (name()[0] == '#') return Constants::SPECIFICITY_BASE * Constants::SPECIFICITY_BASE;
1821
- else return Constants::SPECIFICITY_BASE;
1890
+ if (name()[0] == '#') return Constants::Specificity_ID;
1891
+ if (name()[0] == '.') return Constants::Specificity_Class;
1892
+ else return Constants::Specificity_Type;
1822
1893
  }
1823
1894
  virtual Compound_Selector* unify_with(Compound_Selector*, Context&);
1824
1895
  ATTACH_OPERATIONS();
@@ -1835,12 +1906,28 @@ namespace Sass {
1835
1906
  Attribute_Selector(ParserState pstate, string n, string m, String* v)
1836
1907
  : Simple_Selector(pstate), name_(n), matcher_(m), value_(v)
1837
1908
  { }
1909
+ virtual unsigned long specificity()
1910
+ {
1911
+ return Constants::Specificity_Attr;
1912
+ }
1838
1913
  ATTACH_OPERATIONS();
1839
1914
  };
1840
1915
 
1841
1916
  //////////////////////////////////////////////////////////////////
1842
1917
  // Pseudo selectors -- e.g., :first-child, :nth-of-type(...), etc.
1843
1918
  //////////////////////////////////////////////////////////////////
1919
+ /* '::' starts a pseudo-element, ':' a pseudo-class */
1920
+ /* Except :first-line, :first-letter, :before and :after */
1921
+ /* Note that pseudo-elements are restricted to one per selector */
1922
+ /* and occur only in the last simple_selector_sequence. */
1923
+ inline bool is_pseudo_class_element(const string& name)
1924
+ {
1925
+ return name == ":before" ||
1926
+ name == ":after" ||
1927
+ name == ":first-line" ||
1928
+ name == ":first-letter";
1929
+ }
1930
+
1844
1931
  class Pseudo_Selector : public Simple_Selector {
1845
1932
  ADD_PROPERTY(string, name);
1846
1933
  ADD_PROPERTY(String*, expression);
@@ -1848,29 +1935,33 @@ namespace Sass {
1848
1935
  Pseudo_Selector(ParserState pstate, string n, String* expr = 0)
1849
1936
  : Simple_Selector(pstate), name_(n), expression_(expr)
1850
1937
  { }
1851
- virtual int specificity()
1938
+
1939
+ // A pseudo-class always consists of a "colon" (:) followed by the name
1940
+ // of the pseudo-class and optionally by a value between parentheses.
1941
+ virtual bool is_pseudo_class()
1852
1942
  {
1853
- // TODO: clean up the pseudo-element checking
1854
- if (name() == ":before" || name() == "::before" ||
1855
- name() == ":after" || name() == "::after" ||
1856
- name() == ":first-line" || name() == "::first-line" ||
1857
- name() == ":first-letter" || name() == "::first-letter")
1858
- return 1;
1859
- else
1860
- return Constants::SPECIFICITY_BASE;
1943
+ return (name_[0] == ':' && name_[1] != ':')
1944
+ && ! is_pseudo_class_element(name_);
1861
1945
  }
1946
+
1947
+ // A pseudo-element is made of two colons (::) followed by the name.
1948
+ // The `::` notation is introduced by the current document in order to
1949
+ // establish a discrimination between pseudo-classes and pseudo-elements.
1950
+ // For compatibility with existing style sheets, user agents must also
1951
+ // accept the previous one-colon notation for pseudo-elements introduced
1952
+ // in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and
1953
+ // :after). This compatibility is not allowed for the new pseudo-elements
1954
+ // introduced in this specification.
1862
1955
  virtual bool is_pseudo_element()
1863
1956
  {
1864
- if (name() == ":before" || name() == "::before" ||
1865
- name() == ":after" || name() == "::after" ||
1866
- name() == ":first-line" || name() == "::first-line" ||
1867
- name() == ":first-letter" || name() == "::first-letter") {
1868
- return true;
1869
- }
1870
- else {
1871
- // If it's not a known pseudo-element, check whether it looks like one. This is similar to the type method on the Pseudo class in ruby sass.
1872
- return name().find("::") == 0;
1873
- }
1957
+ return (name_[0] == ':' && name_[1] == ':')
1958
+ || is_pseudo_class_element(name_);
1959
+ }
1960
+ virtual unsigned long specificity()
1961
+ {
1962
+ if (is_pseudo_element())
1963
+ return Constants::Specificity_Type;
1964
+ return Constants::Specificity_Pseudo;
1874
1965
  }
1875
1966
  virtual Compound_Selector* unify_with(Compound_Selector*, Context&);
1876
1967
  ATTACH_OPERATIONS();
@@ -1886,6 +1977,12 @@ namespace Sass {
1886
1977
  Wrapped_Selector(ParserState pstate, string n, Selector* sel)
1887
1978
  : Simple_Selector(pstate), name_(n), selector_(sel)
1888
1979
  { }
1980
+ // Selectors inside the negation pseudo-class are counted like any
1981
+ // other, but the negation itself does not count as a pseudo-class.
1982
+ virtual unsigned long specificity()
1983
+ {
1984
+ return selector_ ? selector_->specificity() : 0;
1985
+ }
1889
1986
  ATTACH_OPERATIONS();
1890
1987
  };
1891
1988
 
@@ -1926,7 +2023,7 @@ namespace Sass {
1926
2023
  return 0;
1927
2024
  }
1928
2025
  bool is_superselector_of(Compound_Selector* rhs);
1929
- virtual int specificity()
2026
+ virtual unsigned long specificity()
1930
2027
  {
1931
2028
  int sum = 0;
1932
2029
  for (size_t i = 0, L = length(); i < L; ++i)
@@ -1987,7 +2084,7 @@ namespace Sass {
1987
2084
  // virtual Selector_Placeholder* find_placeholder();
1988
2085
  Combinator clear_innermost();
1989
2086
  void set_innermost(Complex_Selector*, Combinator);
1990
- virtual int specificity() const
2087
+ virtual unsigned long specificity() const
1991
2088
  {
1992
2089
  int sum = 0;
1993
2090
  if (head()) sum += head()->specificity();
@@ -2068,9 +2165,9 @@ namespace Sass {
2068
2165
  : Selector(pstate), Vectorized<Complex_Selector*>(s), wspace_(0)
2069
2166
  { }
2070
2167
  // virtual Selector_Placeholder* find_placeholder();
2071
- virtual int specificity()
2168
+ virtual unsigned long specificity()
2072
2169
  {
2073
- int sum = 0;
2170
+ unsigned long sum = 0;
2074
2171
  for (size_t i = 0, L = length(); i < L; ++i)
2075
2172
  { sum += (*this)[i]->specificity(); }
2076
2173
  return sum;