author | Boris Kudryavtsev <boriskk.work@gmail.com> |
Mon, 04 May 2015 22:35:00 +0200 | |
changeset 251115 | 775890dd46d35f2dc967c325a625d85d1f267d02 |
parent 251114 | eaaff73823bf93c1b8bfc824b74b8380403e56f0 |
child 251116 | e575d941037742406f327c8819d3b8de8060234d |
push id | 61768 |
push user | cbook@mozilla.com |
push date | Thu, 02 Jul 2015 14:18:18 +0000 |
treeherder | mozilla-inbound@70839bf0a04e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | khuey |
bugs | 1155968 |
milestone | 42.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/header.py +++ b/xpcom/idl-parser/header.py @@ -19,75 +19,86 @@ printdoccomments = False if printdoccomments: def printComments(fd, clist, indent): for c in clist: fd.write("%s%s\n" % (indent, c)) else: def printComments(fd, clist, indent): pass + def firstCap(str): return str[0].upper() + str[1:] + def attributeParamName(a): return "a" + firstCap(a.name) + def attributeParamNames(a): l = [attributeParamName(a)] if a.implicit_jscontext: l.insert(0, "cx") return ", ".join(l) + def attributeNativeName(a, getter): binaryname = a.binaryname is not None and a.binaryname or firstCap(a.name) return "%s%s" % (getter and 'Get' or 'Set', binaryname) + def attributeReturnType(a, macro): """macro should be NS_IMETHOD or NS_IMETHODIMP""" if (a.nostdcall): return macro == "NS_IMETHOD" and "virtual nsresult" or "nsresult" else: return macro + def attributeParamlist(a, getter): l = ["%s%s" % (a.realtype.nativeType(getter and 'out' or 'in'), attributeParamName(a))] if a.implicit_jscontext: l.insert(0, "JSContext* cx") return ", ".join(l) + def attributeAsNative(a, getter): deprecated = a.deprecated and "NS_DEPRECATED " or "" params = {'deprecated': deprecated, 'returntype': attributeReturnType(a, 'NS_IMETHOD'), 'binaryname': attributeNativeName(a, getter), 'paramlist': attributeParamlist(a, getter)} return "%(deprecated)s%(returntype)s %(binaryname)s(%(paramlist)s)" % params + def methodNativeName(m): return m.binaryname is not None and m.binaryname or firstCap(m.name) + def methodReturnType(m, macro): """macro should be NS_IMETHOD or NS_IMETHODIMP""" if m.nostdcall and m.notxpcom: return "%s%s" % (macro == "NS_IMETHOD" and "virtual " or "", m.realtype.nativeType('in').strip()) elif m.nostdcall: return "%snsresult" % (macro == "NS_IMETHOD" and "virtual " or "") elif m.notxpcom: return "%s_(%s)" % (macro, m.realtype.nativeType('in').strip()) else: return macro + def methodAsNative(m): return "%s %s(%s)" % (methodReturnType(m, 'NS_IMETHOD'), methodNativeName(m), paramlistAsNative(m)) + def paramlistAsNative(m, empty='void'): l = [paramAsNative(p) for p in m.params] if m.implicit_jscontext: l.append("JSContext* cx") if m.optional_argc: l.append('uint8_t _argc') @@ -100,20 +111,22 @@ def paramlistAsNative(m, empty='void'): location=None, realtype=m.realtype))) if len(l) == 0: return empty return ", ".join(l) + def paramAsNative(p): return "%s%s" % (p.nativeType(), p.name) + def paramlistNames(m): names = [p.name for p in m.params] if m.implicit_jscontext: names.append('cx') if m.optional_argc: names.append('_argc') @@ -157,20 +170,22 @@ header_end = """/* For IDL files that do footer = """ #endif /* __gen_%(basename)s_h__ */ """ forward_decl = """class %(name)s; /* forward declaration */ """ + def idl_basename(f): """returns the base name of a file with the last extension stripped""" return os.path.basename(f).rpartition('.')[0] + def print_header(idl, fd, filename): fd.write(header % {'filename': filename, 'basename': idl_basename(filename)}) foundinc = False for inc in idl.includes(): if not foundinc: foundinc = True @@ -302,16 +317,17 @@ attr_infallible_tmpl = """\ { %(realtype)sresult; mozilla::DebugOnly<nsresult> rv = %(nativename)s(%(argnames)s&result); MOZ_ASSERT(NS_SUCCEEDED(rv)); return result; } """ + def write_interface(iface, fd): if iface.namemap is None: raise Exception("Interface was not resolved.") def write_const_decls(g): fd.write(" enum {\n") enums = [] for c in g:
--- a/xpcom/idl-parser/runtests.py +++ b/xpcom/idl-parser/runtests.py @@ -4,16 +4,17 @@ # http://creativecommons.org/publicdomain/zero/1.0/ # # Unit tests for xpidl.py import mozunit import unittest import xpidl + class TestParser(unittest.TestCase): def setUp(self): self.p = xpidl.IDLParser() def testEmpty(self): i = self.p.parse("", filename='f') self.assertTrue(isinstance(i, xpidl.IDL)) self.assertEqual([], i.productions)
--- a/xpcom/idl-parser/typelib.py +++ b/xpcom/idl-parser/typelib.py @@ -43,20 +43,22 @@ TypeMap = { 'nsid': xpt.Type.Tags.nsIID, 'domstring': xpt.Type.Tags.DOMString, 'astring': xpt.Type.Tags.AString, 'utf8string': xpt.Type.Tags.UTF8String, 'cstring': xpt.Type.Tags.CString, 'jsval': xpt.Type.Tags.jsval } + # XXXkhuey dipper types should go away (bug 677784) def isDipperType(type): return type == xpt.Type.Tags.DOMString or type == xpt.Type.Tags.AString or type == xpt.Type.Tags.CString or type == xpt.Type.Tags.UTF8String + def build_interface(iface, ifaces): def get_type(type, calltype, iid_is=None, size_is=None): """ Return the appropriate xpt.Type object for this param """ while isinstance(type, xpidl.Typedef): type = type.realtype if isinstance(type, xpidl.Builtin): @@ -231,16 +233,17 @@ def build_interface(iface, ifaces): return xpt.Interface(iface.name, iface.attributes.uuid, methods=methods, constants=consts, resolved=True, parent=parent, scriptable=iface.attributes.scriptable, function=iface.attributes.function, builtinclass=iface.attributes.builtinclass, main_process_scriptable_only=iface.attributes.main_process_scriptable_only) + def write_typelib(idl, fd, filename): """ Generate the typelib. """ # We only care about interfaces ifaces = [] for p in idl.productions: if p.kind == 'interface': ifaces.append(build_interface(p, ifaces))
--- a/xpcom/idl-parser/xpidl.py +++ b/xpcom/idl-parser/xpidl.py @@ -25,31 +25,33 @@ from ply import yacc Interface members const/method/attribute conform to the following pattern: name = 'string' def toIDL(self): 'returns the member signature as IDL' """ + def attlistToIDL(attlist): if len(attlist) == 0: return '' attlist = list(attlist) attlist.sort(cmp=lambda a,b: cmp(a[0], b[0])) return '[%s] ' % ','.join(["%s%s" % (name, value is not None and '(%s)' % value or '') for name, value, aloc in attlist]) _paramsHardcode = { 2: ('array', 'shared', 'iid_is', 'size_is', 'retval'), 3: ('array', 'size_is', 'const'), } + def paramAttlistToIDL(attlist): if len(attlist) == 0: return '' # Hack alert: g_hash_table_foreach is pretty much unimitatable... hardcode # quirk attlist = list(attlist) sorted = [] @@ -64,39 +66,43 @@ def paramAttlistToIDL(attlist): i += 1 sorted.extend(attlist) return '[%s] ' % ', '.join(["%s%s" % (name, value is not None and ' (%s)' % value or '') for name, value, aloc in sorted]) + def unaliasType(t): while t.kind == 'typedef': t = t.realtype assert t is not None return t + def getBuiltinOrNativeTypeName(t): t = unaliasType(t) if t.kind == 'builtin': return t.name elif t.kind == 'native': assert t.specialtype is not None return '[%s]' % t.specialtype else: return None + class BuiltinLocation(object): def get(self): return "<builtin type>" def __str__(self): return self.get() + class Builtin(object): kind = 'builtin' location = BuiltinLocation def __init__(self, name, nativename, signed=False, maybeConst=False): self.name = name self.nativename = nativename self.signed = signed @@ -137,16 +143,17 @@ builtinNames = [ Builtin('wchar', 'char16_t', False, False), Builtin('wstring', 'char16_t *', False, False), ] builtinMap = {} for b in builtinNames: builtinMap[b.name] = b + class Location(object): _line = None def __init__(self, lexer, lineno, lexpos): self._lineno = lineno self._lexpos = lexpos self._lexdata = lexer.lexdata self._file = getattr(lexer, 'filename', "<unknown>") @@ -176,16 +183,17 @@ class Location(object): self.resolve() return "%s line %s:%s" % (self._file, self._lineno, self._colno) def __str__(self): self.resolve() return "%s line %s:%s\n%s\n%s" % (self._file, self._lineno, self._colno, self._line, self.pointerline()) + class NameMap(object): """Map of name -> object. Each object must have a .name and .location property. Setting the same name twice throws an error.""" def __init__(self): self._d = {} def __getitem__(self, key): if key in builtinMap: @@ -216,26 +224,28 @@ class NameMap(object): self._d[object.name] = object def get(self, id, location): try: return self[id] except KeyError: raise IDLError("Name '%s' not found", location) + class IDLError(Exception): def __init__(self, message, location, warning=False): self.message = message self.location = location self.warning = warning def __str__(self): return "%s: %s, %s" % (self.warning and 'warning' or 'error', self.message, self.location) + class Include(object): kind = 'include' def __init__(self, filename, location): self.filename = filename self.location = location def __str__(self): @@ -254,16 +264,17 @@ class Include(object): self.IDL.resolve(parent.incdirs, parent.parser) for type in self.IDL.getNames(): parent.setName(type) parent.deps.extend(self.IDL.deps) return raise IDLError("File '%s' not found" % self.filename, self.location) + class IDL(object): def __init__(self, productions): self.productions = productions self.deps = [] def setName(self, object): self.namemap.set(object) @@ -295,16 +306,17 @@ class IDL(object): yield p def needsJSTypes(self): for p in self.productions: if p.kind == 'interface' and p.needsJSTypes(): return True return False + class CDATA(object): kind = 'cdata' _re = re.compile(r'\n+') def __init__(self, data, location): self.data = self._re.sub('\n', data) self.location = location @@ -312,16 +324,17 @@ class CDATA(object): pass def __str__(self): return "cdata: %s\n\t%r\n" % (self.location.get(), self.data) def count(self): return 0 + class Typedef(object): kind = 'typedef' def __init__(self, type, name, location, doccomments): self.type = type self.name = name self.location = location self.doccomments = doccomments @@ -338,16 +351,17 @@ class Typedef(object): def nativeType(self, calltype): return "%s %s" % (self.name, calltype != 'in' and '*' or '') def __str__(self): return "typedef %s %s\n" % (self.type, self.name) + class Forward(object): kind = 'forward' def __init__(self, name, location, doccomments): self.name = name self.location = location self.doccomments = doccomments @@ -372,16 +386,17 @@ class Forward(object): def nativeType(self, calltype): return "%s %s" % (self.name, calltype != 'in' and '* *' or '*') def __str__(self): return "forward-declared %s\n" % self.name + class Native(object): kind = 'native' modifier = None specialtype = None specialtypes = { 'nsid': None, @@ -457,16 +472,17 @@ class Native(object): m = '*' + ((self.modifier == 'ptr' and calltype != 'in') and '*' or '') else: m = calltype != 'in' and '*' or '' return "%s%s %s" % (const and 'const ' or '', self.nativename, m) def __str__(self): return "native %s(%s)\n" % (self.name, self.nativename) + 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 @@ -573,16 +589,17 @@ class Interface(object): def countEntries(self): ''' Returns the number of entries in the vtable for this interface. ''' total = sum(member.count() for member in self.members) if self.base is not None: realbase = self.idl.getName(self.base, self.location) total += realbase.countEntries() return total + class InterfaceAttributes(object): uuid = None scriptable = False builtinclass = False function = False deprecated = False noscript = False main_process_scriptable_only = False @@ -650,16 +667,17 @@ class InterfaceAttributes(object): if self.builtinclass: l.append("\tbuiltinclass\n") if self.function: l.append("\tfunction\n") if self.main_process_scriptable_only: l.append("\tmain_process_scriptable_only\n") return "".join(l) + class ConstMember(object): kind = 'const' def __init__(self, type, name, value, location, doccomments): self.type = type self.name = name self.value = value self.location = location self.doccomments = doccomments @@ -679,16 +697,17 @@ class ConstMember(object): return self.value(self.iface) def __str__(self): return "\tconst %s %s = %s\n" % (self.type, self.name, self.getValue()) def count(self): return 0 + class Attribute(object): kind = 'attribute' noscript = False readonly = False implicit_jscontext = False nostdcall = False binaryname = None null = None @@ -782,16 +801,17 @@ class Attribute(object): def __str__(self): return "\t%sattribute %s %s\n" % (self.readonly and 'readonly ' or '', self.type, self.name) def count(self): return self.readonly and 1 or 2 + class Method(object): kind = 'method' noscript = False notxpcom = False binaryname = None implicit_jscontext = False nostdcall = False optional_argc = False @@ -884,16 +904,17 @@ class Method(object): t = p.realtype if isinstance(t, Native) and t.specialtype == "jsval": return True return False def count(self): return 1 + class Param(object): size_is = None iid_is = None const = False array = False retval = False shared = False optional = False @@ -976,27 +997,29 @@ class Param(object): raise IDLError("Unexpected parameter attribute", self.location) def toIDL(self): return "%s%s %s %s" % (paramAttlistToIDL(self.attlist), self.paramtype, self.type, self.name) + class Array(object): def __init__(self, basetype): self.type = basetype def isScriptable(self): return self.type.isScriptable() def nativeType(self, calltype, const=False): return "%s%s*" % (const and 'const ' or '', self.type.nativeType(calltype)) + class IDLParser(object): keywords = { 'const': 'CONST', 'interface': 'INTERFACE', 'in': 'IN', 'inout': 'INOUT', 'out': 'OUT', 'attribute': 'ATTRIBUTE',