Skip to content
This repository
Browse code

Fixing up bugs and edge cases in the splat handling.

  • Loading branch information...
commit bc328bd220e909a9d43b381ea66faf6ceec4fc99 1 parent 451e9ca
Aaron Leung authored December 04, 2012
7  document_parser.cpp
@@ -254,7 +254,7 @@ namespace Sass {
254 254
     if (lex< exactly<'('> >()) {
255 255
       if (!peek< exactly<')'> >(position)) {
256 256
         do {
257  
-          Node arg(parse_argument(arg_type))
  257
+          Node arg(parse_argument(arg_type));
258 258
           args << arg;
259 259
           if (arg.type() == Node::assignment) {
260 260
             arg_type = Node::assignment;
@@ -742,7 +742,8 @@ namespace Sass {
742 742
     if (peek< exactly<';'> >(position) ||
743 743
         peek< exactly<'}'> >(position) ||
744 744
         peek< exactly<'{'> >(position) ||
745  
-        peek< exactly<')'> >(position))
  745
+        peek< exactly<')'> >(position) ||
  746
+        peek< exactly<ellipsis> >(position))
746 747
     { return context.new_Node(Node::list, path, line, 0); }
747 748
     Node list1(parse_space_list());
748 749
     // if it's a singleton, return it directly; don't wrap it
@@ -772,6 +773,7 @@ namespace Sass {
772 773
         peek< exactly<'{'> >(position) ||
773 774
         peek< exactly<')'> >(position) ||
774 775
         peek< exactly<','> >(position) ||
  776
+        peek< exactly<ellipsis> >(position) ||
775 777
         peek< default_flag >(position))
776 778
     { return disj1; }
777 779
     
@@ -784,6 +786,7 @@ namespace Sass {
784 786
              peek< exactly<'{'> >(position) ||
785 787
              peek< exactly<')'> >(position) ||
786 788
              peek< exactly<','> >(position) ||
  789
+             peek< exactly<ellipsis> >(position) ||
787 790
              peek< default_flag >(position)))
788 791
     {
789 792
       Node disj(parse_disjunction());
40  eval_apply.cpp
@@ -849,8 +849,14 @@ namespace Sass {
849 849
       if (j == num_params-1 && has_rest_params) {
850 850
         Node arglist(env[params[j].token()]);
851 851
         // collect rest-args
852  
-        for (size_t k = i; k < S; ++k) {
853  
-          arglist << args[k];
  852
+        if (args[i].type() == Node::list && args[i].is_arglist()) {
  853
+          arglist += args[i];
  854
+          arglist.is_comma_separated() = args[i].is_comma_separated();
  855
+        }
  856
+        else {
  857
+          for (size_t k = i; k < S; ++k) {
  858
+            arglist << args[k];
  859
+          }
854 860
         }
855 861
         break;
856 862
       }
@@ -861,8 +867,34 @@ namespace Sass {
861 867
       }
862 868
       // ordinal argument; just bind it and keep going
863 869
       else if (args[i].type() != Node::assignment) {
  870
+        // if it's a splat
864 871
         if (args[i].type() == Node::list && args[i].is_arglist()) {
865  
-
  872
+          // loop through the splatted list and bind each element to the remaining parameters
  873
+          for (size_t rest_i = 0, rest_length = args[i].size(); rest_i < rest_length; ++rest_i) {
  874
+            // if we're binding the last parameter
  875
+            if (j == num_params-1) {
  876
+              Node leftovers;
  877
+              if (has_rest_params) {
  878
+                leftovers = env[params[j].token()];
  879
+                leftovers.is_comma_separated() = args[i].is_comma_separated();
  880
+                for (; rest_i < rest_length; ++rest_i) {
  881
+                  leftovers << args[i][rest_i];
  882
+                }
  883
+              }
  884
+              else {
  885
+                leftovers = args[i][rest_i];
  886
+              }
  887
+              Node param(params[j]);
  888
+              env[param.type() != Node::assignment ? param.token() : param[0].token()] = leftovers;
  889
+            }
  890
+            // otherwise keep going normally
  891
+            else {
  892
+              Node param(params[j]);
  893
+              Token name = ((param.type() == Node::variable) ? param.token() : param[0].token());
  894
+              env[name] = args[i][rest_i];
  895
+              ++j;
  896
+            }
  897
+          }
866 898
         }
867 899
         else {
868 900
           Node arg(args[i]), param(params[j]);
@@ -907,6 +939,8 @@ namespace Sass {
907 939
     Node params(mixin[1]);
908 940
     Node body(new_Node(mixin[2])); // clone the body
909 941
     Node evaluated_args(eval_arguments(args, prefix, env, f_env, new_Node, ctx, bt));
  942
+    // cerr << evaluated_args.back().to_string() << endl;
  943
+    // cerr << evaluated_args.back().is_arglist() << endl;
910 944
     // Create a new environment for the mixin and link it to the appropriate parent
911 945
     Environment bindings;
912 946
     if (dynamic_scope) {
3  functions.cpp
@@ -1049,6 +1049,9 @@ namespace Sass {
1049 1049
           type_name = Token::make(color_name);
1050 1050
         } break;
1051 1051
         case Node::list: {
  1052
+          // cerr << val.to_string() << endl;
  1053
+          // cerr << val.is_arglist() << endl;
  1054
+          // throw (42);
1052 1055
           if (val.is_arglist())
1053 1056
             type_name = Token::make(arglist_name);
1054 1057
           else

0 notes on commit bc328bd

Please sign in to comment.
Something went wrong with that request. Please try again.