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.

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

mercurial