vala r2021 - in trunk: . gobject vala
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r2021 - in trunk: . gobject vala
- Date: Fri, 14 Nov 2008 20:57:37 +0000 (UTC)
Author: juergbi
Date: Fri Nov 14 20:57:37 2008
New Revision: 2021
URL: http://svn.gnome.org/viewvc/vala?rev=2021&view=rev
Log:
2008-11-14 JÃrg Billeter <j bitron ch>
* vala/valaformalparameter.vala:
* vala/valainterfacewriter.vala:
* vala/valainvocationexpression.vala:
* vala/valaparser.vala:
* vala/valascanner.vala:
* vala/valasemanticanalyzer.vala:
* vala/valatokentype.vala:
* gobject/valaccodeinvocationexpressionmodule.vala:
Support parameter arrays, fixes bug 538897
Modified:
trunk/ChangeLog
trunk/gobject/valaccodeinvocationexpressionmodule.vala
trunk/vala/valaformalparameter.vala
trunk/vala/valainterfacewriter.vala
trunk/vala/valainvocationexpression.vala
trunk/vala/valaparser.vala
trunk/vala/valascanner.vala
trunk/vala/valasemanticanalyzer.vala
trunk/vala/valatokentype.vala
Modified: trunk/gobject/valaccodeinvocationexpressionmodule.vala
==============================================================================
--- trunk/gobject/valaccodeinvocationexpressionmodule.vala (original)
+++ trunk/gobject/valaccodeinvocationexpressionmodule.vala Fri Nov 14 20:57:37 2008
@@ -171,7 +171,7 @@
CCodeExpression cexpr = (CCodeExpression) arg.ccodenode;
if (params_it.next ()) {
var param = params_it.get ();
- ellipsis = param.ellipsis;
+ ellipsis = param.params_array || param.ellipsis;
if (!ellipsis) {
// if the vala argument expands to multiple C arguments,
// we have to make sure that the C arguments don't depend
@@ -311,7 +311,7 @@
* the additional parameter is an ellipsis parameter
* otherwise there is a bug in the semantic analyzer
*/
- assert (param.ellipsis);
+ assert (param.params_array || param.ellipsis);
ellipsis = true;
}
Modified: trunk/vala/valaformalparameter.vala
==============================================================================
--- trunk/vala/valaformalparameter.vala (original)
+++ trunk/vala/valaformalparameter.vala Fri Nov 14 20:57:37 2008
@@ -48,6 +48,12 @@
public bool ellipsis { get; set; }
/**
+ * Specifies whether the methods accepts an indefinite number of
+ * parameters.
+ */
+ public bool params_array { get; set; }
+
+ /**
* Specifies the expression used when the caller doesn't supply an
* argument for this parameter.
*/
@@ -161,6 +167,7 @@
public FormalParameter copy () {
if (!ellipsis) {
var result = new FormalParameter (name, parameter_type, source_reference);
+ result.params_array = params_array;
return result;
} else {
return new FormalParameter.with_ellipsis ();
@@ -191,6 +198,12 @@
if (!ellipsis) {
parameter_type.check (analyzer);
+ if (params_array && !(parameter_type is ArrayType)) {
+ error = true;
+ Report.error (source_reference, "parameter array expected");
+ return false;
+ }
+
if (default_expression != null) {
default_expression.check (analyzer);
}
Modified: trunk/vala/valainterfacewriter.vala
==============================================================================
--- trunk/vala/valainterfacewriter.vala (original)
+++ trunk/vala/valainterfacewriter.vala Fri Nov 14 20:57:37 2008
@@ -721,6 +721,10 @@
write_string ("[CCode (%s)] ".printf (ccode_params.str));
}
+ if (param.params_array) {
+ write_string ("params ");
+ }
+
if (param.direction != ParameterDirection.IN) {
if (param.direction == ParameterDirection.REF) {
write_string ("ref ");
Modified: trunk/vala/valainvocationexpression.vala
==============================================================================
--- trunk/vala/valainvocationexpression.vala (original)
+++ trunk/vala/valainvocationexpression.vala Fri Nov 14 20:57:37 2008
@@ -204,6 +204,18 @@
break;
}
+ if (param.params_array) {
+ var array_type = (ArrayType) param.parameter_type;
+ while (arg_it.next ()) {
+ Expression arg = arg_it.get ();
+
+ /* store expected type for callback parameters */
+ arg.target_type = array_type.element_type;
+ arg.target_type.value_owned = array_type.value_owned;
+ }
+ break;
+ }
+
if (arg_it.next ()) {
Expression arg = arg_it.get ();
Modified: trunk/vala/valaparser.vala
==============================================================================
--- trunk/vala/valaparser.vala (original)
+++ trunk/vala/valaparser.vala Fri Nov 14 20:57:37 2008
@@ -207,6 +207,7 @@
case TokenType.NULL:
case TokenType.OUT:
case TokenType.OVERRIDE:
+ case TokenType.PARAMS:
case TokenType.PRIVATE:
case TokenType.PROTECTED:
case TokenType.PUBLIC:
@@ -2699,6 +2700,7 @@
// varargs
return new FormalParameter.with_ellipsis (get_src (begin));
}
+ bool params_array = accept (TokenType.PARAMS);
bool construct_param = false;
if (accept (TokenType.CONSTRUCT)) {
Report.warning (get_last_src (), "deprecated syntax, use assignments in the method body");
@@ -2723,6 +2725,7 @@
var param = new FormalParameter (id, type, get_src (begin));
set_attributes (param, attrs);
param.direction = direction;
+ param.params_array = params_array;
param.construct_parameter = construct_param;
if (accept (TokenType.ASSIGN)) {
param.default_expression = parse_expression ();
Modified: trunk/vala/valascanner.vala
==============================================================================
--- trunk/vala/valascanner.vala (original)
+++ trunk/vala/valascanner.vala Fri Nov 14 20:57:37 2008
@@ -192,7 +192,14 @@
if (matches (begin, "inline")) return TokenType.INLINE;
break;
case 'p':
- if (matches (begin, "public")) return TokenType.PUBLIC;
+ switch (begin[1]) {
+ case 'a':
+ if (matches (begin, "params")) return TokenType.PARAMS;
+ break;
+ case 'u':
+ if (matches (begin, "public")) return TokenType.PUBLIC;
+ break;
+ }
break;
case 'r':
if (matches (begin, "return")) return TokenType.RETURN;
Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala (original)
+++ trunk/vala/valasemanticanalyzer.vala Fri Nov 14 20:57:37 2008
@@ -287,6 +287,20 @@
/* header file necessary if we need to cast argument */
current_source_file.add_type_dependency (param.parameter_type, SourceFileDependencyType.SOURCE);
+ if (param.params_array) {
+ while (arg_it.next ()) {
+ var arg = arg_it.get ();
+ if (!check_argument (arg, i, param.direction)) {
+ expr.error = true;
+ return false;
+ }
+
+ i++;
+ }
+
+ break;
+ }
+
if (arg_it == null || !arg_it.next ()) {
if (param.default_expression == null) {
expr.error = true;
@@ -306,83 +320,9 @@
}
} else {
var arg = arg_it.get ();
- if (arg.error) {
- // ignore inner error
+ if (!check_argument (arg, i, param.direction)) {
expr.error = true;
return false;
- } else if (arg.value_type == null) {
- // disallow untyped arguments except for type inference of callbacks
- if (!(param.parameter_type is DelegateType) || !(arg.symbol_reference is Method)) {
- expr.error = true;
- Report.error (arg.source_reference, "Invalid type for argument %d".printf (i + 1));
- return false;
- }
- } else if (arg.target_type != null && !arg.value_type.compatible (arg.target_type)
- && !(arg is NullLiteral && param.direction == ParameterDirection.OUT)) {
- expr.error = true;
- Report.error (arg.source_reference, "Argument %d: Cannot convert from `%s' to `%s'".printf (i + 1, arg.value_type.to_string (), arg.target_type.to_string ()));
- return false;
- } else {
- // 0 => null, 1 => in, 2 => ref, 3 => out
- int arg_type = 1;
- if (arg.value_type is NullType) {
- arg_type = 0;
- } else if (arg is UnaryExpression) {
- var unary = (UnaryExpression) arg;
- if (unary.operator == UnaryOperator.REF) {
- arg_type = 2;
- } else if (unary.operator == UnaryOperator.OUT) {
- arg_type = 3;
- }
- }
-
- if (arg_type == 0) {
- if (param.direction == ParameterDirection.REF) {
- expr.error = true;
- Report.error (arg.source_reference, "Argument %d: Cannot pass null to reference parameter".printf (i + 1));
- return false;
- } else if (context.non_null && param.direction != ParameterDirection.OUT && !param.parameter_type.nullable) {
- Report.warning (arg.source_reference, "Argument %d: Cannot pass null to non-null parameter type".printf (i + 1));
- }
- } else if (arg_type == 1) {
- if (param.direction != ParameterDirection.IN) {
- expr.error = true;
- Report.error (arg.source_reference, "Argument %d: Cannot pass value to reference or output parameter".printf (i + 1));
- return false;
- }
- } else if (arg_type == 2) {
- if (param.direction != ParameterDirection.REF) {
- expr.error = true;
- Report.error (arg.source_reference, "Argument %d: Cannot pass ref argument to non-reference parameter".printf (i + 1));
- return false;
- }
-
- // weak variables can only be used with weak ref parameters
- if (param.parameter_type.is_disposable ()) {
- if (!(arg.value_type is PointerType) && !arg.value_type.value_owned) {
- /* variable doesn't own the value */
- expr.error = true;
- Report.error (arg.source_reference, "Invalid assignment from owned expression to unowned variable");
- return false;
- }
- }
- } else if (arg_type == 3) {
- if (param.direction != ParameterDirection.OUT) {
- expr.error = true;
- Report.error (arg.source_reference, "Argument %d: Cannot pass out argument to non-output parameter".printf (i + 1));
- return false;
- }
-
- // weak variables can only be used with weak out parameters
- if (param.parameter_type.is_disposable ()) {
- if (!(arg.value_type is PointerType) && !arg.value_type.value_owned) {
- /* variable doesn't own the value */
- expr.error = true;
- Report.error (arg.source_reference, "Invalid assignment from owned expression to unowned variable");
- return false;
- }
- }
- }
}
prev_arg = arg;
@@ -430,6 +370,79 @@
return true;
}
+ bool check_argument (Expression arg, int i, ParameterDirection direction) {
+ if (arg.error) {
+ // ignore inner error
+ 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)) {
+ Report.error (arg.source_reference, "Invalid type for argument %d".printf (i + 1));
+ return false;
+ }
+ } else if (arg.target_type != null && !arg.value_type.compatible (arg.target_type)
+ && !(arg is NullLiteral && direction == ParameterDirection.OUT)) {
+ Report.error (arg.source_reference, "Argument %d: Cannot convert from `%s' to `%s'".printf (i + 1, arg.value_type.to_string (), arg.target_type.to_string ()));
+ return false;
+ } else {
+ // 0 => null, 1 => in, 2 => ref, 3 => out
+ int arg_type = 1;
+ if (arg.value_type is NullType) {
+ arg_type = 0;
+ } else if (arg is UnaryExpression) {
+ var unary = (UnaryExpression) arg;
+ if (unary.operator == UnaryOperator.REF) {
+ arg_type = 2;
+ } else if (unary.operator == UnaryOperator.OUT) {
+ arg_type = 3;
+ }
+ }
+
+ if (arg_type == 0) {
+ if (direction == ParameterDirection.REF) {
+ Report.error (arg.source_reference, "Argument %d: Cannot pass null to reference parameter".printf (i + 1));
+ return false;
+ } else if (context.non_null && direction != ParameterDirection.OUT && !arg.target_type.nullable) {
+ Report.warning (arg.source_reference, "Argument %d: Cannot pass null to non-null parameter type".printf (i + 1));
+ }
+ } else if (arg_type == 1) {
+ if (direction != ParameterDirection.IN) {
+ Report.error (arg.source_reference, "Argument %d: Cannot pass value to reference or output parameter".printf (i + 1));
+ return false;
+ }
+ } else if (arg_type == 2) {
+ if (direction != ParameterDirection.REF) {
+ Report.error (arg.source_reference, "Argument %d: Cannot pass ref argument to non-reference parameter".printf (i + 1));
+ return false;
+ }
+
+ // weak variables can only be used with weak ref parameters
+ if (arg.target_type.is_disposable ()) {
+ if (!(arg.value_type is PointerType) && !arg.value_type.value_owned) {
+ /* variable doesn't own the value */
+ Report.error (arg.source_reference, "Invalid assignment from owned expression to unowned variable");
+ return false;
+ }
+ }
+ } else if (arg_type == 3) {
+ if (direction != ParameterDirection.OUT) {
+ Report.error (arg.source_reference, "Argument %d: Cannot pass out argument to non-output parameter".printf (i + 1));
+ return false;
+ }
+
+ // weak variables can only be used with weak out parameters
+ if (arg.target_type.is_disposable ()) {
+ if (!(arg.value_type is PointerType) && !arg.value_type.value_owned) {
+ /* variable doesn't own the value */
+ Report.error (arg.source_reference, "Invalid assignment from owned expression to unowned variable");
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
private static DataType? get_instance_base_type (DataType instance_type, DataType base_type, CodeNode node_reference) {
// construct a new type reference for the base type with correctly linked type arguments
ReferenceType instance_base_type;
Modified: trunk/vala/valatokentype.vala
==============================================================================
--- trunk/vala/valatokentype.vala (original)
+++ trunk/vala/valatokentype.vala Fri Nov 14 20:57:37 2008
@@ -107,6 +107,7 @@
OPEN_BRACKET,
OPEN_PARENS,
OVERRIDE,
+ PARAMS,
PERCENT,
PLUS,
PRIVATE,
@@ -225,6 +226,7 @@
case OPEN_BRACKET: return "`['";
case OPEN_PARENS: return "`('";
case OVERRIDE: return "`override'";
+ case PARAMS: return "`params'";
case PERCENT: return "`%'";
case PLUS: return "`+'";
case PRIVATE: return "`private'";
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]