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