File: Synopsis/Parsers/IDL/omni.py 1
2
3
4
5
6
7
8from Synopsis import IR, ASG
9from Synopsis.QualifiedName import QualifiedCxxName as QName
10from Synopsis.SourceFile import *
11import idlast, idltype, idlvisitor, idlutil
12import _omniidl
13import sys, getopt, os, os.path, string, types
14
15sourcefile = None
16
17def strip_filename(filename):
18 "This is aliased as strip if -b used and basename set"
19
20 if len(basename) > len(filename): return filename
21 if filename[:len(basename)] == basename:
22 return filename[len(basename):]
23 return filename
24
25class TypeTranslator(idlvisitor.TypeVisitor):
26 """maps idltype objects to ASG.TypeId objects in a ASG.Dictionary"""
27
28 def __init__(self, types):
29 self.types = types
30 self.__result = None
31 self.__basetypes = {idltype.tk_void: QName(('void',)),
32 idltype.tk_short: QName(('short',)),
33 idltype.tk_long: QName(('long',)),
34 idltype.tk_ushort: QName(('unsigned short',)),
35 idltype.tk_ulong: QName(('unsigned long',)),
36 idltype.tk_float: QName(('float',)),
37 idltype.tk_double: QName(('double',)),
38 idltype.tk_boolean: QName(('boolean',)),
39 idltype.tk_char: QName(('char',)),
40 idltype.tk_octet: QName(('octet',)),
41 idltype.tk_any: QName(('any',)),
42 idltype.tk_TypeCode: QName(('CORBA','TypeCode',)),
43 idltype.tk_Principal: QName(('CORBA','Principal',)),
44 idltype.tk_longlong: QName(('long long',)),
45 idltype.tk_ulonglong: QName(('unsigned long long',)),
46 idltype.tk_longdouble: QName(('long double',)),
47 idltype.tk_wchar: QName(('wchar',))}
48
49 def internalize(self, idltype):
50
51 idltype.accept(self)
52 return self.__result
53
54 def has_key(self, name): return self.types.has_key(name)
55
56 def add(self, name, type):
57 self.types[name] = type
58
59 def get(self, name):
60 return self.types[name]
61
62 def visitBaseType(self, idltype):
63
64 type = ASG.BuiltinTypeId('IDL', self.__basetypes[idltype.kind()])
65 self.types[type.name] = type
66 self.__result = type.name
67
68 def visitStringType(self, idltype):
69
70
71 if idltype.bound() == 0:
72 qname = QName(('string',))
73 else:
74 qname = QName(('string<%s>'%idltype.bound(),))
75 if qname not in self.types:
76 self.types[qname] = ASG.BuiltinTypeId('IDL', qname)
77 self.__result = qname
78
79 def visitWStringType(self, idltype):
80
81
82 if idltype.bound() == 0:
83 qname = QName(('wstring',))
84 else:
85 qname = QName(('wstring<%s>'%idltype.bound(),))
86 if qname not in self.types:
87 self.types[qname] = ASG.BuiltinTypeId('IDL', qname)
88 self.__result = qname
89
90 def visitSequenceType(self, idltype):
91
92 qname = QName(('sequence',))
93 if not self.types.has_key(qname):
94 self.types[qname] = ASG.BuiltinTypeId("IDL", qname)
95 idltype.seqType().accept(self)
96 ptype = self.types[self.__result]
97 type = ASG.ParametrizedTypeId("IDL", self.types[qname], [ptype])
98 qname = QName(('sequence<%s>'%str(ptype.name),))
99 self.types[qname] = type
100 self.__result = qname
101
102 def visitDeclaredType(self, idltype):
103
104 self.__result = QName(idltype.decl().scopedName())
105
106class ASGTranslator(idlvisitor.AstVisitor):
107
108 def __init__(self, declarations, types, primary_file_only):
109
110 self.declarations = declarations
111 self.primary_file_only = primary_file_only
112 self.types = types
113 self.__scope = []
114 self.__operation = None
115 self.__enum = None
116
117 def scope(self): return self.__scope[-1].name
118
119 def add_declaration(self, declaration):
120 self.__scope[-1].declarations.append(declaration)
121
122 def addType(self, name, type):
123
124 if self.types.has_key(name):
125 if isinstance(self.types.get(name), ASG.UnknownTypeId):
126 self.types.add(name, type)
127 else:
128 pass
129 return
130 self.types.add(name, type)
131
132 def getType(self, name): return self.types.get(QName(name))
133 def visitAST(self, node):
134
135 self.__scope.append(ASG.Scope(sourcefile, 0, 'file', QName()))
136
137
138 qname = QName(('CORBA', 'Object'))
139 object = ASG.Class(sourcefile, 0, 'interface', qname)
140 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, object))
141 for n in node.declarations():
142 n.accept(self)
143 for d in self.__scope[-1].declarations:
144 self.declarations.append(d)
145
146 def visitModule(self, node):
147
148 visible = node.mainFile() or not self.primary_file_only
149 qname = QName(list(self.scope()) + [node.identifier()])
150 module = ASG.Module(sourcefile, node.line(), 'module', qname)
151 if visible:
152 self.add_declaration(module)
153 self.__scope.append(module)
154 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, module))
155 if not self.primary_file_only or node.mainFile():
156 comments = [c.text() for c in node.comments()]
157 if comments:
158 module.annotations['comments'] = comments
159 for n in node.definitions():
160 n.accept(self)
161 self.__scope.pop()
162
163 def visitInterface(self, node):
164
165 visible = node.mainFile() or not self.primary_file_only
166 qname = QName(list(self.scope()) + [node.identifier()])
167 class_ = ASG.Class(sourcefile, node.line(), 'interface', qname)
168 if visible:
169 self.add_declaration(class_)
170 self.__scope.append(class_)
171 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, class_))
172 if not self.primary_file_only or node.mainFile():
173 comments = [c.text() for c in node.comments()]
174 if comments:
175 class_.annotations['comments'] = comments
176 for i in node.inherits():
177 parent = self.getType(i.scopedName())
178 class_.parents.append(ASG.Inheritance("", parent, []))
179 for c in node.contents(): c.accept(self)
180 self.__scope.pop()
181
182 def visitForward(self, node):
183
184 visible = node.mainFile() or not self.primary_file_only
185 name = list(self.scope())
186 qname = QName(name + [node.identifier()])
187 forward = ASG.Forward(sourcefile, node.line(), 'interface', qname)
188 if visible:
189 self.add_declaration(forward)
190 self.addType(qname, ASG.UnknownTypeId('IDL', qname))
191
192 def visitConst(self, node):
193
194 visible = node.mainFile() or not self.primary_file_only
195 name = list(self.scope())
196 qname = QName(name + [node.identifier()])
197 type = self.types.internalize(node.constType())
198 if node.constType().kind() == idltype.tk_enum:
199 value = "::" + idlutil.ccolonName(node.value().scopedName())
200 else:
201 value = str(node.value())
202 const = ASG.Const(sourcefile, node.line(), 'const',
203 self.getType(type), qname, value)
204 if visible:
205 self.add_declaration(const)
206 comments = [c.text() for c in node.comments()]
207 if comments:
208 const.annotations['comments'] = comments
209
210 def visitTypedef(self, node):
211
212 visible = node.mainFile() or not self.primary_file_only
213
214
215 if node.constrType():
216 node.aliasType().decl().accept(self)
217 type = self.types.internalize(node.aliasType())
218 comments = [c.text() for c in node.comments()]
219 for d in node.declarators():
220
221
222 dtype = type
223 if d.sizes():
224 array = ASG.ArrayTypeId('IDL', self.getType(type), [str(s) for s in d.sizes()])
225 dtype = map(None, type[:-1])
226 dtype.append(type[-1] + string.join(map(lambda s:"["+ str(s) +"]", d.sizes()),''))
227 self.addType(QName(dtype), array)
228 name = list(self.scope())
229 qname = QName(name + [d.identifier()])
230 typedef = ASG.Typedef(sourcefile, node.line(), 'typedef', qname, self.getType(dtype), node.constrType())
231 d_comments = comments + [c.text() for c in d.comments()]
232 if d_comments:
233 typedef.annotations['comments'] = d_comments
234 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, typedef))
235 if visible:
236 self.add_declaration(typedef)
237
238 def visitMember(self, node):
239
240 visible = node.mainFile() or not self.primary_file_only
241
242
243 if node.constrType():
244 node.memberType().decl().accept(self)
245 type = self.types.internalize(node.memberType())
246 comments = [c.text() for c in node.comments()]
247 for d in node.declarators():
248
249
250 dtype = type
251 if d.sizes():
252 array = ASG.ArrayTypeId('IDL', self.getType(type), [str(s) for s in node.sizes()])
253 dtype = type[:-1]
254 dtype.append(type[-1] + string.join(map(lambda s:"["+s+"]", d.sizes()),''))
255 self.addType(dtype, array)
256 qname = QName(list(self.scope()) + [d.identifier()])
257 member = ASG.Variable(sourcefile, node.line(), 'variable', qname, self.getType(dtype), node.constrType())
258 d_comments = comments + [c.text() for c in d.comments()]
259 if d_comments:
260 member.annotations['comments'] = d_comments
261 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, member))
262 if visible:
263 self.add_declaration(member)
264
265 def visitStruct(self, node):
266
267 visible = node.mainFile() or not self.primary_file_only
268 qname = QName(list(self.scope()) + [node.identifier()])
269 if self.primary_file_only and not node.mainFile():
270 forward = ASG.Forward(sourcefile, node.line(), 'struct', qname)
271 if visible:
272 self.add_declaration(forward)
273 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, forward))
274 return
275 struct = ASG.Class(sourcefile, node.line(), 'struct', qname)
276 if visible:
277 self.add_declaration(struct)
278 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, struct))
279 comments = [c.text() for c in node.comments()]
280 if comments:
281 struct.annotations['comments'] = comments
282 self.__scope.append(struct)
283 for member in node.members(): member.accept(self)
284 self.__scope.pop()
285
286 def visitException(self, node):
287
288 visible = node.mainFile() or not self.primary_file_only
289 qname = QName(list(self.scope()) + [node.identifier()])
290 if self.primary_file_only and not node.mainFile():
291 forward = ASG.Forward(sourcefile, node.line(), 'exception', qname)
292 if visible:
293 self.add_declaration(forward)
294 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, forward))
295 return
296 exc = ASG.Class(sourcefile, node.line(), 'exception', qname)
297 if visible:
298 self.add_declaration(exc)
299 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, exc))
300 self.__scope.append(exc)
301 comments = [c.text() for c in node.comments()]
302 if comments:
303 exc.annotations['comments'] = comments
304 for member in node.members(): member.accept(self)
305 self.__scope.pop()
306
307
308
309 def visitUnionCase(self, node):
310
311
312
313 if node.constrType():
314 node.caseType().decl().accept(self)
315 type = self.types.internalize(node.caseType())
316 declarator = node.declarator()
317 if declarator.sizes():
318 array = ASG.ArrayTypeId('IDL', self.getType(type), [str(s) for s in declarator.sizes()])
319 type = type[:-1]
320 type.append(type[-1] + string.join(map(lambda s:"["+s+"]",node.sizes()),''))
321 self.addType(type, array)
322 qname = QName(list(self.scope()) + [node.declarator().identifier()])
323 self.__scope[-1].declarations.append(
324 ASG.Operation(sourcefile, node.line(), 'case',
325 [], self.getType(type), [], qname, qname[-1]))
326
327 def visitUnion(self, node):
328
329 visible = node.mainFile() or not self.primary_file_only
330 qname = QName(list(self.scope()) + [node.identifier()])
331 if self.primary_file_only and not node.mainFile():
332 forward = ASG.Forward(sourcefile, node.line(), 'union', qname)
333 if visible:
334 self.add_declaration(forward)
335 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, forward))
336 return
337 class_ = ASG.Class(sourcefile, node.line(), 'union', qname)
338 self.add_declaration(class_)
339 self.__scope.append(class_)
340 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, class_))
341 comments = [c.text() for c in node.comments()]
342 if comments:
343 class_.annotations['comments'] = comments
344 for c in node.cases(): c.accept(self)
345 self.__scope.pop()
346
347 def visitEnumerator(self, node):
348
349 qname = QName(list(self.scope()) + [node.identifier()])
350 enum = ASG.Enumerator(sourcefile, node.line(), qname, '')
351 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, enum))
352 self.__enum.enumerators.append(enum)
353
354 def visitEnum(self, node):
355
356 visible = node.mainFile() or not self.primary_file_only
357 qname = QName(list(self.scope()) + [node.identifier()])
358 if self.primary_file_only and not node.mainFile():
359 forward = ASG.Forward(sourcefile, node.line(), 'enum', qname)
360 if visible:
361 self.add_declaration(forward)
362 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, forward))
363 return
364 self.__enum = ASG.Enum(sourcefile, node.line(), qname, [])
365 if visible:
366 self.add_declaration(self.__enum)
367 self.addType(qname, ASG.DeclaredTypeId('IDL', qname, self.__enum))
368 comments = [c.text() for c in node.comments()]
369 if comments:
370 self.__enum.annotations['comments'] = comments
371 for enumerator in node.enumerators(): enumerator.accept(self)
372 self.__enum = None
373
374 def visitAttribute(self, node):
375
376 visible = node.mainFile() or not self.primary_file_only
377 scopename = list(self.scope())
378 if self.primary_file_only and not node.mainFile(): return
379
380 pre = []
381 if node.readonly(): pre.append("readonly")
382 type = self.types.internalize(node.attrType())
383 comments = [c.text() for c in node.comments()]
384 for id in node.identifiers():
385 qname = QName(scopename + [id])
386 attr = ASG.Operation(sourcefile, node.line(), 'attribute',
387 pre, self.getType(type), [], qname, qname[-1])
388 if comments:
389 attr.annotations['comments'] = comments
390 if visible:
391 self.add_declaration(attr)
392
393 def visitParameter(self, node):
394
395 operation = self.__operation
396 pre = []
397 if node.direction() == 0: pre.append("in")
398 elif node.direction() == 1: pre.append("out")
399 else: pre.append("inout")
400 post = []
401 name = self.types.internalize(node.paramType())
402 operation.parameters.append(ASG.Parameter(pre, self.getType(name), post, node.identifier()))
403
404 def visitOperation(self, node):
405
406 visible = node.mainFile() or not self.primary_file_only
407 pre = []
408 if node.oneway(): pre.append("oneway")
409 return_type = self.types.internalize(node.returnType())
410 qname = QName(list(self.scope()) + [node.identifier()])
411 self.__operation = ASG.Operation(sourcefile, node.line(), 'operation', pre, self.getType(return_type), [], qname, qname[-1])
412 comments = [c.text() for c in node.comments()]
413 if comments:
414 self.__operation.annotations['comments'] = comments
415 for p in node.parameters(): p.accept(self)
416 for e in node.raises():
417 exception = self.getType(e.scopedName())
418 self.__operation.exceptions.append(exception)
419
420 if visible:
421 self.add_declaration(self.__operation)
422 self.__operation = None
423
424
425
426
427
428
429
430
431
432def parse(ir, cppfile, src, primary_file_only,
433 base_path, verbose, debug):
434 global basename, strip, sourcefile
435
436 if base_path:
437 basename = base_path
438
439 _omniidl.keepComments(1)
440 _omniidl.noForwardWarning()
441 tree = _omniidl.compile(open(cppfile, 'r+'))
442 if tree == None:
443 sys.stderr.write("omni: Error parsing %s\n"%cppfile)
444 sys.exit(1)
445
446 sourcefile = SourceFile(strip_filename(src), src, 'IDL')
447 sourcefile.annotations['primary'] = True
448 new_ir = IR.IR()
449 new_ir.files[sourcefile.name] = sourcefile
450 type_trans = TypeTranslator(new_ir.asg.types)
451 ast_trans = ASGTranslator(new_ir.asg.declarations, type_trans, primary_file_only)
452 tree.accept(ast_trans)
453 sourcefile.declarations[:] = new_ir.asg.declarations
454 ir.merge(new_ir)
455 _omniidl.clear()
456 return ir
457
Generated on Thu Apr 16 16:27:14 2009 by
synopsis (version devel)