dom/bindings/Configuration.py
author Bobby Holley <bobbyholley@gmail.com>
Wed, 08 Feb 2012 13:46:41 -0800
changeset 86464 979451d9d4167e15d2eb787458652e673877e394
parent 86463 bab09b5e0e9fb52b17668a3aac86e1baf27b3138
child 86748 8b5809ac11749bdd197100953df2eda9623e34d7
permissions -rw-r--r--
Add functionality for getting the correct descriptor for an interface given context (ie, worker vs non-worker).

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.

autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n"

class Configuration:
    """
    Represents global configuration state based on IDL parse data and
    the configuration file.
    """
    def __init__(self, filename, parseData):

        # Read the configuration file.
        glbl = {}
        execfile(filename, glbl)
        config = glbl['DOMInterfaces']

        # Build descriptors for all the interfaces we have in the parse data.
        # This allows callers to specify a subset of interfaces by filtering
        # |parseData|.
        self.descriptors = []
        self.interfaces = {}
        for iface in parseData:
            if not iface.isInterface(): continue
            self.interfaces[iface.identifier.name] = iface
            if iface.identifier.name not in config: continue
            entry = config[iface.identifier.name]
            if not isinstance(entry, list):
                assert isinstance(entry, dict)
                entry = [entry]
            self.descriptors.extend([Descriptor(self, iface, x) for x in entry])

        # Keep the descriptor list sorted for determinism.
        self.descriptors.sort(lambda x,y: cmp(x.name, y.name))

    def getInterface(self, ifname):
        return self.interfaces[ifname]
    def getAllDescriptors(self, webIDLFile=None):
        if not webIDLFile:
            return self.descriptors
        else:
            return filter(lambda x: x.interface.filename() == webIDLFile, self.descriptors)
    def getConcreteDescriptors(self, webIDLFile=None):
        return filter(lambda x: x.concrete, self.getAllDescriptors(webIDLFile))
    def getDescriptorsForInterface(self, iface):
        return filter(lambda x: x.interface is iface, self.descriptors)

class Descriptor:
    """
    Represents a single descriptor for an interface. See Bindings.conf.
    """
    def __init__(self, config, interface, desc):
        self.config = config
        self.interface = interface

        # Read the desc, and fill in the relevant defaults.
        self.concrete = desc['concrete']
        self.workers = desc.get('workers', False)
        self.nativeIsISupports = not self.workers
        if self.concrete:
            self.nativeClass = desc['nativeClass']
        else:
            self.nativeInterface = desc.get('nativeInterface', 'XXXFillMeInbz!')

        headerDefault = self.nativeClass if self.concrete else self.nativeInterface
        headerDefault = headerDefault.split("::")[-1] + ".h"
        self.headerFile = desc.get('headerFile', headerDefault)

        self.customTrace = desc.get('customTrace', self.workers)
        self.customFinalize = desc.get('customFinalize', self.workers)

        def make_name(name):
            return name + "_workers" if self.workers else name
        self.name = make_name(interface.identifier.name)

        # Build the prototype chain.
        self.prototypeChain = []
        parent = interface
        while parent:
            self.prototypeChain.insert(0, make_name(parent.identifier.name))
            parent = parent.parent

    def getDescriptor(self, interfaceName):
        """
        Gets the appropriate descriptor for the given interface name given the
        context of the current descriptor. This selects the appropriate
        implementation for cases like workers.
        """
        iface = self.config.getInterface(interfaceName)
        descriptors = self.config.getDescriptorsForInterface(iface)

        # The only filter we currently have is workers vs non-workers.
        matches = filter(lambda x: x.workers is self.workers, descriptors)

        # After filtering, we should have exactly one result.
        assert len(matches) is 1
        return matches[0]