mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-05 05:30:29 +00:00
Bug 1444991 - Part 2: Parse webidl productions in xpidl, r=mccr8
They are parsed into a WebIDL object, and lowered into C++, Rust, and XPT. For C++ code, we generate a correctly namespaced forward declaration. In Rust, the types are exposed as `*const c_void`, as we don't have WebIDL type information there. The XPT code generator needs to know the header filename in order to perform correct codegen, so we also get that information.
This commit is contained in:
parent
be8b24333a
commit
6969209b41
@ -233,6 +233,9 @@ def print_header(idl, fd, filename):
|
||||
fd.write(p.data)
|
||||
continue
|
||||
|
||||
if p.kind == 'webidl':
|
||||
write_webidl(p, fd)
|
||||
continue
|
||||
if p.kind == 'forward':
|
||||
fd.write(forward_decl % {'name': p.name})
|
||||
continue
|
||||
@ -246,6 +249,17 @@ def print_header(idl, fd, filename):
|
||||
|
||||
fd.write(footer % {'basename': idl_basename(filename)})
|
||||
|
||||
|
||||
def write_webidl(p, fd):
|
||||
path = p.native.split('::')
|
||||
for seg in path[:-1]:
|
||||
fd.write("namespace %s {\n" % seg)
|
||||
fd.write("class %s; /* webidl %s */\n" % (path[-1], p.name))
|
||||
for seg in reversed(path[:-1]):
|
||||
fd.write("} // namespace %s\n" % seg)
|
||||
fd.write("\n")
|
||||
|
||||
|
||||
iface_header = r"""
|
||||
/* starting interface: %(name)s */
|
||||
#define %(defname)s_IID_STR "%(iid)s"
|
||||
|
@ -78,6 +78,14 @@ def get_type(type, calltype, iid_is=None, size_is=None):
|
||||
'name': type.name,
|
||||
}
|
||||
|
||||
if isinstance(type, xpidl.WebIDL):
|
||||
return {
|
||||
'tag': 'TD_DOMOBJECT',
|
||||
'name': type.name,
|
||||
'native': type.native,
|
||||
'headerFile': type.headerFile,
|
||||
}
|
||||
|
||||
if isinstance(type, xpidl.Native):
|
||||
if type.specialtype:
|
||||
return {
|
||||
|
@ -565,6 +565,50 @@ class Native(object):
|
||||
return "native %s(%s)\n" % (self.name, self.nativename)
|
||||
|
||||
|
||||
class WebIDL(object):
|
||||
kind = 'webidl'
|
||||
|
||||
def __init__(self, name, location):
|
||||
self.name = name
|
||||
self.location = location
|
||||
|
||||
def __eq__(self, other):
|
||||
return other.kind == 'webidl' and self.name == other.name
|
||||
|
||||
def resolve(self, parent):
|
||||
# XXX(nika): We don't handle _every_ kind of webidl object here (as that
|
||||
# would be hard). For example, we don't support nsIDOM*-defaulting
|
||||
# interfaces.
|
||||
# TODO: More explicit compile-time checks?
|
||||
|
||||
assert parent.webidlconfig is not None, \
|
||||
"WebIDL declarations require passing webidlconfig to resolve."
|
||||
|
||||
# Resolve our native name according to the WebIDL configs.
|
||||
config = parent.webidlconfig.get(self.name, {})
|
||||
self.native = config.get('nativeType')
|
||||
if self.native is None:
|
||||
self.native = "mozilla::dom::%s" % self.name
|
||||
self.headerFile = config.get('headerFile')
|
||||
if self.headerFile is None:
|
||||
self.headerFile = self.native.replace('::', '/') + '.h'
|
||||
|
||||
parent.setName(self)
|
||||
|
||||
def isScriptable(self):
|
||||
return True # All DOM objects are script exposed.
|
||||
|
||||
def nativeType(self, calltype):
|
||||
return "%s %s" % (self.native, calltype != 'in' and '* *' or '*')
|
||||
|
||||
def rustType(self, calltype):
|
||||
# Just expose the type as a void* - we can't do any better.
|
||||
return "%s*const libc::c_void" % (calltype != 'in' and '*mut ' or '')
|
||||
|
||||
def __str__(self):
|
||||
return "webidl %s\n" % self.name
|
||||
|
||||
|
||||
class Interface(object):
|
||||
kind = 'interface'
|
||||
|
||||
@ -1165,6 +1209,7 @@ class IDLParser(object):
|
||||
'readonly': 'READONLY',
|
||||
'native': 'NATIVE',
|
||||
'typedef': 'TYPEDEF',
|
||||
'webidl': 'WEBIDL',
|
||||
}
|
||||
|
||||
tokens = [
|
||||
@ -1279,7 +1324,8 @@ class IDLParser(object):
|
||||
def p_productions_interface(self, p):
|
||||
"""productions : interface productions
|
||||
| typedef productions
|
||||
| native productions"""
|
||||
| native productions
|
||||
| webidl productions"""
|
||||
p[0] = list(p[2])
|
||||
p[0].insert(0, p[1])
|
||||
|
||||
@ -1303,6 +1349,10 @@ class IDLParser(object):
|
||||
# mode here, to slurp up everything until the closeparen
|
||||
self.lexer.begin('nativeid')
|
||||
|
||||
def p_webidl(self, p):
|
||||
"""webidl : WEBIDL IDENTIFIER ';'"""
|
||||
p[0] = WebIDL(name=p[2], location=self.getLocation(p, 2))
|
||||
|
||||
def p_anyident(self, p):
|
||||
"""anyident : IDENTIFIER
|
||||
| CONST"""
|
||||
|
Loading…
x
Reference in New Issue
Block a user