var cb = dt.delegate_symbol;
/* check whether method matches callback type */
- if (!cb.matches_method (m)) {
+ if (!cb.matches_method (m, dt)) {
error = true;
Report.error (source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
return false;
var cb = dt.delegate_symbol;
/* check whether method matches callback type */
- if (!cb.matches_method (m)) {
+ if (!cb.matches_method (m, dt)) {
f.error = true;
Report.error (source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
return false;
write_string (" ");
write_identifier (cb.name);
-
+
+ var type_params = cb.get_type_parameters ();
+ if (type_params.size > 0) {
+ write_string ("<");
+ bool first = true;
+ foreach (TypeParameter type_param in type_params) {
+ if (first) {
+ first = false;
+ } else {
+ write_string (",");
+ }
+ write_identifier (type_param.name);
+ }
+ write_string (">");
+ }
+
write_string (" ");
write_params (cb.get_parameters ());
type_parameters.add (p);
scope.add (p.name, p);
}
-
+
+ public List<TypeParameter> get_type_parameters () {
+ return type_parameters;
+ }
+
+ public override int get_type_parameter_index (string name) {
+ int i = 0;
+ foreach (TypeParameter parameter in type_parameters) {
+ if (parameter.name == name) {
+ return i;
+ }
+ i++;
+ }
+ return -1;
+ }
+
/**
* Appends paramater to this callback function.
*
* @param m a method
* @return true if the specified method is compatible to this callback
*/
- public bool matches_method (Method m) {
+ public bool matches_method (Method m, DataType dt) {
// method is allowed to ensure stricter return type (stronger postcondition)
- if (!m.return_type.stricter (return_type)) {
+ if (!m.return_type.stricter (return_type.get_actual_type (dt, null, this))) {
return false;
}
// method is allowed to accept arguments of looser types (weaker precondition)
var method_param = method_params_it.get ();
- if (!param.parameter_type.stricter (method_param.parameter_type)) {
+ if (!param.parameter_type.get_actual_type (dt, null, this).stricter (method_param.parameter_type)) {
return false;
}
}
/* valadelegatetype.vala
*
- * Copyright (C) 2007-2009 Jürg Billeter
+ * Copyright (C) 2007-2010 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
public override string to_qualified_string (Scope? scope) {
string s = delegate_symbol.get_full_name ();
+
+ var type_args = get_type_arguments ();
+ if (type_args.size > 0) {
+ s += "<";
+ bool first = true;
+ foreach (DataType type_arg in type_args) {
+ if (!first) {
+ s += ",";
+ } else {
+ first = false;
+ }
+ if (!type_arg.value_owned) {
+ s += "weak ";
+ }
+ s += type_arg.to_qualified_string (scope);
+ }
+ s += ">";
+ }
if (nullable) {
s += "?";
}
}
string lambda_param = lambda_param_it.get ();
- var param = new FormalParameter (lambda_param, cb_param.parameter_type);
+ var param_type = cb_param.parameter_type.get_actual_type (target_type, null, this);
+ var param = new FormalParameter (lambda_param, param_type);
method.add_parameter (param);
}
var cb = dt.delegate_symbol;
/* check whether method matches callback type */
- if (!cb.matches_method (m)) {
+ if (!cb.matches_method (m, dt)) {
error = true;
Report.error (source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
return false;
// type of target object
DataType target_object_type = null;
- if (call is MemberAccess) {
+ if (call.value_type is DelegateType) {
+ // delegate invocation, resolve generic types relative to delegate
+ target_object_type = call.value_type;
+ } else if (call is MemberAccess) {
var ma = (MemberAccess) call;
if (ma.prototype_access) {
error = true;
return false;
}
- return dt.delegate_symbol.matches_method (method_symbol);
+ return dt.delegate_symbol.matches_method (method_symbol, dt);
}
public override string to_qualified_string (Scope? scope) {
}
}
- if (instance_type.data_type == type_symbol) {
+ if (instance_type is DelegateType && ((DelegateType) instance_type).delegate_symbol == type_symbol) {
+ return instance_type;
+ } else if (instance_type.data_type == type_symbol) {
return instance_type;
}
assert (instance_type != null);
- int param_index = instance_type.data_type.get_type_parameter_index (generic_type.type_parameter.name);
+ int param_index;
+ if (instance_type is DelegateType) {
+ param_index = ((DelegateType) instance_type).delegate_symbol.get_type_parameter_index (generic_type.type_parameter.name);
+ } else {
+ param_index = instance_type.data_type.get_type_parameter_index (generic_type.type_parameter.name);
+ }
if (param_index == -1) {
Report.error (node_reference.source_reference, "internal error: unknown type parameter %s".printf (generic_type.type_parameter.name));
node_reference.error = true;
}
}
- init.initializer.target_type = member_type;
+ init.initializer.formal_target_type = member_type;
+ init.initializer.target_type = init.initializer.formal_target_type.get_actual_type (type, null, init);;
init.check (this);