author | Boris Zbarsky <bzbarsky@mit.edu> |
Wed, 03 Apr 2013 22:22:16 -0400 | |
changeset 127620 | 7e28ac04452a92e5a6aafc0ea52b86dfcdf5f0d7 |
parent 127619 | 87326badb104b97469acf35d51116737e651f837 |
child 127621 | 3455bab4adc7c7e3127905be77b6b3a77b7d09f8 |
push id | 24509 |
push user | ryanvm@gmail.com |
push date | Fri, 05 Apr 2013 00:57:47 +0000 |
treeherder | mozilla-central@55f9e3e3dae7 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mccr8 |
bugs | 856819 |
milestone | 23.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/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -7121,16 +7121,47 @@ class CGRegisterProtos(CGAbstractMethod) register=True): lines.append("REGISTER_PROTO(%s, %s);" % (desc.name, getPrefCheck(desc))) lines.extend("REGISTER_CONSTRUCTOR(%s, %s, %s);" % (n.identifier.name, desc.name, getPrefCheck(desc)) for n in desc.interface.namedConstructors) return '\n'.join(lines) + '\n' def definition_body(self): return self._defineMacro() + self._registerProtos() + self._undefineMacro() +def dependencySortObjects(objects, dependencyGetter, nameGetter): + """ + Sort IDL objects with dependencies on each other such that if A + depends on B then B will come before A. This is needed for + declaring C++ classes in the right order, for example. Objects + that have no dependencies are just sorted by name. + + objects should be something that can produce a set of objects + (e.g. a set, iterator, list, etc). + + dependencyGetter is something that, given an object, should return + the set of objects it depends on. + """ + # XXXbz this will fail if we have two webidl files F1 and F2 such that F1 + # declares an object which depends on an object in F2, and F2 declares an + # object (possibly a different one!) that depends on an object in F1. The + # good news is that I expect this to never happen. + sortedObjects = [] + objects = set(objects) + while len(objects) != 0: + # Find the dictionaries that don't depend on anything else + # anymore and move them over. + toMove = [o for o in objects if + len(dependencyGetter(o) & objects) == 0] + if len(toMove) == 0: + raise TypeError("Loop in dependency graph\n" + + "\n".join(o.location for o in objects)) + objects = objects - set(toMove) + sortedObjects.extend(sorted(toMove, key=nameGetter)) + return sortedObjects + class CGBindingRoot(CGThing): """ Root codegen class for binding generation. Instantiate the class, and call declare or define to generate header or cpp code (respectively). """ def __init__(self, config, prefix, webIDLFile): descriptors = config.getDescriptors(webIDLFile=webIDLFile, hasInterfaceOrInterfacePrototypeObject=True, @@ -7265,40 +7296,26 @@ class CGBindingRoot(CGThing): (e.identifier.name, e.identifier.name))) cgthings = [ fun(e) for e in config.getEnums(webIDLFile) for fun in [makeEnum, makeEnumTypedef] ] # Do codegen for all the dictionaries. We have to be a bit careful # here, because we have to generate these in order from least derived # to most derived so that class inheritance works out. We also have to # generate members before the dictionary that contains them. - # - # XXXbz this will fail if we have two webidl files A and B such that A - # declares a dictionary which inherits from a dictionary in B and B - # declares a dictionary (possibly a different one!) that inherits from a - # dictionary in A. The good news is that I expect this to never happen. - def sortDictionaries(dictionaries): - reSortedDictionaries = [] - dictionaries = set(dictionaries) - while len(dictionaries) != 0: - # Find the dictionaries that don't depend on anything else - # anymore and move them over. - toMove = [d for d in dictionaries if - len(CGDictionary.getDictionaryDependencies(d) & - dictionaries) == 0] - if len(toMove) == 0: - raise TypeError("Loop in dictionary dependency graph") - dictionaries = dictionaries - set(toMove) - reSortedDictionaries.extend(toMove) - return reSortedDictionaries - cgthings.extend([CGDictionary(d, config.getDescriptorProvider(True)) - for d in sortDictionaries(workerDictionaries)]) + for d in + dependencySortObjects(workerDictionaries, + CGDictionary.getDictionaryDependencies, + lambda d: d.identifier.name)]) cgthings.extend([CGDictionary(d, config.getDescriptorProvider(False)) - for d in sortDictionaries(mainDictionaries)]) + for d in + dependencySortObjects(mainDictionaries, + CGDictionary.getDictionaryDependencies, + lambda d: d.identifier.name)]) # Do codegen for all the callbacks. Only do non-worker codegen for now, # since we don't have a sane setup yet for invoking callbacks in workers # and managing their lifetimes. cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(False)) for c in mainCallbacks) # Do codegen for all the descriptors