author | Nika Layzell <nika@thelayzells.com> |
Fri, 06 Apr 2018 18:22:14 -0400 | |
changeset 414201 | c59b5be67ba225f8864219c8b8d589446d1d8459 |
parent 414200 | 40a027a1f2cf5318f96e97cef8a5a7a388cb0a20 |
child 414202 | ae4da56bcf71aeb41efdd4cd1a7a76d59cfcf1cc |
push id | 33861 |
push user | ccoroiu@mozilla.com |
push date | Wed, 18 Apr 2018 10:50:38 +0000 |
treeherder | mozilla-central@4af4ae0aee55 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mccr8 |
bugs | 1444991 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/xpcom/idl-parser/xpidl/header.py +++ b/xpcom/idl-parser/xpidl/header.py @@ -228,29 +228,43 @@ def print_header(idl, fd, filename): for p in idl.productions: if p.kind == 'include': continue if p.kind == 'cdata': 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 if p.kind == 'interface': write_interface(p, fd) continue if p.kind == 'typedef': printComments(fd, p.doccomments, '') fd.write("typedef %s %s;\n\n" % (p.realtype.nativeType('in'), p.name)) 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" #define %(defname)s_IID \ {0x%(m0)s, 0x%(m1)s, 0x%(m2)s, \ { %(m3joined)s }}
--- a/xpcom/idl-parser/xpidl/jsonxpt.py +++ b/xpcom/idl-parser/xpidl/jsonxpt.py @@ -73,16 +73,24 @@ def get_type(type, calltype, iid_is=None } if isinstance(type, xpidl.Interface) or isinstance(type, xpidl.Forward): return { 'tag': 'TD_INTERFACE_TYPE', '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 { 'tag': TypeMap[type.specialtype] } elif iid_is is not None: return { 'tag': 'TD_INTERFACE_IS_TYPE',
--- a/xpcom/idl-parser/xpidl/xpidl.py +++ b/xpcom/idl-parser/xpidl/xpidl.py @@ -560,16 +560,60 @@ class Native(object): else: m = calltype != 'in' and '*mut ' or '' return "%s%s" % (m, name) def __str__(self): 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' def __init__(self, name, attlist, base, members, location, doccomments): self.name = name self.attributes = InterfaceAttributes(attlist, location) self.base = base self.members = members @@ -1160,16 +1204,17 @@ class IDLParser(object): 'in': 'IN', 'inout': 'INOUT', 'out': 'OUT', 'attribute': 'ATTRIBUTE', 'raises': 'RAISES', 'readonly': 'READONLY', 'native': 'NATIVE', 'typedef': 'TYPEDEF', + 'webidl': 'WEBIDL', } tokens = [ 'IDENTIFIER', 'CDATA', 'INCLUDE', 'IID', 'NUMBER', @@ -1274,17 +1319,18 @@ class IDLParser(object): def p_productions_include(self, p): """productions : INCLUDE productions""" p[0] = list(p[2]) p[0].insert(0, Include(p[1], self.getLocation(p, 1))) 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]) def p_typedef(self, p): """typedef : TYPEDEF IDENTIFIER IDENTIFIER ';'""" p[0] = Typedef(type=p[2], name=p[3], location=self.getLocation(p, 1), @@ -1298,16 +1344,20 @@ class IDLParser(object): location=self.getLocation(p, 2)) def p_afternativeid(self, p): """afternativeid : """ # this is a place marker: we switch the lexer into literal identifier # 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""" p[0] = {'value': p[1], 'location': self.getLocation(p, 1)} def p_attributes(self, p): """attributes : '[' attlist ']'