Merge in the gir-compiler branch. Thanks to Philip and Colin for their
[gnome.gobject-introspection] / giscanner / ast.py
1 # -*- Mode: Python -*-
2 # GObject-Introspection - a framework for introspecting GObject libraries
3 # Copyright (C) 2008  Johan Dahlin
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 # 02110-1301, USA.
19 #
20
21 """AST nodes
22 This file descbribes abstract data type nodes independent on the
23 implementation language.
24
25 These can later on be extended (eg subclassed) with additional information
26 which is language/library/domain specific.
27 """
28
29 ##
30 ## Types
31 ##
32
33 # Basic types
34 TYPE_INT8     = 'int8'
35 TYPE_UINT8    = 'uint8'
36 TYPE_INT16    = 'int16'
37 TYPE_UINT16   = 'uint16'
38 TYPE_INT32    = 'int32'
39 TYPE_UINT32   = 'uint32'
40 TYPE_INT64    = 'int64'
41 TYPE_UINT64   = 'uint64'
42 TYPE_LONG     = 'long'
43 TYPE_ULONG    = 'ulong'
44
45 # Floating-point
46 TYPE_FLOAT    = 'float'
47 TYPE_DOUBLE   = 'double'
48
49 # Higher-level data types
50 TYPE_NONE     = 'none'
51 TYPE_ANY      = 'any'      # CORBA Any/Variant/GValue, holds anything.
52 TYPE_BOOLEAN  = 'boolean'  # True/False
53 TYPE_STRING   = 'string'   # Sequence of characters
54 TYPE_SEQUENCE = 'sequence' # Sequence of something
55 TYPE_CHAR     = 'char'     # Character
56 TYPE_UCHAR    = 'uchar'    # Unsigned Character
57 TYPE_SIZE     = 'size'     # Size type (memory, buffer etc)
58 TYPE_SSIZE    = 'ssize'
59
60 # Wide/Unicode
61 TYPE_UCHAR    = 'uchar'
62 TYPE_USTRING  = 'ustring'
63
64 # Domain specific, but practically useful
65 TYPE_FILENAME = 'filename'
66
67 ##
68 ## Parameters
69 ##
70
71 PARAM_DIRECTION_IN = 'in'
72 PARAM_DIRECTION_OUT = 'out'
73 PARAM_DIRECTION_INOUT = 'inout'
74
75 type_names = {}
76
77 # C
78 type_names['char'] = TYPE_CHAR
79 type_names['unsigned char'] = TYPE_UCHAR
80 type_names['short'] = TYPE_INT16
81 type_names['unsigned short'] = TYPE_UINT16
82 type_names['int'] = TYPE_INT32
83 type_names['unsigned int'] = TYPE_UINT32
84 type_names['long'] = TYPE_LONG
85 type_names['unsigned long'] = TYPE_ULONG
86 type_names['float'] = TYPE_FLOAT
87 type_names['double'] = TYPE_DOUBLE
88 type_names['char*'] = TYPE_STRING
89 type_names['void*'] = TYPE_ANY
90 type_names['void'] = TYPE_NONE
91 type_names['size_t'] = TYPE_SIZE
92 type_names['ssize_t'] = TYPE_SSIZE
93
94
95 def type_name_from_ctype(ctype):
96     return type_names.get(ctype, ctype)
97
98
99 class Node(object):
100
101     def __init__(self, name=None):
102         self.name = name
103
104     def __repr__(self):
105         return '%s(%r)' % (self.__class__.__name__, self.name)
106
107
108 class Namespace(Node):
109     def __init__(self, name):
110         Node.__init__(self, name)
111         self.nodes = []
112
113     def __repr__(self):
114         return '%s(%r, %r)' % (self.__class__.__name__, self.name,
115                                self.nodes)
116
117 class Function(Node):
118     def __init__(self, name, retval, parameters, symbol):
119         Node.__init__(self, name)
120         self.retval = retval
121         self.parameters = parameters
122         self.symbol = symbol
123
124     def __repr__(self):
125         return '%s(%r, %r, %r)' % (self.__class__.__name__,
126                                    self.name, self.retval,
127                                    self.parameters)
128
129
130 class VFunction(Function):
131     pass
132
133
134 class Type(Node):
135     def __init__(self, name, ctype=None):
136         Node.__init__(self, name)
137         self.ctype = ctype
138
139
140 class Parameter(Node):
141     def __init__(self, name, typenode):
142         Node.__init__(self, name)
143         self.type = typenode
144         self.direction = PARAM_DIRECTION_IN
145         self.transfer = False
146         self.allow_none = False
147
148     def __repr__(self):
149         return 'Parameter(%r, %r)' % (self.name, self.type)
150
151
152 class Enum(Node):
153     def __init__(self, name, symbol, members):
154         Node.__init__(self, name)
155         self.symbol = symbol
156         self.members = members
157
158     def __repr__(self):
159         return 'Enum(%r, %r)' % (self.name, self.members)
160
161
162 class Member(Node):
163     def __init__(self, name, value, symbol):
164         Node.__init__(self, name)
165         self.value = value
166         self.symbol = symbol
167
168     def __repr__(self):
169         return 'Member(%r, %r)' % (self.name, self.value)
170
171
172 class Struct(Node):
173     def __init__(self, name, symbol):
174         Node.__init__(self, name)
175         self.fields = []
176         self.symbol = symbol
177
178
179 class Field(Node):
180     def __init__(self, name, typenode, symbol):
181         Node.__init__(self, name)
182         self.type = typenode
183         self.symbol = symbol
184
185     def __repr__(self):
186         return 'Field(%r, %r)' % (self.name, self.type)
187
188
189 class Return(Node):
190     def __init__(self, rtype):
191         Node.__init__(self)
192         self.type = rtype
193         self.transfer = False
194
195     def __repr__(self):
196         return 'Return(%r)' % (self.type,)
197
198
199 class Class(Node):
200     def __init__(self, name, parent):
201         Node.__init__(self, name)
202         self.ctype = name
203         self.parent = parent
204         self.methods = []
205         self.constructors = []
206         self.properties = []
207         self.fields = []
208
209     def __repr__(self):
210         return '%s(%r, %r, %r)' % (
211             self.__class__.__name__,
212             self.name, self.parent, self.methods)
213
214
215 class Interface(Node):
216     def __init__(self, name):
217         Node.__init__(self, name)
218         self.methods = []
219         self.properties = []
220         self.fields = []
221
222     def __repr__(self):
223         return '%s(%r, %r)' % (
224             self.__class__.__name__,
225             self.name, self.methods)
226
227
228 class Constant(Node):
229     def __init__(self, name, type_name, value):
230         Node.__init__(self, name)
231         self.type = Type(type_name)
232         self.value = value
233
234     def __repr__(self):
235         return 'Constant(%r, %r, %r)' % (
236             self.name, self.type, self.value)
237
238
239 class Property(Node):
240     def __init__(self, name, type_name, ctype=None):
241         Node.__init__(self, name)
242         self.type = Type(type_name, ctype)
243
244     def __repr__(self):
245         return '%s(%r, %r, %r)' % (
246             self.__class__.__name__,
247             self.name, self.type, self.value)
248
249
250 # FIXME: Inherit from Function
251 class Callback(Node):
252     def __init__(self, name, retval, parameters):
253         Node.__init__(self, name)
254         self.retval = retval
255         self.parameters = parameters
256
257     def __repr__(self):
258         return 'Callback(%r, %r, %r)' % (
259             self.name, self.retval, self.parameters)
260
261
262 class Sequence(Type):
263     # Subclass, because a Sequence is a kind of Type
264     def __init__(self, name, ctype, element_type):
265         Type.__init__(self, name, ctype)
266         self.element_type = element_type
267         self.transfer = False
268