2007-12-14 Jürg Billeter <j@bitron.ch>
+ * vala/Makefile.am, vala/valadatatype.vala, vala/valadelegatetype.vala,
+ vala/valafield.vala, vala/valaformalparameter.vala,
+ vala/valainterfacewriter.vala, vala/valainvokable.vala,
+ vala/valamemorymanager.vala, vala/valamethod.vala,
+ vala/valamethodtype.vala, vala/valasemanticanalyzer.vala,
+ vala/valasignal.vala, vala/valasignaltype.vala,
+ vala/valasymbolresolver.vala, vala/valavariabledeclarator.vala,
+ gobject/valaccodegenerator.vala,
+ gobject/valaccodegeneratorinvocationexpression.vala: replace Invokable
+ interface by DelegateType, MethodType, and SignalType classes
+
+2007-12-14 Jürg Billeter <j@bitron.ch>
+
* gobject/valaccodegeneratorinvocationexpression.vala: fix exception
handling with ellipsis parameters
var local_vars = b.get_local_variables ();
foreach (VariableDeclarator decl in local_vars) {
- if (decl.active && decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
+ if (decl.active && decl.type_reference.data_type != null && decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
found = true;
var ma = new MemberAccess.simple (decl.name);
ma.symbol_reference = decl;
var ma = (MemberAccess) expr.call;
- if (expr.call.symbol_reference is Invokable) {
- var i = (Invokable) expr.call.symbol_reference;
- params = i.get_parameters ();
-
- if (i is Method) {
- m = (Method) i;
- } else if (i is Signal) {
- ccall = (CCodeFunctionCall) expr.call.ccodenode;
- }
+ var itype = expr.call.static_type;
+ params = itype.get_parameters ();
+
+ if (itype is MethodType) {
+ m = ((MethodType) itype).method_symbol;
+ } else if (itype is SignalType) {
+ ccall = (CCodeFunctionCall) expr.call.ccodenode;
}
if (m is ArrayResizeMethod) {
valacreationmethod.vala \
valadatatype.vala \
valadeclarationstatement.vala \
+ valadelegatetype.vala \
valadestructor.vala \
valadostatement.vala \
valaelementaccess.vala \
valainterface.vala \
valainterfacewriter.vala \
valainvocationexpression.vala \
- valainvokable.vala \
valalambdaexpression.vala \
valaliteral.vala \
valaliteralexpression.vala \
valamemberinitializer.vala \
valamemorymanager.vala \
valamethod.vala \
+ valamethodtype.vala \
valanamedargument.vala \
valanamespace.vala \
valanamespacereference.vala \
valascope.vala \
valasemanticanalyzer.vala \
valasignal.vala \
+ valasignaltype.vala \
valasizeofexpression.vala \
valasourcefile.vala \
valasourcefilecycle.vala \
*
* @return the type string to be used in C code
*/
- public string get_cname (bool var_type = false, bool const_type = false) {
+ public virtual string get_cname (bool var_type = false, bool const_type = false) {
if (data_type == null && type_parameter == null) {
if (var_type) {
return "gpointer";
return "const %s%s".printf (t.get_cname (), ptr);
}
-
- /**
- * Returns a user-readable name of the type corresponding to this type
- * reference.
- *
- * @return display name
- */
- public string! to_string () {
+
+ public override string! to_string () {
+ string s;
+
if (data_type != null) {
- return data_type.get_full_name ();
+ s = data_type.get_full_name ();
} else if (type_parameter != null) {
- return type_parameter.name;
+ s = type_parameter.name;
} else {
- return "null";
+ s = "null";
}
+
+ var type_args = get_type_arguments ();
+ if (!(data_type is Array) && type_args.size > 0) {
+ s += "<";
+ bool first = true;
+ foreach (DataType type_arg in type_args) {
+ if (!first) {
+ s += ",";
+ } else {
+ first = false;
+ }
+ if (!type_arg.takes_ownership) {
+ s += "weak ";
+ }
+ if (type_arg.data_type != null) {
+ s += type_arg.data_type.get_full_name ();
+ } else {
+ s += type_arg.type_parameter.name;
+ }
+ }
+ s += ">";
+ }
+ if (non_null) {
+ s += "!";
+ }
+
+ return s;
}
/**
}
}
}
+
+ /**
+ * Returns whether instances of this type are invokable.
+ *
+ * @return true if invokable, false otherwise
+ */
+ public virtual bool is_invokable () {
+ return false;
+ }
+
+ /**
+ * Returns the return type of this invokable.
+ *
+ * @return return type
+ */
+ public virtual DataType get_return_type () {
+ return null;
+ }
+
+ /**
+ * Returns copy of the list of invocation parameters.
+ *
+ * @return parameter list
+ */
+ public virtual Collection<FormalParameter> get_parameters () {
+ return null;
+ }
}
--- /dev/null
+/* valadelegatetype.vala
+ *
+ * Copyright (C) 2007 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>
+ */
+
+using GLib;
+using Gee;
+
+/**
+ * The type of an instance of a delegate.
+ */
+public class Vala.DelegateType : DataType {
+ public Callback delegate_symbol { get; set; }
+
+ public DelegateType (construct Callback delegate_symbol) {
+ }
+
+ public override bool is_invokable () {
+ return true;
+ }
+
+ public override DataType get_return_type () {
+ return delegate_symbol.return_type;
+ }
+
+ public override Collection<FormalParameter> get_parameters () {
+ return delegate_symbol.get_parameters ();
+ }
+
+ public override string! to_string () {
+ return delegate_symbol.get_full_name ();
+ }
+
+ public override DataType! copy () {
+ return new DelegateType (delegate_symbol);
+ }
+
+ public override string get_cname (bool var_type = false, bool const_type = false) {
+ return delegate_symbol.get_cname (const_type);
+ }
+}
/**
* Represents a type or namespace field.
*/
-public class Vala.Field : Member, Invokable, Lockable {
+public class Vala.Field : Member, Lockable {
/**
* The data type of this field.
*/
}
}
- public Collection<FormalParameter> get_parameters () {
- if (!is_invokable ()) {
- return null;
- }
-
- var cb = (Callback) type_reference.data_type;
- return cb.get_parameters ();
- }
-
- public DataType get_return_type () {
- if (!is_invokable ()) {
- return null;
- }
-
- var cb = (Callback) type_reference.data_type;
- return cb.return_type;
- }
-
- public bool is_invokable () {
- return (type_reference.data_type is Callback);
- }
-
public bool get_lock_used () {
return lock_used;
}
/**
* Represents a formal parameter in method and callback signatures.
*/
-public class Vala.FormalParameter : Symbol, Invokable {
+public class Vala.FormalParameter : Symbol {
/**
* The parameter type.
*/
}
}
- public Collection<FormalParameter> get_parameters () {
- if (!is_invokable ()) {
- return null;
- }
-
- var cb = (Callback) type_reference.data_type;
- return cb.get_parameters ();
- }
-
- public DataType get_return_type () {
- if (!is_invokable ()) {
- return null;
- }
-
- var cb = (Callback) type_reference.data_type;
- return cb.return_type;
- }
-
- public bool is_invokable () {
- return (type_reference.data_type is Callback);
- }
-
public override void replace_type (DataType! old_type, DataType! new_type) {
if (type_reference == old_type) {
type_reference = new_type;
}
private void write_type (DataType! type) {
- if (type.data_type != null) {
- write_string (type.data_type.get_full_name ());
- } else {
- write_string (type.type_parameter.name);
- }
-
- var type_args = type.get_type_arguments ();
- if (!(type.data_type is Array) && type_args.size > 0) {
- write_string ("<");
- bool first = true;
- foreach (DataType type_arg in type_args) {
- if (!first) {
- write_string (",");
- } else {
- first = false;
- }
- if (!type_arg.takes_ownership) {
- write_string ("weak ");
- }
- if (type_arg.data_type != null) {
- write_string (type_arg.data_type.get_full_name ());
- } else {
- write_string (type_arg.type_parameter.name);
- }
- }
- write_string (">");
- }
- if (type.non_null) {
- write_string ("!");
- }
+ write_string (type.to_string ());
}
private void write_string (string! s) {
public override void visit_invocation_expression (InvocationExpression! expr) {
expr.accept_children (this);
- var msym = (Invokable) expr.call.symbol_reference;
- Collection<FormalParameter> params = msym.get_parameters ();
+ var mtype = expr.call.static_type;
+ Collection<FormalParameter> params = mtype.get_parameters ();
Iterator<FormalParameter> params_it = params.iterator ();
foreach (Expression arg in expr.get_argument_list ()) {
if (is_ref && param.type_reference.type_parameter != null) {
if (expr.call is MemberAccess) {
var ma = (MemberAccess) expr.call;
- var param_type = SemanticAnalyzer.get_actual_type (ma.inner.static_type, msym, param.type_reference, expr);
+ var param_type = SemanticAnalyzer.get_actual_type (ma.inner.static_type, ma.symbol_reference, param.type_reference, expr);
if (param_type != null) {
is_ref = param_type.takes_ownership;
}
public override void visit_object_creation_expression (ObjectCreationExpression! expr) {
expr.accept_children (this);
- if (!(expr.symbol_reference is Invokable)) {
+ if (!(expr.symbol_reference is Method)) {
return;
}
- var msym = (Invokable) expr.symbol_reference;
+ var msym = (Method) expr.symbol_reference;
Collection<FormalParameter> params = msym.get_parameters ();
Iterator<FormalParameter> params_it = params.iterator ();
/**
* Represents a type or namespace method.
*/
-public class Vala.Method : Member, Invokable {
+public class Vala.Method : Member {
public const string DEFAULT_SENTINEL = "NULL";
/**
public Collection<FormalParameter> get_parameters () {
return new ReadOnlyCollection<FormalParameter> (parameters);
}
-
- public DataType get_return_type () {
- return return_type;
- }
-
- public bool is_invokable () {
- return true;
- }
public override void accept (CodeVisitor! visitor) {
visitor.visit_method (this);
-/* valainvokable.vala
+/* valamethodtype.vala
*
- * Copyright (C) 2006-2007 Jürg Billeter
+ * Copyright (C) 2007 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
using Gee;
/**
- * Represents a possibly invokable code object.
+ * The type of a method referencea.
*/
-public interface Vala.Invokable : Symbol {
- /**
- * Returns whether this code object is invokable.
- *
- * @return true if invokable, false otherwise
- */
- public abstract bool is_invokable ();
-
- /**
- * Returns the return type of this invokable.
- *
- * @return return type
- */
- public abstract DataType get_return_type ();
-
- /**
- * Returns copy of the list of invocation parameters.
- *
- * @return parameter list
- */
- public abstract Collection<FormalParameter> get_parameters ();
+public class Vala.MethodType : DataType {
+ public Method method_symbol { get; set; }
+
+ public MethodType (construct Method method_symbol) {
+ }
+
+ public override bool is_invokable () {
+ return true;
+ }
+
+ public override DataType get_return_type () {
+ return method_symbol.return_type;
+ }
+
+ public override Collection<FormalParameter> get_parameters () {
+ return method_symbol.get_parameters ();
+ }
}
return decl.type_reference;
} else if (sym is EnumValue) {
return new ValueType ((Typesymbol) sym.parent_symbol);
+ } else if (sym is Method) {
+ return new MethodType ((Method) sym);
+ } else if (sym is Signal) {
+ return new SignalType ((Signal) sym);
}
return null;
}
}
private bool is_type_compatible (DataType! expression_type, DataType! expected_type) {
+ if (expected_type is DelegateType && expression_type is DelegateType) {
+ return ((DelegateType) expected_type).delegate_symbol == ((DelegateType) expression_type).delegate_symbol;
+ }
+
/* only null is compatible to null */
if (expected_type.data_type == null && expected_type.type_parameter == null) {
return (expression_type.data_type == null && expected_type.type_parameter == null);
}
}
- var msym = expr.call.symbol_reference;
+ var mtype = expr.call.static_type;
- if (msym == null) {
- /* if no symbol found, skip this check */
+ if (mtype == null) {
+ /* if no type found, skip this check */
expr.error = true;
return;
}
Collection<FormalParameter> params;
- if (msym is Invokable) {
- var m = (Invokable) msym;
- if (m.is_invokable ()) {
- params = m.get_parameters ();
- } else {
- expr.error = true;
- Report.error (expr.source_reference, "invocation not supported in this context");
- return;
- }
+ if (mtype.is_invokable ()) {
+ params = mtype.get_parameters ();
} else {
expr.error = true;
Report.error (expr.source_reference, "invocation not supported in this context");
DataType ret_type;
- if (msym is Invokable) {
- var m = (Invokable) msym;
- ret_type = m.get_return_type ();
- params = m.get_parameters ();
+ ret_type = mtype.get_return_type ();
+ params = mtype.get_parameters ();
- if (ret_type.data_type == null && ret_type.type_parameter == null) {
- // void return type
- if (!(expr.parent_node is ExpressionStatement)) {
- expr.error = true;
- Report.error (expr.source_reference, "invocation of void method not allowed as expression");
- return;
- }
+ if (ret_type.data_type == null && ret_type.type_parameter == null) {
+ // void return type
+ if (!(expr.parent_node is ExpressionStatement)) {
+ expr.error = true;
+ Report.error (expr.source_reference, "invocation of void method not allowed as expression");
+ return;
}
+ }
- // resolve generic return values
- if (ret_type.type_parameter != null) {
- if (!(expr.call is MemberAccess)) {
- Report.error (((CodeNode) m).source_reference, "internal error: unsupported generic return value");
- expr.error = true;
- return;
- }
- var ma = (MemberAccess) expr.call;
- if (ma.inner == null) {
- // TODO resolve generic return values within the type hierarchy if possible
- Report.error (expr.source_reference, "internal error: resolving generic return values within type hierarchy not supported yet");
- expr.error = true;
+ // resolve generic return values
+ if (ret_type.type_parameter != null) {
+ if (!(expr.call is MemberAccess)) {
+ Report.error (expr.source_reference, "internal error: unsupported generic return value");
+ expr.error = true;
+ return;
+ }
+ var ma = (MemberAccess) expr.call;
+ if (ma.inner == null) {
+ // TODO resolve generic return values within the type hierarchy if possible
+ Report.error (expr.source_reference, "internal error: resolving generic return values within type hierarchy not supported yet");
+ expr.error = true;
+ return;
+ } else {
+ ret_type = get_actual_type (ma.inner.static_type, ma.symbol_reference, ret_type, expr);
+ if (ret_type == null) {
return;
- } else {
- ret_type = get_actual_type (ma.inner.static_type, msym, ret_type, expr);
- if (ret_type == null) {
- return;
- }
}
}
}
- if (msym is Method) {
- var m = (Method) msym;
+ if (mtype is MethodType) {
+ var m = ((MethodType) mtype).method_symbol;
expr.tree_can_fail = expr.can_fail = (m.get_error_domains ().size > 0);
}
expr.static_type = ret_type;
- check_arguments (expr, msym, params, expr.get_argument_list ());
+ check_arguments (expr, mtype, params, expr.get_argument_list ());
}
- private bool check_arguments (Expression! expr, Symbol! msym, Collection<FormalParameter> params, Collection<Expression> args) {
+ private bool check_arguments (Expression! expr, DataType! mtype, Collection<FormalParameter> params, Collection<Expression> args) {
Expression prev_arg = null;
Iterator<Expression> arg_it = args.iterator ();
- bool diag = (msym.get_attribute ("Diagnostics") != null);
+ bool diag = (mtype is MethodType && ((MethodType) mtype).method_symbol.get_attribute ("Diagnostics") != null);
bool ellipsis = false;
int i = 0;
if (!arg_it.next ()) {
if (param.default_expression == null) {
expr.error = true;
- Report.error (expr.source_reference, "Too few arguments, method `%s' does not take %d arguments".printf (msym.get_full_name (), args.size));
+ Report.error (expr.source_reference, "Too few arguments, method `%s' does not take %d arguments".printf (mtype.to_string (), args.size));
return false;
}
} else {
return false;
} else if (arg.static_type == null) {
// disallow untyped arguments except for type inference of callbacks
- if (!(param.type_reference.data_type is Callback) || !(arg.symbol_reference is Method)) {
+ if (!(param.type_reference is DelegateType) || !(arg.symbol_reference is Method)) {
expr.error = true;
Report.error (expr.source_reference, "Invalid type for argument %d".printf (i + 1));
return false;
}
} else if (!ellipsis && arg_it.next ()) {
expr.error = true;
- Report.error (expr.source_reference, "Too many arguments, method `%s' does not take %d arguments".printf (msym.get_full_name (), args.size));
+ Report.error (expr.source_reference, "Too many arguments, method `%s' does not take %d arguments".printf (mtype.to_string (), args.size));
return false;
}
if (expr.symbol_reference is Method) {
var m = (Method) expr.symbol_reference;
- check_arguments (expr, m, m.get_parameters (), expr.get_argument_list ());
+ check_arguments (expr, new MethodType (m), m.get_parameters (), expr.get_argument_list ());
expr.tree_can_fail = expr.can_fail = (m.get_error_domains ().size > 0);
} else if (type is Enum) {
}
public override void visit_lambda_expression (LambdaExpression! l) {
- if (l.expected_type == null || !(l.expected_type.data_type is Callback)) {
+ if (!(l.expected_type is DelegateType)) {
l.error = true;
Report.error (l.source_reference, "lambda expression not allowed in this context");
return;
in_instance_method = is_in_constructor ();
}
- var cb = (Callback) l.expected_type.data_type;
+ var cb = (Callback) ((DelegateType) l.expected_type).delegate_symbol;
l.method = new Method (get_lambda_name (), cb.return_type);
l.method.instance = cb.instance && in_instance_method;
l.method.owner = current_symbol.scope;
if (ma.symbol_reference is Signal) {
var sig = (Signal) ma.symbol_reference;
- a.right.expected_type = new DataType ();
- a.right.expected_type.data_type = sig.get_callback ();
+ a.right.expected_type = new DelegateType (sig.get_callback ());
} else {
a.right.expected_type = ma.static_type;
}
/**
* Represents an object signal. Signals enable objects to provide notifications.
*/
-public class Vala.Signal : Member, Invokable, Lockable {
+public class Vala.Signal : Member, Lockable {
/**
* The return type of handlers of this signal.
*/
public Collection<FormalParameter> get_parameters () {
return new ReadOnlyCollection<FormalParameter> (parameters);
}
-
- public DataType get_return_type () {
- return return_type;
- }
- public bool is_invokable () {
- return true;
- }
-
/**
* Returns generated callback to be used for signal handlers.
*
--- /dev/null
+/* valasignaltype.vala
+ *
+ * Copyright (C) 2007 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>
+ */
+
+using GLib;
+using Gee;
+
+/**
+ * The type of a signal referencea.
+ */
+public class Vala.SignalType : DataType {
+ public Signal signal_symbol { get; set; }
+
+ public SignalType (construct Signal signal_symbol) {
+ }
+
+ public override bool is_invokable () {
+ return true;
+ }
+
+ public override DataType get_return_type () {
+ return signal_symbol.return_type;
+ }
+
+ public override Collection<FormalParameter> get_parameters () {
+ return signal_symbol.get_parameters ();
+ }
+}
if (sym is TypeParameter) {
type.type_parameter = (TypeParameter) sym;
} else if (sym is Typesymbol) {
- type.data_type = (Typesymbol) sym;
+ if (sym is Callback) {
+ type = new DelegateType ((Callback) sym);
+ } else {
+ type.data_type = (Typesymbol) sym;
+ }
} else {
Report.error (type.source_reference, "`%s' is not a type".printf (sym.get_full_name ()));
return null;
return null;
}
if (sym is Typesymbol) {
- type.data_type = (Typesymbol) sym;
+ if (sym is Callback) {
+ type = new DelegateType ((Callback) sym);
+ } else {
+ type.data_type = (Typesymbol) sym;
+ }
} else {
Report.error (type.source_reference, "`%s' is not a type".printf (sym.get_full_name ()));
return null;
/**
* Represents a variable declarator in the source code.
*/
-public class Vala.VariableDeclarator : Symbol, Invokable {
+public class Vala.VariableDeclarator : Symbol {
/**
* The optional initializer expression.
*/
}
}
- public Collection<FormalParameter> get_parameters () {
- if (!is_invokable ()) {
- return null;
- }
-
- var cb = (Callback) type_reference.data_type;
- return cb.get_parameters ();
- }
-
- public DataType get_return_type () {
- if (!is_invokable ()) {
- return null;
- }
-
- var cb = (Callback) type_reference.data_type;
- return cb.return_type;
- }
-
- public bool is_invokable () {
- return (type_reference.data_type is Callback);
- }
-
public override void replace_expression (Expression! old_node, Expression! new_node) {
if (initializer == old_node) {
initializer = new_node;