summaryrefslogtreecommitdiff
path: root/gobject/valadbusbindingprovider.vala
blob: 879a57a7a3d087ed0649649325c40a8c1d900950 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* valadbusbindingprovider.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;

/**
 * Dynamic binding provider for DBus objects.
 */
public class Vala.DBusBindingProvider : Object, BindingProvider {
	public CodeContext context {
		set {
			_context = value;

			string_type = (DataType) _context.root.scope.lookup ("string");

			var dbus_ns = _context.root.scope.lookup ("DBus");
			if (dbus_ns != null) {
				connection_type = (DataType) dbus_ns.scope.lookup ("Connection");
				dbus_error_type = (DataType) dbus_ns.scope.lookup ("Error");
			}
		}
	}

	private CodeContext _context;
	private DataType string_type;
	private DataType connection_type;
	private DataType dbus_error_type;

	private Collection<Symbol> symbols = new ArrayList<Symbol> ();

	public DBusBindingProvider () {
	}

	public Symbol get_binding (MemberAccess! ma) {
		if (connection_type != null && ma.inner != null && ma.inner.static_type != null && ma.inner.static_type.data_type == connection_type) {
			var type_args = ma.get_type_arguments ();
			if (type_args.size != 1) {
				return null;
			}
			Iterator<TypeReference> type_args_it = type_args.iterator ();
			type_args_it.next ();
			var ret_type = new TypeReference ();
			ret_type.data_type = type_args_it.get ().data_type;
			if (!is_dbus_interface (ret_type.data_type)) {
				return null;
			}
			var m = new Method ("get_object", ret_type, ma.source_reference);
			m.set_cname ("dbus_g_proxy_new_for_name");
			m.add_cheader_filename ("dbus/dbus-glib.h");
			m.access = SymbolAccessibility.PUBLIC;
			var string_type_ref = new TypeReference ();
			string_type_ref.data_type = string_type;
			m.add_parameter (new FormalParameter ("name", string_type_ref));
			m.add_parameter (new FormalParameter ("path", string_type_ref));
			symbols.add (m);
			return m;
		} else if (ma.inner != null && ma.inner.static_type != null && is_dbus_interface (ma.inner.static_type.data_type)) {
			if (ma.parent_node is InvocationExpression) {
				var expr = (InvocationExpression) ma.parent_node;
				var ret_type = new TypeReference ();
				if (expr.expected_type != null) {
					ret_type.data_type = expr.expected_type.data_type;
					ret_type.transfers_ownership = ret_type.data_type.is_reference_type ();
				}
				var m = new DBusMethod (ma.member_name, ret_type, ma.source_reference);
				if (expr.expected_type != null) {
					var error_type = new TypeReference ();
					error_type.data_type = dbus_error_type;
					m.add_error_domain (error_type);
				}
				m.access = SymbolAccessibility.PUBLIC;
				m.add_parameter (new FormalParameter.with_ellipsis ());
				symbols.add (m);
				return m;
			} else if (ma.parent_node is Assignment) {
				var a = (Assignment) ma.parent_node;
				if (a.left != ma) {
					return null;
				}
				var s = new DBusSignal (ma.member_name, new TypeReference (), ma.source_reference);
				s.access = SymbolAccessibility.PUBLIC;
				symbols.add (s);
				return s;
			}
		}
		return null;
	}

	private bool is_dbus_interface (DataType! t) {
		if (!(t is Interface)) {
			return false;
		}
		return (t.get_attribute ("DBusInterface") != null);
	}
}