sassc 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
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;