summaryrefslogtreecommitdiff
path: root/vala
diff options
context:
space:
mode:
authorSimon Werbeck <simon.werbeck@gmail.com>2014-08-14 23:46:17 +0200
committerLuca Bruno <lucabru@src.gnome.org>2014-11-17 00:47:13 +0100
commit11e6d28ab4dcbf93278c9f77489a05bf5cb8fce1 (patch)
treea3f3b05947f5fefabc939cdc13880a0e33d48c38 /vala
parent9644dd2a97fcc3e9a55cf90f322cdb1a901150cf (diff)
downloadvala-11e6d28ab4dcbf93278c9f77489a05bf5cb8fce1.tar.gz
Recursively infer generic type arguments
Slightly changed by Luca Bruno. Fixes bug 626783
Diffstat (limited to 'vala')
-rw-r--r--vala/valaarraytype.vala9
-rw-r--r--vala/valadatatype.vala18
-rw-r--r--vala/valagenerictype.vala10
-rw-r--r--vala/valamethodcall.vala12
-rw-r--r--vala/valapointertype.vala9
5 files changed, 49 insertions, 9 deletions
diff --git a/vala/valaarraytype.vala b/vala/valaarraytype.vala
index 941485a1f..d993e3c93 100644
--- a/vala/valaarraytype.vala
+++ b/vala/valaarraytype.vala
@@ -272,6 +272,15 @@ public class Vala.ArrayType : ReferenceType {
return result;
}
+ public override DataType? infer_type_argument (TypeParameter type_param, DataType value_type) {
+ var array_type = value_type as ArrayType;
+ if (array_type != null) {
+ return element_type.infer_type_argument (type_param, array_type.element_type);
+ }
+
+ return null;
+ }
+
public override bool is_disposable () {
if (fixed_length) {
return element_type.is_disposable ();
diff --git a/vala/valadatatype.vala b/vala/valadatatype.vala
index 352885bfd..02b4cf13f 100644
--- a/vala/valadatatype.vala
+++ b/vala/valadatatype.vala
@@ -462,6 +462,24 @@ public abstract class Vala.DataType : CodeNode {
return result;
}
+ /**
+ * Search for the type parameter in this formal type and match it in
+ * value_type.
+ */
+ public virtual DataType? infer_type_argument (TypeParameter type_param, DataType value_type) {
+ var value_type_arg_it = value_type.get_type_arguments ().iterator ();
+ foreach (var formal_type_arg in this.get_type_arguments ()) {
+ if (value_type_arg_it.next ()) {
+ var inferred_type = formal_type_arg.infer_type_argument (type_param, value_type_arg_it.get ());
+ if (inferred_type != null) {
+ return inferred_type;
+ }
+ }
+ }
+
+ return null;
+ }
+
public bool is_weak () {
if (this.value_owned) {
return false;
diff --git a/vala/valagenerictype.vala b/vala/valagenerictype.vala
index 49a4c5723..66415e6f9 100644
--- a/vala/valagenerictype.vala
+++ b/vala/valagenerictype.vala
@@ -42,6 +42,16 @@ public class Vala.GenericType : DataType {
return result;
}
+ public override DataType? infer_type_argument (TypeParameter type_param, DataType value_type) {
+ if (type_parameter == type_param) {
+ var ret = value_type.copy ();
+ ret.value_owned = true;
+ return ret;
+ }
+
+ return null;
+ }
+
public override string to_qualified_string (Scope? scope = null) {
return type_parameter.name;
}
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index efce5483a..0229e40b7 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -536,10 +536,8 @@ public class Vala.MethodCall : Expression {
if (arg_it.next ()) {
Expression arg = arg_it.get ();
- var generic_type = param.variable_type as GenericType;
- if (generic_type != null && generic_type.type_parameter == type_param) {
- type_arg = arg.value_type.copy ();
- type_arg.value_owned = true;
+ type_arg = param.variable_type.infer_type_argument (type_param, arg.value_type);
+ if (type_arg != null) {
break;
}
@@ -549,11 +547,7 @@ public class Vala.MethodCall : Expression {
// infer type arguments from expected return type
if (type_arg == null && target_type != null) {
- var generic_type = m.return_type as GenericType;
- if (generic_type != null && generic_type.type_parameter == type_param) {
- type_arg = target_type.copy ();
- type_arg.value_owned = true;
- }
+ type_arg = m.return_type.infer_type_argument (type_param, target_type);
}
if (type_arg == null) {
diff --git a/vala/valapointertype.vala b/vala/valapointertype.vala
index 822123e91..461983c30 100644
--- a/vala/valapointertype.vala
+++ b/vala/valapointertype.vala
@@ -137,6 +137,15 @@ public class Vala.PointerType : DataType {
return result;
}
+ public override DataType? infer_type_argument (TypeParameter type_param, DataType value_type) {
+ var pointer_type = value_type as PointerType;
+ if (pointer_type != null) {
+ return base_type.infer_type_argument (type_param, pointer_type.base_type);
+ }
+
+ return null;
+ }
+
public override bool check (CodeContext context) {
error = !base_type.check (context);
return !error;