]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Support named arguments with ellipsis parameters
authorJürg Billeter <j@bitron.ch>
Wed, 21 Oct 2009 20:38:52 +0000 (22:38 +0200)
committerJürg Billeter <j@bitron.ch>
Wed, 21 Oct 2009 20:38:52 +0000 (22:38 +0200)
codegen/valaccodebasemodule.vala
codegen/valaccodegenerator.vala
codegen/valaccodemethodcallmodule.vala
codegen/valaccodemodule.vala
vala/Makefile.am
vala/valacodevisitor.vala
vala/valanamedargument.vala [new file with mode: 0644]
vala/valaparser.vala
vala/valasemanticanalyzer.vala

index 9966bff0c5644bcbde0f10a8c310a7d99d06e49f..4da1f2157f8d67268dec0c2dd50e921e3c3cf92f 100644 (file)
@@ -4020,6 +4020,12 @@ internal class Vala.CCodeBaseModule : CCodeModule {
                }
        }
        
+       public override void visit_named_argument (NamedArgument expr) {
+               expr.accept_children (codegen);
+
+               expr.ccodenode = expr.inner.ccodenode;
+       }
+
        public override void visit_pointer_indirection (PointerIndirection expr) {
                expr.ccodenode = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, (CCodeExpression) expr.inner.ccodenode);
        }
index ae8fb7c924ddb9e8bd4762d16be7dcb7b97ceba4..a0808a060f3c193878c55b802d79c51d27156f45 100644 (file)
@@ -303,7 +303,11 @@ public class Vala.CCodeGenerator : CodeGenerator {
        public override void visit_cast_expression (CastExpression expr) {
                head.visit_cast_expression (expr);
        }
-       
+
+       public override void visit_named_argument (NamedArgument expr) {
+               head.visit_named_argument (expr);
+       }
+
        public override void visit_pointer_indirection (PointerIndirection expr) {
                head.visit_pointer_indirection (expr);
        }
index b21a52d2fd5cd3a85d1980034bab8e4c55a9975e..c5a188db64036b6ca803be32558b3af102979bfb 100644 (file)
@@ -390,6 +390,12 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 
                        carg_map.set (arg_pos, cexpr);
 
+                       if (arg is NamedArgument && ellipsis) {
+                               var named_arg = (NamedArgument) arg;
+                               string name = string.joinv ("-", named_arg.name.split ("_"));
+                               carg_map.set (get_param_pos (i - 0.1, ellipsis), new CCodeConstant ("\"%s\"".printf (name)));
+                       }
+
                        i++;
                }
                if (params_it.next ()) {
index bfafe395c051ab9002557bf783447b9b9a836615..aa0d7c43c4d0fd88850e10ad78df1e1636790d5e 100644 (file)
@@ -282,7 +282,11 @@ public abstract class Vala.CCodeModule {
        public virtual void visit_cast_expression (CastExpression expr) {
                next.visit_cast_expression (expr);
        }
-       
+
+       public virtual void visit_named_argument (NamedArgument expr) {
+               next.visit_named_argument (expr);
+       }
+
        public virtual void visit_pointer_indirection (PointerIndirection expr) {
                next.visit_pointer_indirection (expr);
        }
index 685bab29a86723880e0052f913667368e4af1f92..17575dc7348bfa7021dbd5874ffcae3db039c1eb 100644 (file)
@@ -99,6 +99,7 @@ libvalacore_la_VALASOURCES = \
        valamethod.vala \
        valamethodcall.vala \
        valamethodtype.vala \
+       valanamedargument.vala \
        valanamespace.vala \
        valanullliteral.vala \
        valanulltype.vala \
index 65ddb23ead1c7d4ff23edf30097c2efca7f91ae0..cf9c74e2aac2b6be0f2ff0b096558121ec32e409 100644 (file)
@@ -556,6 +556,14 @@ public abstract class Vala.CodeVisitor {
        public virtual void visit_cast_expression (CastExpression expr) {
        }
 
+       /**
+        * Visit operation called for named arguments.
+        *
+        * @param expr a named argument
+        */
+       public virtual void visit_named_argument (NamedArgument expr) {
+       }
+
        /**
         * Visit operation called for pointer indirections.
         *
diff --git a/vala/valanamedargument.vala b/vala/valanamedargument.vala
new file mode 100644 (file)
index 0000000..8fe98d9
--- /dev/null
@@ -0,0 +1,90 @@
+/* valanamedargument.vala
+ *
+ * Copyright (C) 2009  Jürg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+public class Vala.NamedArgument : Expression {
+       public string name { get; set; }
+
+       public Expression inner {
+               get {
+                       return _inner;
+               }
+               set {
+                       _inner = value;
+                       _inner.parent_node = this;
+               }
+       }
+
+       private Expression _inner;
+
+       public NamedArgument (string name, Expression inner, SourceReference? source_reference = null) {
+               this.name = name;
+               this.inner = inner;
+               this.source_reference = source_reference;
+       }
+
+       public override void accept (CodeVisitor visitor) {
+               visitor.visit_named_argument (this);
+
+               visitor.visit_expression (this);
+       }
+
+       public override void accept_children (CodeVisitor visitor) {
+               inner.accept (visitor);
+       }
+
+       public override void replace_expression (Expression old_node, Expression new_node) {
+               if (inner == old_node) {
+                       inner = new_node;
+               }
+       }
+
+       public override bool is_pure () {
+               return inner.is_pure ();
+       }
+
+       public override bool check (SemanticAnalyzer analyzer) {
+               if (checked) {
+                       return !error;
+               }
+
+               checked = true;
+
+               inner.target_type = target_type;
+
+               if (!inner.check (analyzer)) {
+                       error = true;
+                       return false;
+               }
+
+               value_type = inner.value_type;
+
+               return !error;
+       }
+
+       public override void get_defined_variables (Collection<LocalVariable> collection) {
+               inner.get_defined_variables (collection);
+       }
+
+       public override void get_used_variables (Collection<LocalVariable> collection) {
+               inner.get_used_variables (collection);
+       }
+}
index cb544b2bb6cfa3d49299ad4e51353351c5e44e33..6828341f0b323da57d37113b3ce0c9cef5a6db9b 100644 (file)
@@ -520,7 +520,15 @@ public class Vala.Parser : CodeVisitor {
                        var inner = parse_expression ();
                        return new UnaryExpression (UnaryOperator.OUT, inner, get_src (begin));
                } else {
-                       return parse_expression ();
+                       var expr = parse_expression ();
+                       var ma = expr as MemberAccess;
+                       if (ma != null && ma.inner == null && accept (TokenType.COLON)) {
+                               // named argument
+                               expr = parse_expression ();
+                               return new NamedArgument (ma.member_name, expr, get_src (begin));
+                       } else {
+                               return expr;
+                       }
                }
        }
 
index cfdb05e4b6570444b4459c4edd86333e876b5f4f..b18fe9663b33239905e7b394edeb4797962411a8 100644 (file)
@@ -447,6 +447,9 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                if (arg.error) {
                        // ignore inner error
                        return false;
+               } else if (arg is NamedArgument) {
+                       Report.error (arg.source_reference, "Named arguments are not supported yet");
+                       return false;
                } else if (arg.value_type == null) {
                        // disallow untyped arguments except for type inference of callbacks
                        if (!(arg.target_type is DelegateType) || !(arg.symbol_reference is Method)) {