dom/bindings/GlobalGen.py
author Boris Zbarsky <bzbarsky@mit.edu>
Thu, 26 Jan 2012 17:23:31 +0100
changeset 85149 4119ff5bd1104150455174319f6f1edba3d41c8f
parent 85148 fdee219a75502a61e28f8d2990ec4d91385e4dbd
child 85156 fd3416b716f37f849188ceb77007c9b124807623
permissions -rw-r--r--
Implement prototype setup infrastructure.

# 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/.

# We do one global pass over all the WebIDL to generate our prototype enum
# and generate information for subsequent phases.

import os
import cStringIO
import WebIDL
import cPickle
from Codegen import Configuration, DOMClass, DOMClassImplementation

def generate_prototype_list(config, filename):

    # Read a copy of the old file, so that we don't touch it if it hasn't changed.
    oldFileContents = ""
    try:
        oldFile = open(filename, 'r')
        oldFileContents = ''.join(oldFile.readlines())
        oldFile.close()
    except:
        pass

    prologue = """
/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */

#ifndef mozilla_dom_bindings_PrototypeList_h
#define mozilla_dom_bindings_PrototypeList_h

namespace mozilla {
namespace dom {
namespace bindings {
namespace prototypes {
namespace id {

enum ID
{
"""
    epilogue = """
};

} // namespace id

typedef id::ID ID;

} // namespace prototypes
} // namespace bindings
} // namespace dom
} // namespace mozilla

#endif // mozilla_dom_bindings_PrototypeList_h
"""

    protoList = []

    domClasses = config.dom_classes.values()
    # Sort the class list so that it doesn't change from run to run
    domClasses.sort()
    for domClass in domClasses:
        for implementation in domClass.implementations:
            protoList.append(implementation.name)

    # Append the enum count.
    protoList.append('Count')

    # Add appropriate indentation before the prototype strings.
    protoList = ["  " + p for p in protoList]

    # Start the enum at 0
    protoList[0] = protoList[0] + " = 0"

    newFileContents = prologue + ',\n'.join(protoList) + epilogue

    if newFileContents == oldFileContents:
        print "Prototype list hasn't changed - not touching %s" % (filename)
        return

    print "Generating prototype list: %s" % (filename)
    f = open(filename, 'w')
    f.write(newFileContents)
    f.close()

def main():

    # Parse arguments.
    from optparse import OptionParser
    usageString = "usage: %prog [options] webidldir [files]"
    o = OptionParser(usage=usageString)
    o.add_option("--verbose-errors", action='store_true', default=False,
                 help="When an error happens, display the Python traceback.")
    (options, args) = o.parse_args()

    if len(args) < 2:
        o.error(usageString)

    configFile = args[0]
    baseDir = args[1]
    fileList = args[2:]

    # Parse the WebIDL.
    parser = WebIDL.Parser()
    for filename in fileList:
        fullPath = os.path.join(baseDir, filename)
        f = open(fullPath, 'r')
        lines = f.readlines()
        f.close()
        parser.parse(''.join(lines), fullPath)
    parserResults = parser.finish()

    # Write the parser results out to a pickle.
    resultsFile = open('ParserResults.pkl', 'wb')
    cPickle.dump(parserResults, resultsFile, -1)
    resultsFile.close()

    configData = dict()
    for r in parserResults:
        configData[r.identifier.name] = r
    config = Configuration(configFile, configData)

    # Generate the prototype list header.
    generate_prototype_list(config, "PrototypeList.h")

if __name__ == '__main__':
    main()