[vala] Support named arguments with ellipsis parameters



commit 7786b0edf14b513d82f7315c2c63ec14488ca7a8
Author: Jürg Billeter <j bitron ch>
Date:   Wed Oct 21 22:38:52 2009 +0200

    Support named arguments with ellipsis parameters

 codegen/valaccodebasemodule.vala       |    6 ++
 codegen/valaccodegenerator.vala        |    6 ++-
 codegen/valaccodemethodcallmodule.vala |    6 ++
 codegen/valaccodemodule.vala           |    6 ++-
 vala/Makefile.am                       |    1 +
 vala/valacodevisitor.vala              |    8 +++
 vala/valanamedargument.vala            |   90 ++++++++++++++++++++++++++++++++
 vala/valaparser.vala                   |   10 +++-
 vala/valasemanticanalyzer.vala         |    3 +
 9 files changed, 133 insertions(+), 3 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 9966bff..4da1f21 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -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);
 	}
diff --git a/codegen/valaccodegenerator.vala b/codegen/valaccodegenerator.vala
index ae8fb7c..a0808a0 100644
--- a/codegen/valaccodegenerator.vala
+++ b/codegen/valaccodegenerator.vala
@@ -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);
 	}
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index b21a52d..c5a188d 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -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 ()) {
diff --git a/codegen/valaccodemodule.vala b/codegen/valaccodemodule.vala
index bfafe39..aa0d7c4 100644
--- a/codegen/valaccodemodule.vala
+++ b/codegen/valaccodemodule.vala
@@ -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);
 	}
diff --git a/vala/Makefile.am b/vala/Makefile.am
index 685bab2..17575dc 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -99,6 +99,7 @@ libvalacore_la_VALASOURCES = \
 	valamethod.vala \
 	valamethodcall.vala \
 	valamethodtype.vala \
+	valanamedargument.vala \
 	valanamespace.vala \
 	valanullliteral.vala \
 	valanulltype.vala \
diff --git a/vala/valacodevisitor.vala b/vala/valacodevisitor.vala
index 65ddb23..cf9c74e 100644
--- a/vala/valacodevisitor.vala
+++ b/vala/valacodevisitor.vala
@@ -557,6 +557,14 @@ public abstract class Vala.CodeVisitor {
 	}
 
 	/**
+	 * 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.
 	 *
 	 * @param expr a pointer indirection
diff --git a/vala/valanamedargument.vala b/vala/valanamedargument.vala
new file mode 100644
index 0000000..8fe98d9
--- /dev/null
+++ b/vala/valanamedargument.vala
@@ -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);
+	}
+}
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index cb544b2..6828341 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -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;
+			}
 		}
 	}
 
diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala
index cfdb05e..b18fe96 100644
--- a/vala/valasemanticanalyzer.vala
+++ b/vala/valasemanticanalyzer.vala
@@ -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)) {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]