tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

AccEventGen.py (8264B)


      1 #!/usr/bin/env python
      2 #
      3 # This Source Code Form is subject to the terms of the Mozilla Public
      4 # License, v. 2.0. If a copy of the MPL was not distributed with this
      5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      6 
      7 import os
      8 
      9 import buildconfig
     10 import mozpack.path as mozpath
     11 from xpidl import xpidl
     12 
     13 # Load the webidl configuration file.
     14 glbl = {}
     15 exec(
     16    open(
     17        mozpath.join(buildconfig.topsrcdir, "dom", "bindings", "Bindings.conf")
     18    ).read(),
     19    glbl,
     20 )
     21 webidlconfig = glbl["DOMInterfaces"]
     22 
     23 # Instantiate the parser.
     24 p = xpidl.IDLParser()
     25 
     26 
     27 def findIDL(includePath, interfaceFileName):
     28    for d in includePath:
     29        path = mozpath.join(d, interfaceFileName)
     30        if os.path.exists(path):
     31            return path
     32    raise BaseException(
     33        "No IDL file found for interface %s "
     34        "in include path %r" % (interfaceFileName, includePath)
     35    )
     36 
     37 
     38 def loadEventIDL(parser, includePath, eventname):
     39    eventidl = "nsIAccessible%s.idl" % eventname
     40    idlFile = findIDL(includePath, eventidl)
     41    idl = p.parse(open(idlFile).read(), idlFile)
     42    idl.resolve(includePath, p, webidlconfig)
     43    return idl, idlFile
     44 
     45 
     46 class Configuration:
     47    def __init__(self, filename):
     48        config = {}
     49        exec(open(filename).read(), config)
     50        self.simple_events = config.get("simple_events", [])
     51 
     52 
     53 def firstCap(str):
     54    return str[0].upper() + str[1:]
     55 
     56 
     57 def writeAttributeParams(a):
     58    return "%s a%s" % (a.realtype.nativeType("in"), firstCap(a.name))
     59 
     60 
     61 def print_header_file(fd, conf, incdirs):
     62    idl_paths = set()
     63 
     64    fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n")
     65    fd.write(
     66        "#ifndef _mozilla_a11y_generated_AccEvents_h_\n"
     67        "#define _mozilla_a11y_generated_AccEvents_h_\n\n"
     68    )
     69    fd.write('#include "nscore.h"\n')
     70    fd.write('#include "nsCOMPtr.h"\n')
     71    fd.write('#include "nsCycleCollectionParticipant.h"\n')
     72    fd.write('#include "nsString.h"\n')
     73    for e in conf.simple_events:
     74        fd.write('#include "nsIAccessible%s.h"\n' % e)
     75    for e in conf.simple_events:
     76        idl, idl_path = loadEventIDL(p, incdirs, e)
     77        idl_paths.add(idl_path)
     78        for iface in filter(lambda p: p.kind == "interface", idl.productions):
     79            classname = "xpcAcc%s" % e
     80            baseinterfaces = interfaces(iface)
     81 
     82            fd.write("\nclass %s final : public %s\n" % (classname, iface.name))
     83            fd.write("{\n")
     84            fd.write("public:\n")
     85 
     86            attributes = allAttributes(iface)
     87            args = map(writeAttributeParams, attributes)
     88            fd.write("  %s(%s) :\n" % (classname, ", ".join(args)))
     89 
     90            initializers = []
     91            for a in attributes:
     92                initializers.append("m%s(a%s)" % (firstCap(a.name), firstCap(a.name)))
     93            fd.write("  %s\n  {}\n\n" % ", ".join(initializers))
     94            fd.write("  NS_DECL_CYCLE_COLLECTING_ISUPPORTS\n")
     95            fd.write("  NS_DECL_CYCLE_COLLECTION_CLASS(%s)\n" % (classname))
     96 
     97            for iface in filter(lambda i: i.name != "nsISupports", baseinterfaces):
     98                fd.write("  NS_DECL_%s\n" % iface.name.upper())
     99 
    100            fd.write("\nprivate:\n")
    101            fd.write("  ~%s() {}\n\n" % classname)
    102            for a in attributes:
    103                fd.write("  %s\n" % attributeVariableTypeAndName(a))
    104            fd.write("};\n\n")
    105 
    106    fd.write("#endif\n")
    107 
    108    return idl_paths
    109 
    110 
    111 def interfaceAttributeTypes(idl):
    112    ifaces = filter(lambda p: p.kind == "interface", idl.productions)
    113    attributes = []
    114    for i in ifaces:
    115        ifaceAttributes = allAttributes(i)
    116        attributes.extend(ifaceAttributes)
    117    ifaceAttrs = filter(lambda a: a.realtype.nativeType("in").endswith("*"), attributes)
    118    return map(lambda a: a.realtype.nativeType("in").strip(" *"), ifaceAttrs)
    119 
    120 
    121 def print_cpp(idl, fd, conf, eventname):
    122    for p in idl.productions:
    123        if p.kind == "interface":
    124            write_cpp(eventname, p, fd)
    125 
    126 
    127 def print_cpp_file(fd, conf, incdirs):
    128    idl_paths = set()
    129    fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n")
    130    fd.write('#include "xpcAccEvents.h"\n')
    131 
    132    includes = []
    133    for e in conf.simple_events:
    134        if e not in includes:
    135            includes.append("nsIAccessible%s" % e)
    136 
    137    types = []
    138    for e in conf.simple_events:
    139        idl, idl_path = loadEventIDL(p, incdirs, e)
    140        idl_paths.add(idl_path)
    141        types.extend(interfaceAttributeTypes(idl))
    142 
    143    for c in types:
    144        fd.write('#include "%s.h"\n' % c)
    145 
    146    fd.write("\n")
    147    for e in conf.simple_events:
    148        idl, idl_path = loadEventIDL(p, incdirs, e)
    149        idl_paths.add(idl_path)
    150        print_cpp(idl, fd, conf, e)
    151 
    152    return idl_paths
    153 
    154 
    155 def attributeVariableTypeAndName(a):
    156    if a.realtype.nativeType("in").endswith("*"):
    157        l = [
    158            "nsCOMPtr<%s> m%s;"
    159            % (a.realtype.nativeType("in").strip("* "), firstCap(a.name))
    160        ]
    161    elif a.realtype.nativeType("in").count("nsAString"):
    162        l = ["nsString m%s;" % firstCap(a.name)]
    163    elif a.realtype.nativeType("in").count("nsACString"):
    164        l = ["nsCString m%s;" % firstCap(a.name)]
    165    else:
    166        l = ["%sm%s;" % (a.realtype.nativeType("in"), firstCap(a.name))]
    167    return ", ".join(l)
    168 
    169 
    170 def writeAttributeGetter(fd, classname, a):
    171    fd.write("NS_IMETHODIMP\n")
    172    fd.write("%s::Get%s(" % (classname, firstCap(a.name)))
    173    if a.realtype.nativeType("in").endswith("*"):
    174        fd.write(
    175            "%s** a%s" % (a.realtype.nativeType("in").strip("* "), firstCap(a.name))
    176        )
    177    elif a.realtype.nativeType("in").count("nsAString"):
    178        fd.write("nsAString& a%s" % firstCap(a.name))
    179    elif a.realtype.nativeType("in").count("nsACString"):
    180        fd.write("nsACString& a%s" % firstCap(a.name))
    181    else:
    182        fd.write("%s*a%s" % (a.realtype.nativeType("in"), firstCap(a.name)))
    183    fd.write(")\n")
    184    fd.write("{\n")
    185    if a.realtype.nativeType("in").endswith("*"):
    186        fd.write("  NS_IF_ADDREF(*a%s = m%s);\n" % (firstCap(a.name), firstCap(a.name)))
    187    elif a.realtype.nativeType("in").count("nsAString"):
    188        fd.write("  a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
    189    elif a.realtype.nativeType("in").count("nsACString"):
    190        fd.write("  a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
    191    else:
    192        fd.write("  *a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
    193    fd.write("  return NS_OK;\n")
    194    fd.write("}\n\n")
    195 
    196 
    197 def interfaces(iface):
    198    interfaces = []
    199    while iface.base:
    200        interfaces.append(iface)
    201        iface = iface.idl.getName(xpidl.TypeId(iface.base), iface.location)
    202    interfaces.append(iface)
    203    interfaces.reverse()
    204    return interfaces
    205 
    206 
    207 def allAttributes(iface):
    208    attributes = []
    209    for i in interfaces(iface):
    210        attrs = filter(lambda m: isinstance(m, xpidl.Attribute), i.members)
    211        attributes.extend(attrs)
    212 
    213    return attributes
    214 
    215 
    216 def write_cpp(eventname, iface, fd):
    217    classname = "xpcAcc%s" % eventname
    218    attributes = allAttributes(iface)
    219    ccattributes = filter(
    220        lambda m: m.realtype.nativeType("in").endswith("*"), attributes
    221    )
    222    fd.write("NS_IMPL_CYCLE_COLLECTION(%s" % classname)
    223    for c in ccattributes:
    224        fd.write(", m%s" % firstCap(c.name))
    225    fd.write(")\n\n")
    226 
    227    fd.write("NS_IMPL_CYCLE_COLLECTING_ADDREF(%s)\n" % classname)
    228    fd.write("NS_IMPL_CYCLE_COLLECTING_RELEASE(%s)\n\n" % classname)
    229 
    230    fd.write("NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(%s)\n" % classname)
    231    for baseiface in interfaces(iface):
    232        fd.write("  NS_INTERFACE_MAP_ENTRY(%s)\n" % baseiface.name)
    233    fd.write("NS_INTERFACE_MAP_END\n\n")
    234 
    235    for a in attributes:
    236        writeAttributeGetter(fd, classname, a)
    237 
    238 
    239 def get_conf(conf_file):
    240    conf = Configuration(conf_file)
    241    inc_dir = [
    242        mozpath.join(buildconfig.topsrcdir, "accessible", "interfaces"),
    243        mozpath.join(buildconfig.topsrcdir, "xpcom", "base"),
    244    ]
    245    return conf, inc_dir
    246 
    247 
    248 def gen_files(fd, conf_file):
    249    deps = set()
    250    conf, inc_dir = get_conf(conf_file)
    251    deps.update(print_header_file(fd, conf, inc_dir))
    252    with open(
    253        os.path.join(os.path.dirname(fd.name), "xpcAccEvents.cpp"), "w"
    254    ) as cpp_fd:
    255        deps.update(print_cpp_file(cpp_fd, conf, inc_dir))
    256    return deps