js/xpconnect/src/event_impl_gen.py

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rwxr-xr-x

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 #!/usr/bin/env python
michael@0 2 # header.py - Generate C++ header files from IDL.
michael@0 3 #
michael@0 4 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 5 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 6 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 7
michael@0 8 import sys, os, xpidl, makeutils
michael@0 9
michael@0 10 def strip_end(text, suffix):
michael@0 11 if not text.endswith(suffix):
michael@0 12 return text
michael@0 13 return text[:-len(suffix)]
michael@0 14
michael@0 15 def findIDL(includePath, interfaceFileName):
michael@0 16 for d in includePath:
michael@0 17 # Not os.path.join: we need a forward slash even on Windows because
michael@0 18 # this filename ends up in makedepend output.
michael@0 19 path = d + '/' + interfaceFileName
michael@0 20 if os.path.exists(path):
michael@0 21 return path
michael@0 22 raise BaseException("No IDL file found for interface %s "
michael@0 23 "in include path %r"
michael@0 24 % (interfaceFileName, includePath))
michael@0 25
michael@0 26 eventFileNameToIdl = {};
michael@0 27
michael@0 28 def loadIDL(parser, includePath, filename):
michael@0 29 global eventFileNameToIdl
michael@0 30 if filename in eventFileNameToIdl:
michael@0 31 return eventFileNameToIdl[filename]
michael@0 32
michael@0 33 idlFile = findIDL(includePath, filename)
michael@0 34 if not idlFile in makeutils.dependencies:
michael@0 35 makeutils.dependencies.append(idlFile)
michael@0 36 idl = p.parse(open(idlFile).read(), idlFile)
michael@0 37 idl.resolve(includePath, p)
michael@0 38 eventFileNameToIdl[filename] = idl
michael@0 39 return idl
michael@0 40
michael@0 41 def loadEventIDL(parser, includePath, eventname):
michael@0 42 eventidl = ("nsIDOM%s.idl" % eventname)
michael@0 43 return loadIDL(parser, includePath, eventidl)
michael@0 44
michael@0 45 class Configuration:
michael@0 46 def __init__(self, filename):
michael@0 47 config = {}
michael@0 48 execfile(filename, config)
michael@0 49 self.simple_events = config.get('simple_events', [])
michael@0 50 self.special_includes = config.get('special_includes', [])
michael@0 51 self.exclude_automatic_type_include = config.get('exclude_automatic_type_include', [])
michael@0 52 self.xpidl_to_native = config.get('xpidl_to_native', [])
michael@0 53
michael@0 54 def readConfigFile(filename):
michael@0 55 return Configuration(filename)
michael@0 56
michael@0 57 def firstCap(str):
michael@0 58 return str[0].upper() + str[1:]
michael@0 59
michael@0 60 def getBaseName(iface):
michael@0 61 return ("%s" % iface.base[6:])
michael@0 62
michael@0 63 def print_header_file(fd, conf):
michael@0 64 fd.write("#ifndef _gen_mozilla_idl_generated_events_h_\n"
michael@0 65 "#define _gen_mozilla_idl_generated_events_h_\n\n")
michael@0 66 fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n")
michael@0 67 fd.write("#include \"nscore.h\"\n")
michael@0 68 fd.write("class nsIDOMEvent;\n")
michael@0 69 fd.write("class nsPresContext;\n")
michael@0 70 fd.write("namespace mozilla {\n");
michael@0 71 fd.write("class WidgetEvent;\n")
michael@0 72 fd.write("namespace dom {\n");
michael@0 73 fd.write("class EventTarget;\n")
michael@0 74 fd.write("}\n");
michael@0 75 fd.write("}\n\n");
michael@0 76 for e in conf.simple_events:
michael@0 77 fd.write("nsresult\n")
michael@0 78 fd.write("NS_NewDOM%s(nsIDOMEvent** aInstance, " % e)
michael@0 79 fd.write("mozilla::dom::EventTarget* aOwner, ")
michael@0 80 fd.write("nsPresContext* aPresContext, mozilla::WidgetEvent* aEvent);\n")
michael@0 81
michael@0 82 fd.write("\n#endif\n")
michael@0 83
michael@0 84 def print_classes_file(fd, conf):
michael@0 85 fd.write("#ifndef _gen_mozilla_idl_generated_event_declarations_h_\n")
michael@0 86 fd.write("#define _gen_mozilla_idl_generated_event_declarations_h_\n\n")
michael@0 87
michael@0 88 fd.write("#include \"mozilla/dom/Event.h\"\n");
michael@0 89 includes = []
michael@0 90 for s in conf.special_includes:
michael@0 91 if not s in includes:
michael@0 92 includes.append(strip_end(s, ".h"))
michael@0 93
michael@0 94 for e in conf.simple_events:
michael@0 95 if not e in includes:
michael@0 96 includes.append(("nsIDOM%s" % e))
michael@0 97
michael@0 98 attrnames = []
michael@0 99 for e in conf.simple_events:
michael@0 100 idl = loadEventIDL(p, options.incdirs, e)
michael@0 101 collect_names_and_non_primitive_attribute_types(idl, attrnames, includes)
michael@0 102
michael@0 103 for c in includes:
michael@0 104 if not c in conf.exclude_automatic_type_include:
michael@0 105 fd.write("#include \"%s.h\"\n" % c)
michael@0 106
michael@0 107 for e in conf.simple_events:
michael@0 108 fd.write('#include "mozilla/dom/%sBinding.h"\n' % e);
michael@0 109
michael@0 110 fd.write("namespace mozilla {\n")
michael@0 111 fd.write("namespace dom {\n")
michael@0 112 for e in conf.simple_events:
michael@0 113 idl = loadEventIDL(p, options.incdirs, e)
michael@0 114 for pr in idl.productions:
michael@0 115 if pr.kind == 'interface':
michael@0 116 print_class_declaration(e, pr, fd, conf)
michael@0 117 fd.write("} // namespace dom\n")
michael@0 118 fd.write("} // namespace mozilla\n\n")
michael@0 119 fd.write("#endif\n");
michael@0 120
michael@0 121 def print_class_declaration(eventname, iface, fd, conf):
michael@0 122 classname = ("%s" % eventname)
michael@0 123 basename = getBaseName(iface)
michael@0 124 attributes = []
michael@0 125 ccattributes = []
michael@0 126 for member in iface.members:
michael@0 127 if isinstance(member, xpidl.Attribute):
michael@0 128 attributes.append(member)
michael@0 129 if (member.realtype.nativeType('in').endswith('*')):
michael@0 130 ccattributes.append(member);
michael@0 131
michael@0 132 baseinterfaces = []
michael@0 133 baseiface = iface.idl.getName(iface.base, iface.location)
michael@0 134 while baseiface.name != "nsIDOMEvent":
michael@0 135 baseinterfaces.append(baseiface)
michael@0 136 baseiface = baseiface.idl.getName(baseiface.base, baseiface.location)
michael@0 137 baseinterfaces.reverse()
michael@0 138
michael@0 139 allattributes = []
michael@0 140 for baseiface in baseinterfaces:
michael@0 141 for member in baseiface.members:
michael@0 142 if isinstance(member, xpidl.Attribute):
michael@0 143 allattributes.append(member)
michael@0 144 allattributes.extend(attributes);
michael@0 145
michael@0 146 fd.write("\nclass %s MOZ_FINAL : public %s, public %s\n" % (classname, basename, iface.name))
michael@0 147 fd.write("{\n")
michael@0 148 fd.write("public:\n")
michael@0 149 fd.write(" %s(mozilla::dom::EventTarget* aOwner, " % classname)
michael@0 150 fd.write("nsPresContext* aPresContext = nullptr, mozilla::WidgetEvent* aEvent = nullptr);\n");
michael@0 151 fd.write(" virtual ~%s();\n\n" % classname)
michael@0 152 fd.write(" NS_DECL_ISUPPORTS_INHERITED\n")
michael@0 153 fd.write(" NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(%s, %s)\n" % (classname, basename))
michael@0 154 fd.write(" NS_FORWARD_TO_EVENT\n")
michael@0 155
michael@0 156 for baseiface in baseinterfaces:
michael@0 157 baseimpl = ("%s" % baseiface.name[6:])
michael@0 158 fd.write(" NS_FORWARD_%s(%s::)\n" % (baseiface.name.upper(), baseimpl))
michael@0 159
michael@0 160 fd.write(" NS_DECL_%s\n" % iface.name.upper())
michael@0 161
michael@0 162 hasVariant = False
michael@0 163 for a in allattributes:
michael@0 164 if a.type == "nsIVariant":
michael@0 165 hasVariant = True
michael@0 166 break;
michael@0 167 fd.write(" static already_AddRefed<%s> Constructor(const GlobalObject& aGlobal, " % eventname)
michael@0 168 if hasVariant:
michael@0 169 fd.write("JSContext* aCx, ")
michael@0 170 fd.write("const nsAString& aType, ")
michael@0 171 fd.write("const %sInit& aParam, " % eventname)
michael@0 172 fd.write("ErrorResult& aRv);\n\n")
michael@0 173
michael@0 174 fd.write(" virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE\n")
michael@0 175 fd.write(" {\n")
michael@0 176 fd.write(" return mozilla::dom::%sBinding::Wrap(aCx, this);\n" % eventname)
michael@0 177 fd.write(" }\n\n")
michael@0 178
michael@0 179 for a in attributes:
michael@0 180 """xpidl methods take care of string member variables!"""
michael@0 181 firstCapName = firstCap(a.name)
michael@0 182 cleanNativeType = a.realtype.nativeType('in').strip('* ')
michael@0 183 if a.realtype.nativeType('in').count("nsAString"):
michael@0 184 continue
michael@0 185 elif a.realtype.nativeType('in').count("nsIVariant"):
michael@0 186 fd.write(" void Get%s(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval, ErrorResult& aRv);\n\n" % firstCapName);
michael@0 187 elif a.realtype.nativeType('in').endswith('*'):
michael@0 188 fd.write(" already_AddRefed<%s> Get%s()\n" % (xpidl_to_native(cleanNativeType, conf), firstCapName))
michael@0 189 fd.write(" {\n");
michael@0 190 fd.write(" nsCOMPtr<%s> %s = do_QueryInterface(m%s);\n" % (xpidl_to_canonical(cleanNativeType, conf), a.name, firstCapName))
michael@0 191 fd.write(" return %s.forget().downcast<%s>();\n" % (a.name, xpidl_to_native(cleanNativeType, conf)))
michael@0 192 fd.write(" }\n\n");
michael@0 193 else:
michael@0 194 fd.write(" %s %s()\n" % (cleanNativeType, firstCapName))
michael@0 195 fd.write(" {\n");
michael@0 196 fd.write(" return m%s;\n" % firstCapName)
michael@0 197 fd.write(" }\n\n");
michael@0 198
michael@0 199 fd.write(" void ")
michael@0 200 fd.write("Init%s(" % eventname)
michael@0 201 if hasVariant:
michael@0 202 fd.write("JSContext* aCx, ")
michael@0 203 fd.write("const nsAString& aType, bool aCanBubble, bool aCancelable")
michael@0 204 for a in allattributes:
michael@0 205 writeNativeAttributeParams(fd, a, conf)
michael@0 206 fd.write(", ErrorResult& aRv);\n\n")
michael@0 207
michael@0 208 fd.write("protected:\n")
michael@0 209 for a in attributes:
michael@0 210 fd.write(" %s\n" % attributeVariableTypeAndName(a))
michael@0 211 fd.write("};\n")
michael@0 212
michael@0 213 def collect_names_and_non_primitive_attribute_types(idl, attrnames, forwards):
michael@0 214 for p in idl.productions:
michael@0 215 if p.kind == 'interface' or p.kind == 'dictionary':
michael@0 216 interfaces = []
michael@0 217 base = p.base
michael@0 218 baseiface = p
michael@0 219 while base is not None:
michael@0 220 baseiface = baseiface.idl.getName(baseiface.base, baseiface.location)
michael@0 221 interfaces.append(baseiface)
michael@0 222 base = baseiface.base
michael@0 223
michael@0 224 interfaces.reverse()
michael@0 225 interfaces.append(p)
michael@0 226
michael@0 227 for iface in interfaces:
michael@0 228 collect_names_and_non_primitive_attribute_types_from_interface(iface, attrnames, forwards)
michael@0 229
michael@0 230 def collect_names_and_non_primitive_attribute_types_from_interface(iface, attrnames, forwards):
michael@0 231 for member in iface.members:
michael@0 232 if isinstance(member, xpidl.Attribute):
michael@0 233 if not member.name in attrnames:
michael@0 234 attrnames.append(member.name)
michael@0 235 if member.realtype.nativeType('in').endswith('*'):
michael@0 236 t = member.realtype.nativeType('in').strip('* ')
michael@0 237 if not t in forwards:
michael@0 238 forwards.append(t)
michael@0 239
michael@0 240 def print_cpp(idl, fd, conf, eventname):
michael@0 241 for p in idl.productions:
michael@0 242 if p.kind == 'interface':
michael@0 243 write_cpp(eventname, p, fd, conf)
michael@0 244
michael@0 245 def print_cpp_file(fd, conf):
michael@0 246 fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n")
michael@0 247 fd.write('#include "GeneratedEventClasses.h"\n')
michael@0 248 fd.write('#include "xpcprivate.h"\n');
michael@0 249 fd.write('#include "mozilla/dom/Event.h"\n');
michael@0 250 fd.write('#include "mozilla/dom/EventTarget.h"\n');
michael@0 251
michael@0 252 for e in conf.simple_events:
michael@0 253 idl = loadEventIDL(p, options.incdirs, e)
michael@0 254 print_cpp(idl, fd, conf, e)
michael@0 255
michael@0 256 def init_value(attribute):
michael@0 257 realtype = attribute.realtype.nativeType('in')
michael@0 258 realtype = realtype.strip(' ')
michael@0 259 if realtype.endswith('*'):
michael@0 260 return "nullptr"
michael@0 261 if realtype == "bool":
michael@0 262 return "false"
michael@0 263 if realtype.count("nsAString"):
michael@0 264 return ""
michael@0 265 if realtype.count("nsACString"):
michael@0 266 return ""
michael@0 267 if realtype.count("JS::Value"):
michael@0 268 raise BaseException("JS::Value not supported in simple events!")
michael@0 269 return "0"
michael@0 270
michael@0 271 def attributeVariableTypeAndName(a):
michael@0 272 if a.realtype.nativeType('in').endswith('*'):
michael@0 273 l = ["nsCOMPtr<%s> m%s;" % (a.realtype.nativeType('in').strip('* '),
michael@0 274 firstCap(a.name))]
michael@0 275 elif a.realtype.nativeType('in').count("nsAString"):
michael@0 276 l = ["nsString m%s;" % firstCap(a.name)]
michael@0 277 elif a.realtype.nativeType('in').count("nsACString"):
michael@0 278 l = ["nsCString m%s;" % firstCap(a.name)]
michael@0 279 else:
michael@0 280 l = ["%sm%s;" % (a.realtype.nativeType('in'),
michael@0 281 firstCap(a.name))]
michael@0 282 return ", ".join(l)
michael@0 283
michael@0 284 def writeAttributeGetter(fd, classname, a):
michael@0 285 fd.write("NS_IMETHODIMP\n")
michael@0 286 fd.write("%s::Get%s(" % (classname, firstCap(a.name)))
michael@0 287 if a.realtype.nativeType('in').endswith('*'):
michael@0 288 fd.write("%s** a%s" % (a.realtype.nativeType('in').strip('* '), firstCap(a.name)))
michael@0 289 elif a.realtype.nativeType('in').count("nsAString"):
michael@0 290 fd.write("nsAString& a%s" % firstCap(a.name))
michael@0 291 elif a.realtype.nativeType('in').count("nsACString"):
michael@0 292 fd.write("nsACString& a%s" % firstCap(a.name))
michael@0 293 else:
michael@0 294 fd.write("%s*a%s" % (a.realtype.nativeType('in'), firstCap(a.name)))
michael@0 295 fd.write(")\n");
michael@0 296 fd.write("{\n");
michael@0 297 if a.realtype.nativeType('in').endswith('*'):
michael@0 298 fd.write(" NS_IF_ADDREF(*a%s = m%s);\n" % (firstCap(a.name), firstCap(a.name)))
michael@0 299 elif a.realtype.nativeType('in').count("nsAString"):
michael@0 300 fd.write(" a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
michael@0 301 elif a.realtype.nativeType('in').count("nsACString"):
michael@0 302 fd.write(" a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
michael@0 303 else:
michael@0 304 fd.write(" *a%s = %s();\n" % (firstCap(a.name), firstCap(a.name)))
michael@0 305 fd.write(" return NS_OK;\n");
michael@0 306 fd.write("}\n\n");
michael@0 307 if a.realtype.nativeType('in').count("nsIVariant"):
michael@0 308 fd.write("void\n")
michael@0 309 fd.write("%s::Get%s(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval, ErrorResult& aRv)\n" % (classname, firstCap(a.name)))
michael@0 310 fd.write("{\n")
michael@0 311 fd.write(" nsresult rv = NS_ERROR_UNEXPECTED;\n")
michael@0 312 fd.write(" if (!m%s) {\n" % firstCap(a.name))
michael@0 313 fd.write(" aRetval.setNull();\n")
michael@0 314 fd.write(" } else if (!XPCVariant::VariantDataToJS(m%s, &rv, aRetval)) {\n" % (firstCap(a.name)))
michael@0 315 fd.write(" aRv.Throw(NS_ERROR_FAILURE);\n")
michael@0 316 fd.write(" }\n")
michael@0 317 fd.write("}\n\n")
michael@0 318
michael@0 319 def writeAttributeParams(fd, a):
michael@0 320 if a.realtype.nativeType('in').endswith('*'):
michael@0 321 fd.write(", %s* a%s" % (a.realtype.nativeType('in').strip('* '), firstCap(a.name)))
michael@0 322 elif a.realtype.nativeType('in').count("nsAString"):
michael@0 323 fd.write(", const nsAString& a%s" % firstCap(a.name))
michael@0 324 elif a.realtype.nativeType('in').count("nsACString"):
michael@0 325 fd.write(", const nsACString& a%s" % firstCap(a.name))
michael@0 326 else:
michael@0 327 fd.write(", %s a%s" % (a.realtype.nativeType('in'), firstCap(a.name)))
michael@0 328
michael@0 329 def writeNativeAttributeParams(fd, a, conf):
michael@0 330 if a.type == "nsIVariant":
michael@0 331 fd.write(", JS::Value a%s" % firstCap(a.name));
michael@0 332 elif a.realtype.nativeType('in').endswith('*'):
michael@0 333 fd.write(", %s* a%s" % (xpidl_to_native(a.realtype.nativeType('in').strip('* '), conf), firstCap(a.name)))
michael@0 334 elif a.realtype.nativeType('in').count("nsAString"):
michael@0 335 fd.write(", const nsAString& a%s" % firstCap(a.name))
michael@0 336 elif a.realtype.nativeType('in').count("nsACString"):
michael@0 337 fd.write(", const nsACString& a%s" % firstCap(a.name))
michael@0 338 else:
michael@0 339 fd.write(", %s a%s" % (a.realtype.nativeType('in'), firstCap(a.name)))
michael@0 340
michael@0 341 def write_cpp(eventname, iface, fd, conf):
michael@0 342 classname = ("%s" % eventname)
michael@0 343 basename = getBaseName(iface)
michael@0 344 attributes = []
michael@0 345 ccattributes = []
michael@0 346 for member in iface.members:
michael@0 347 if isinstance(member, xpidl.Attribute):
michael@0 348 attributes.append(member)
michael@0 349 if (member.realtype.nativeType('in').endswith('*')):
michael@0 350 ccattributes.append(member);
michael@0 351
michael@0 352 baseinterfaces = []
michael@0 353 baseiface = iface.idl.getName(iface.base, iface.location)
michael@0 354 while baseiface.name != "nsIDOMEvent":
michael@0 355 baseinterfaces.append(baseiface)
michael@0 356 baseiface = baseiface.idl.getName(baseiface.base, baseiface.location)
michael@0 357 baseinterfaces.reverse()
michael@0 358
michael@0 359 baseattributes = []
michael@0 360 for baseiface in baseinterfaces:
michael@0 361 for member in baseiface.members:
michael@0 362 if isinstance(member, xpidl.Attribute):
michael@0 363 baseattributes.append(member)
michael@0 364
michael@0 365 allattributes = []
michael@0 366 allattributes.extend(baseattributes);
michael@0 367 allattributes.extend(attributes);
michael@0 368
michael@0 369 fd.write("namespace mozilla {\n")
michael@0 370 fd.write("namespace dom {\n\n")
michael@0 371
michael@0 372 fd.write("%s::%s(mozilla::dom::EventTarget* aOwner, " % (classname, classname))
michael@0 373 fd.write("nsPresContext* aPresContext, mozilla::WidgetEvent* aEvent)\n");
michael@0 374 fd.write(": %s(aOwner, aPresContext, aEvent)" % basename)
michael@0 375 for a in attributes:
michael@0 376 fd.write(",\n m%s(%s)" % (firstCap(a.name), init_value(a)))
michael@0 377 fd.write("\n{\n")
michael@0 378 fd.write("}\n\n")
michael@0 379
michael@0 380 fd.write("%s::~%s() {}\n\n" % (classname, classname))
michael@0 381
michael@0 382 fd.write("NS_IMPL_CYCLE_COLLECTION_CLASS(%s)\n" % (classname))
michael@0 383 fd.write("NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(%s, %s)\n" % (classname, basename))
michael@0 384 for c in ccattributes:
michael@0 385 fd.write(" NS_IMPL_CYCLE_COLLECTION_UNLINK(m%s)\n" % firstCap(c.name))
michael@0 386 fd.write("NS_IMPL_CYCLE_COLLECTION_UNLINK_END\n\n");
michael@0 387 fd.write("NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(%s, %s)\n" % (classname, basename))
michael@0 388 for c in ccattributes:
michael@0 389 fd.write(" NS_IMPL_CYCLE_COLLECTION_TRAVERSE(m%s)\n" % firstCap(c.name))
michael@0 390 fd.write("NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END\n\n");
michael@0 391
michael@0 392 fd.write("NS_IMPL_ADDREF_INHERITED(%s, %s)\n" % (classname, basename))
michael@0 393 fd.write("NS_IMPL_RELEASE_INHERITED(%s, %s)\n\n" % (classname, basename))
michael@0 394
michael@0 395 fd.write("NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(%s)\n" % classname)
michael@0 396 fd.write(" NS_INTERFACE_MAP_ENTRY(nsIDOM%s)\n" % eventname)
michael@0 397 fd.write("NS_INTERFACE_MAP_END_INHERITING(%s)\n\n" % basename)
michael@0 398
michael@0 399 hasVariant = False
michael@0 400 for a in allattributes:
michael@0 401 if a.type == "nsIVariant":
michael@0 402 hasVariant = True
michael@0 403 break;
michael@0 404
michael@0 405 fd.write("already_AddRefed<%s>\n" % eventname)
michael@0 406 fd.write("%s::Constructor(const GlobalObject& aGlobal, " % eventname)
michael@0 407 if hasVariant:
michael@0 408 fd.write("JSContext* aCx, ");
michael@0 409 fd.write("const nsAString& aType, ")
michael@0 410 fd.write("const %sInit& aParam, " % eventname)
michael@0 411 fd.write("ErrorResult& aRv)\n")
michael@0 412 fd.write("{\n")
michael@0 413 fd.write(" nsCOMPtr<mozilla::dom::EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());\n")
michael@0 414 fd.write(" nsRefPtr<%s> e = new %s(t, nullptr, nullptr);\n" % (eventname, eventname))
michael@0 415 fd.write(" bool trusted = e->Init(t);\n")
michael@0 416 fd.write(" e->Init%s(" % eventname)
michael@0 417 if hasVariant:
michael@0 418 fd.write("aCx, ");
michael@0 419 fd.write("aType, aParam.mBubbles, aParam.mCancelable")
michael@0 420 for a in allattributes:
michael@0 421 fd.write(", aParam.m%s" % firstCap(a.name))
michael@0 422 fd.write(", aRv);\n")
michael@0 423 fd.write(" e->SetTrusted(trusted);\n")
michael@0 424 fd.write(" return e.forget();\n")
michael@0 425 fd.write("}\n\n")
michael@0 426
michael@0 427 fd.write("NS_IMETHODIMP\n")
michael@0 428 fd.write("%s::Init%s(" % (classname, eventname))
michael@0 429 fd.write("const nsAString& aType, bool aCanBubble, bool aCancelable")
michael@0 430 for a in allattributes:
michael@0 431 writeAttributeParams(fd, a)
michael@0 432 fd.write(")\n{\n")
michael@0 433 fd.write(" nsresult rv = %s::Init%s(aType, aCanBubble, aCancelable" % (basename, ("%s" % iface.base[6:])))
michael@0 434 for a in baseattributes:
michael@0 435 fd.write(", a%s" % firstCap(a.name))
michael@0 436 fd.write(");\n");
michael@0 437 fd.write(" NS_ENSURE_SUCCESS(rv, rv);\n")
michael@0 438 for a in attributes:
michael@0 439 if a.realtype.nativeType("in").count("nsAString"):
michael@0 440 fd.write(" if (!m%s.Assign(a%s, fallible_t())) {\n" % (firstCap(a.name), firstCap(a.name)))
michael@0 441 fd.write(" return NS_ERROR_OUT_OF_MEMORY;\n")
michael@0 442 fd.write(" }\n")
michael@0 443 else:
michael@0 444 fd.write(" m%s = a%s;\n" % (firstCap(a.name), firstCap(a.name)))
michael@0 445 fd.write(" return NS_OK;\n")
michael@0 446 fd.write("}\n\n")
michael@0 447
michael@0 448 fd.write("void\n")
michael@0 449 fd.write("%s::Init%s(" % (classname, eventname))
michael@0 450 if hasVariant:
michael@0 451 fd.write("JSContext* aCx, ")
michael@0 452 fd.write("const nsAString& aType, bool aCanBubble, bool aCancelable")
michael@0 453 for a in allattributes:
michael@0 454 writeNativeAttributeParams(fd, a, conf)
michael@0 455 fd.write(", ErrorResult& aRv")
michael@0 456 fd.write(")\n")
michael@0 457 fd.write("{\n");
michael@0 458 for a in allattributes:
michael@0 459 if a.type == "nsIVariant":
michael@0 460 fd.write(" nsCOMPtr<nsIVariant> %s = dont_AddRef(XPCVariant::newVariant(aCx, a%s));\n" % (a.name, firstCap(a.name)))
michael@0 461 fd.write(" if (!%s) {\n" % a.name)
michael@0 462 fd.write(" aRv.Throw(NS_ERROR_FAILURE);\n")
michael@0 463 fd.write(" return;\n")
michael@0 464 fd.write(" }\n")
michael@0 465 elif a.realtype.nativeType('in').endswith('*'):
michael@0 466 xpidl_t = a.realtype.nativeType('in').strip('* ')
michael@0 467 native_t = xpidl_to_native(xpidl_t, conf)
michael@0 468 if xpidl_t != native_t:
michael@0 469 fd.write(" nsCOMPtr<%s> %s = do_QueryInterface(static_cast<%s*>(a%s));\n" % (xpidl_t, a.name, xpidl_to_canonical(xpidl_t, conf), firstCap(a.name)))
michael@0 470 fd.write(" aRv = Init%s(" % classname);
michael@0 471 fd.write("aType, aCanBubble, aCancelable")
michael@0 472 for a in allattributes:
michael@0 473 if a.realtype.nativeType('in').endswith('*'):
michael@0 474 xpidl_t = a.realtype.nativeType('in').strip('* ')
michael@0 475 native_t = xpidl_to_native(xpidl_t, conf)
michael@0 476 if xpidl_t != native_t or a.type == "nsIVariant":
michael@0 477 fd.write(", %s" % a.name)
michael@0 478 continue
michael@0 479 fd.write(", a%s" % firstCap(a.name))
michael@0 480 fd.write(");\n}\n\n");
michael@0 481
michael@0 482 for a in attributes:
michael@0 483 writeAttributeGetter(fd, classname, a)
michael@0 484
michael@0 485 fd.write("} // namespace dom\n")
michael@0 486 fd.write("} // namespace mozilla\n\n")
michael@0 487
michael@0 488 fd.write("nsresult\n")
michael@0 489 fd.write("NS_NewDOM%s(nsIDOMEvent** aInstance, " % eventname)
michael@0 490 fd.write("mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext = nullptr, mozilla::WidgetEvent* aEvent = nullptr)\n")
michael@0 491 fd.write("{\n")
michael@0 492 fd.write(" mozilla::dom::%s* it = new mozilla::dom::%s(aOwner, aPresContext, aEvent);\n" % (classname, classname))
michael@0 493 fd.write(" NS_ADDREF(it);\n")
michael@0 494 fd.write(" *aInstance = static_cast<mozilla::dom::Event*>(it);\n")
michael@0 495 fd.write(" return NS_OK;\n");
michael@0 496 fd.write("}\n\n")
michael@0 497
michael@0 498 def toWebIDLType(attribute, inType=False, onlyInterface=False):
michael@0 499 if attribute.type == "nsIVariant":
michael@0 500 return "any";
michael@0 501 if attribute.type == "nsISupports":
michael@0 502 return "%s%s" % (attribute.type, "" if onlyInterface else "?")
michael@0 503 if attribute.type.count("nsIDOM"):
michael@0 504 return "%s%s" % (attribute.type[6:], "" if onlyInterface else "?")
michael@0 505 if attribute.type.count("nsI"):
michael@0 506 return "%s%s" % (attribute.type[3:], "" if onlyInterface else "?")
michael@0 507 if attribute.realtype.nativeType('in').endswith('*') or attribute.realtype.nativeType('in').count("nsAString"):
michael@0 508 return "%s%s" % (attribute.type, "" if onlyInterface else "?")
michael@0 509 return attribute.type
michael@0 510
michael@0 511 def write_webidl(eventname, iface, fd, conf, idl):
michael@0 512 basename = ("%s" % iface.base[6:])
michael@0 513 attributes = []
michael@0 514 ccattributes = []
michael@0 515 consts = []
michael@0 516 hasInit = False
michael@0 517 initMethod = "init%s" % eventname;
michael@0 518 for member in iface.members:
michael@0 519 if isinstance(member, xpidl.Attribute):
michael@0 520 attributes.append(member)
michael@0 521 if (member.realtype.nativeType('in').endswith('*')):
michael@0 522 ccattributes.append(member);
michael@0 523 elif isinstance(member, xpidl.Method) and member.name == initMethod:
michael@0 524 if not member.noscript and not member.notxpcom:
michael@0 525 hasInit = True
michael@0 526 elif isinstance(member, xpidl.ConstMember):
michael@0 527 consts.append(member);
michael@0 528 else:
michael@0 529 raise BaseException("Unsupported idl member %s::%s" % (eventname, member.name))
michael@0 530
michael@0 531 baseinterfaces = []
michael@0 532 baseiface = iface.idl.getName(iface.base, iface.location)
michael@0 533 while baseiface.name != "nsIDOMEvent":
michael@0 534 baseinterfaces.append(baseiface)
michael@0 535 baseiface = baseiface.idl.getName(baseiface.base, baseiface.location)
michael@0 536 baseinterfaces.reverse()
michael@0 537
michael@0 538 allattributes = []
michael@0 539 for baseiface in baseinterfaces:
michael@0 540 for member in baseiface.members:
michael@0 541 if isinstance(member, xpidl.Attribute):
michael@0 542 allattributes.append(member)
michael@0 543 allattributes.extend(attributes)
michael@0 544
michael@0 545 fd.write(
michael@0 546 """/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 547 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 548 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 549 * You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 550 */
michael@0 551 """)
michael@0 552
michael@0 553 neededInterfaces = []
michael@0 554 for a in attributes:
michael@0 555 if a.realtype.nativeType('in').endswith('*'):
michael@0 556 nativeType = a.realtype.nativeType('in').strip('* ')
michael@0 557 mappingForWebIDL = False
michael@0 558 for xp in conf.xpidl_to_native:
michael@0 559 if xp[0] == nativeType:
michael@0 560 mappingForWebIDL = True
michael@0 561 break;
michael@0 562 if not mappingForWebIDL:
michael@0 563 webidlType = toWebIDLType(a, False, True)
michael@0 564 if (not webidlType in neededInterfaces and webidlType != "any"):
michael@0 565 neededInterfaces.append(webidlType);
michael@0 566
michael@0 567 for i in neededInterfaces:
michael@0 568 fd.write("interface %s;\n" % i)
michael@0 569
michael@0 570 fd.write("\n");
michael@0 571 fd.write("[Constructor(DOMString type, optional %sInit eventInitDict), HeaderFile=\"GeneratedEventClasses.h\"]\n" % eventname);
michael@0 572 fd.write("interface %s : %s\n" % (eventname, basename))
michael@0 573 fd.write("{\n")
michael@0 574
michael@0 575 for c in consts:
michael@0 576 fd.write(" const %s %s = %s;\n" % (c.type, c.name, c.getValue()))
michael@0 577 if len(consts):
michael@0 578 fd.write("\n")
michael@0 579
michael@0 580 for a in attributes:
michael@0 581 if a.realtype.nativeType('in').count("nsIVariant"):
michael@0 582 fd.write(" [Throws]\n")
michael@0 583 fd.write(" readonly attribute %s %s;\n" % (toWebIDLType(a), a.name))
michael@0 584 elif a.realtype.nativeType('in').endswith('*') or a.realtype.nativeType('in').count("nsAString"):
michael@0 585 fd.write(" readonly attribute %s %s;\n" % (toWebIDLType(a), a.name))
michael@0 586 else:
michael@0 587 fd.write(" readonly attribute %s %s;\n" % (a.type, a.name))
michael@0 588 if hasInit:
michael@0 589 fd.write("\n [Throws]\n")
michael@0 590 m = " void %s(" % initMethod
michael@0 591 fd.write(m)
michael@0 592 indent = "".join(" " for i in range(len(m)))
michael@0 593 indent = ",\n%s" % indent
michael@0 594 fd.write("DOMString type")
michael@0 595 fd.write(indent);
michael@0 596 fd.write("boolean canBubble")
michael@0 597 fd.write(indent);
michael@0 598 fd.write("boolean cancelable")
michael@0 599 for a in baseattributes + attributes:
michael@0 600 fd.write(indent);
michael@0 601 fd.write("%s %s" % (toWebIDLType(a, True), a.name))
michael@0 602 fd.write(");\n");
michael@0 603 fd.write("};\n\n")
michael@0 604
michael@0 605 dname = "%sInit" % eventname
michael@0 606 for p in idl.productions:
michael@0 607 if p.kind == "dictionary" and p.name == dname:
michael@0 608 fd.write("dictionary %s : %sInit\n" % (dname, basename))
michael@0 609 fd.write("{\n")
michael@0 610 # We want to keep the same ordering what interface has.
michael@0 611 for ifaceattribute in attributes:
michael@0 612 for member in p.members:
michael@0 613 if member.name == ifaceattribute.name:
michael@0 614 a = member
michael@0 615 if a.realtype.nativeType('in').endswith('*'):
michael@0 616 fd.write(" %s %s = null;\n" % (toWebIDLType(a, True), a.name))
michael@0 617 elif a.realtype.nativeType('in').count("nsAString"):
michael@0 618 if a.defvalue is None:
michael@0 619 if a.nullable:
michael@0 620 fd.write(" %s? %s = null;\n" % (a.type, a.name))
michael@0 621 else:
michael@0 622 fd.write(" %s %s = \"\";\n" % (a.type, a.name))
michael@0 623 else:
michael@0 624 if a.nullable:
michael@0 625 fd.write(" %s? %s = \"%s\";\n" % (a.type, a.name, a.defvalue))
michael@0 626 else:
michael@0 627 fd.write(" %s %s = \"%s\";\n" % (a.type, a.name, a.defvalue))
michael@0 628 else:
michael@0 629 if a.defvalue is None:
michael@0 630 if a.type == "boolean":
michael@0 631 fd.write(" %s %s = false;\n" % (a.type, a.name))
michael@0 632 else:
michael@0 633 fd.write(" %s %s = 0;\n" % (a.type, a.name))
michael@0 634 # Infinity is not supported by all the types, but
michael@0 635 # WebIDL parser will then complain about the wrong values.
michael@0 636 elif a.defvalue == "Infinity":
michael@0 637 fd.write(" unrestricted %s %s = Infinity;\n" % (a.type, a.name))
michael@0 638 elif a.defvalue == "-Infinity":
michael@0 639 fd.write(" unrestricted %s %s = -Infinity;\n" % (a.type, a.name))
michael@0 640 else:
michael@0 641 fd.write(" %s %s = %s;\n" % (a.type, a.name, a.defvalue))
michael@0 642 continue
michael@0 643 fd.write("};\n")
michael@0 644 return
michael@0 645
michael@0 646 # There is no dictionary defined in the .idl file. Generate one based on
michael@0 647 # the interface.
michael@0 648 fd.write("dictionary %s : %sInit\n" % (dname, basename))
michael@0 649 fd.write("{\n")
michael@0 650 for a in attributes:
michael@0 651 if a.realtype.nativeType('in').endswith('*'):
michael@0 652 fd.write(" %s %s = null;\n" % (toWebIDLType(a, True), a.name))
michael@0 653 elif a.realtype.nativeType('in').count("nsAString"):
michael@0 654 fd.write(" %s? %s = \"\";\n" % (a.type, a.name))
michael@0 655 elif a.type == "boolean":
michael@0 656 fd.write(" %s %s = false;\n" % (a.type, a.name))
michael@0 657 else:
michael@0 658 fd.write(" %s %s = 0;\n" % (a.type, a.name))
michael@0 659 fd.write("};\n")
michael@0 660
michael@0 661 def print_webidl_file(idl, fd, conf, eventname):
michael@0 662 for p in idl.productions:
michael@0 663 if p.kind == 'interface':
michael@0 664 write_webidl(eventname, p, fd, conf, idl)
michael@0 665
michael@0 666 def xpidl_to_native(xpidl, conf):
michael@0 667 for x in conf.xpidl_to_native:
michael@0 668 if x[0] == xpidl:
michael@0 669 return x[1]
michael@0 670 return xpidl
michael@0 671
michael@0 672 def xpidl_to_canonical(xpidl, conf):
michael@0 673 for x in conf.xpidl_to_native:
michael@0 674 if x[0] == xpidl:
michael@0 675 return x[2]
michael@0 676 return xpidl
michael@0 677
michael@0 678 def native_to_xpidl(native, conf):
michael@0 679 for x in conf.xpidl_to_native:
michael@0 680 if x[1] == native:
michael@0 681 return x[0]
michael@0 682 return native
michael@0 683
michael@0 684 def print_webidl_files(webidlDir, conf):
michael@0 685 for e in conf.simple_events:
michael@0 686 idl = loadEventIDL(p, options.incdirs, e)
michael@0 687 webidl = "%s/%s.webidl" % (webidlDir, e)
michael@0 688 if not os.path.exists(webidl):
michael@0 689 fd = open(webidl, 'w')
michael@0 690 print_webidl_file(idl, fd, conf, e)
michael@0 691 fd.close();
michael@0 692
michael@0 693 if __name__ == '__main__':
michael@0 694 from optparse import OptionParser
michael@0 695 o = OptionParser(usage="usage: %prog [options] configfile")
michael@0 696 o.add_option('-I', action='append', dest='incdirs', default=['.'],
michael@0 697 help="Directory to search for imported files")
michael@0 698 o.add_option('-o', "--stub-output",
michael@0 699 type='string', dest='stub_output', default=None,
michael@0 700 help="Quick stub C++ source output file", metavar="FILE")
michael@0 701 o.add_option('--header-output', type='string', default=None,
michael@0 702 help="Quick stub header output file", metavar="FILE")
michael@0 703 o.add_option('--makedepend-output', type='string', default=None,
michael@0 704 help="gnumake dependencies output file", metavar="FILE")
michael@0 705 o.add_option('--cachedir', dest='cachedir', default=None,
michael@0 706 help="Directory in which to cache lex/parse tables.")
michael@0 707 o.add_option('--class-declarations', type='string', default=None,
michael@0 708 help="Class declarations", metavar="FILE")
michael@0 709 o.add_option('--webidltarget', dest='webidltarget', default=None,
michael@0 710 help="Directory in which to store generated WebIDL files.")
michael@0 711 (options, filenames) = o.parse_args()
michael@0 712 if len(filenames) != 1:
michael@0 713 o.error("Exactly one config filename is needed.")
michael@0 714 filename = filenames[0]
michael@0 715
michael@0 716 if options.cachedir is not None:
michael@0 717 if not os.path.isdir(options.cachedir):
michael@0 718 os.mkdir(options.cachedir)
michael@0 719 sys.path.append(options.cachedir)
michael@0 720
michael@0 721 # Instantiate the parser.
michael@0 722 p = xpidl.IDLParser(outputdir=options.cachedir)
michael@0 723
michael@0 724 conf = readConfigFile(filename)
michael@0 725
michael@0 726 if options.header_output is not None:
michael@0 727 outfd = open(options.header_output, 'w')
michael@0 728 print_header_file(outfd, conf)
michael@0 729 outfd.close()
michael@0 730 if options.class_declarations is not None:
michael@0 731 outfd = open(options.class_declarations, 'w')
michael@0 732 print_classes_file(outfd, conf)
michael@0 733 outfd.close()
michael@0 734 if options.stub_output is not None:
michael@0 735 makeutils.targets.append(options.stub_output)
michael@0 736 outfd = open(options.stub_output, 'w')
michael@0 737 print_cpp_file(outfd, conf)
michael@0 738 outfd.close()
michael@0 739 if options.makedepend_output is not None:
michael@0 740 makeutils.writeMakeDependOutput(options.makedepend_output)
michael@0 741
michael@0 742 if options.webidltarget is not None:
michael@0 743 print_webidl_files(options.webidltarget, conf)
michael@0 744

mercurial