2013-01-19 19:38:01 +04:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
|
|
|
# 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/.
|
|
|
|
|
2019-07-02 18:47:34 +03:00
|
|
|
from __future__ import absolute_import
|
2015-11-17 03:51:51 +03:00
|
|
|
import sys
|
|
|
|
import os
|
2014-12-07 02:47:06 +03:00
|
|
|
|
2015-11-17 03:51:51 +03:00
|
|
|
import buildconfig
|
|
|
|
import mozpack.path as mozpath
|
|
|
|
|
2020-05-01 00:49:10 +03:00
|
|
|
# The xpidl parser cache directory is not incorporated in the in-tree virtualenv.
|
2016-09-19 20:42:44 +03:00
|
|
|
xpidl_cachedir = mozpath.join(buildconfig.topobjdir, 'xpcom', 'idl-parser',
|
|
|
|
'xpidl')
|
2020-05-01 00:49:10 +03:00
|
|
|
sys.path.append(xpidl_cachedir)
|
|
|
|
from xpidl import xpidl
|
2015-11-17 03:51:51 +03:00
|
|
|
|
2018-04-07 01:20:49 +03:00
|
|
|
# Load the webidl configuration file.
|
|
|
|
glbl = {}
|
2019-09-24 17:44:01 +03:00
|
|
|
exec(open(mozpath.join(buildconfig.topsrcdir, 'dom', 'bindings', 'Bindings.conf')).read(), glbl)
|
2018-04-07 01:20:49 +03:00
|
|
|
webidlconfig = glbl['DOMInterfaces']
|
|
|
|
|
2015-11-17 03:51:51 +03:00
|
|
|
# Instantiate the parser.
|
|
|
|
p = xpidl.IDLParser()
|
2013-01-19 19:38:01 +04:00
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
def findIDL(includePath, interfaceFileName):
|
|
|
|
for d in includePath:
|
2015-11-17 03:51:51 +03:00
|
|
|
path = mozpath.join(d, interfaceFileName)
|
2013-01-19 19:38:01 +04:00
|
|
|
if os.path.exists(path):
|
|
|
|
return path
|
|
|
|
raise BaseException("No IDL file found for interface %s "
|
|
|
|
"in include path %r"
|
|
|
|
% (interfaceFileName, includePath))
|
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
def loadEventIDL(parser, includePath, eventname):
|
|
|
|
eventidl = ("nsIAccessible%s.idl" % eventname)
|
|
|
|
idlFile = findIDL(includePath, eventidl)
|
|
|
|
idl = p.parse(open(idlFile).read(), idlFile)
|
2018-04-07 01:20:49 +03:00
|
|
|
idl.resolve(includePath, p, webidlconfig)
|
2014-12-07 02:47:06 +03:00
|
|
|
return idl, idlFile
|
2013-01-19 19:38:01 +04:00
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
class Configuration:
|
|
|
|
def __init__(self, filename):
|
|
|
|
config = {}
|
2019-09-24 17:44:01 +03:00
|
|
|
exec(open(filename).read(), config)
|
2013-01-19 19:38:01 +04:00
|
|
|
self.simple_events = config.get('simple_events', [])
|
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
def firstCap(str):
|
|
|
|
return str[0].upper() + str[1:]
|
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
def writeAttributeParams(a):
|
|
|
|
return ("%s a%s" % (a.realtype.nativeType('in'), firstCap(a.name)))
|
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2015-11-17 03:51:51 +03:00
|
|
|
def print_header_file(fd, conf, incdirs):
|
2014-12-07 02:47:06 +03:00
|
|
|
idl_paths = set()
|
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n")
|
|
|
|
fd.write("#ifndef _mozilla_a11y_generated_AccEvents_h_\n"
|
|
|
|
"#define _mozilla_a11y_generated_AccEvents_h_\n\n")
|
|
|
|
fd.write("#include \"nscore.h\"\n")
|
|
|
|
fd.write("#include \"nsCOMPtr.h\"\n")
|
|
|
|
fd.write("#include \"nsCycleCollectionParticipant.h\"\n")
|
|
|
|
fd.write("#include \"nsString.h\"\n")
|
|
|
|
for e in conf.simple_events:
|
|
|
|
fd.write("#include \"nsIAccessible%s.h\"\n" % e)
|
|
|
|
for e in conf.simple_events:
|
2015-11-17 03:51:51 +03:00
|
|
|
idl, idl_path = loadEventIDL(p, incdirs, e)
|
2014-12-07 02:47:06 +03:00
|
|
|
idl_paths.add(idl_path)
|
2013-01-19 19:38:01 +04:00
|
|
|
for iface in filter(lambda p: p.kind == "interface", idl.productions):
|
|
|
|
classname = ("xpcAcc%s" % e)
|
|
|
|
baseinterfaces = interfaces(iface)
|
|
|
|
|
2015-03-21 19:28:46 +03:00
|
|
|
fd.write("\nclass %s final : public %s\n" % (classname, iface.name))
|
2013-01-19 19:38:01 +04:00
|
|
|
fd.write("{\n")
|
|
|
|
fd.write("public:\n")
|
|
|
|
|
|
|
|
attributes = allAttributes(iface)
|
|
|
|
args = map(writeAttributeParams, attributes)
|
|
|
|
fd.write(" %s(%s) :\n" % (classname, ", ".join(args)))
|
|
|
|
|
|
|
|
initializers = []
|
|
|
|
for a in attributes:
|
|
|
|
initializers.append("m%s(a%s)" % (firstCap(a.name), firstCap(a.name)))
|
2014-07-28 21:15:58 +04:00
|
|
|
fd.write(" %s\n {}\n\n" % ", ".join(initializers))
|
2013-01-19 19:38:01 +04:00
|
|
|
fd.write(" NS_DECL_CYCLE_COLLECTING_ISUPPORTS\n")
|
|
|
|
fd.write(" NS_DECL_CYCLE_COLLECTION_CLASS(%s)\n" % (classname))
|
|
|
|
|
|
|
|
for iface in filter(lambda i: i.name != "nsISupports", baseinterfaces):
|
|
|
|
fd.write(" NS_DECL_%s\n" % iface.name.upper())
|
|
|
|
|
2014-07-28 21:15:58 +04:00
|
|
|
fd.write("\nprivate:\n")
|
|
|
|
fd.write(" ~%s() {}\n\n" % classname)
|
2013-01-19 19:38:01 +04:00
|
|
|
for a in attributes:
|
|
|
|
fd.write(" %s\n" % attributeVariableTypeAndName(a))
|
|
|
|
fd.write("};\n\n")
|
|
|
|
|
|
|
|
fd.write("#endif\n")
|
|
|
|
|
2014-12-07 02:47:06 +03:00
|
|
|
return idl_paths
|
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
def interfaceAttributeTypes(idl):
|
|
|
|
ifaces = filter(lambda p: p.kind == "interface", idl.productions)
|
|
|
|
attributes = []
|
|
|
|
for i in ifaces:
|
|
|
|
ifaceAttributes = allAttributes(i)
|
|
|
|
attributes.extend(ifaceAttributes)
|
|
|
|
ifaceAttrs = filter(lambda a: a.realtype.nativeType("in").endswith("*"), attributes)
|
|
|
|
return map(lambda a: a.realtype.nativeType("in").strip(" *"), ifaceAttrs)
|
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
def print_cpp(idl, fd, conf, eventname):
|
|
|
|
for p in idl.productions:
|
|
|
|
if p.kind == 'interface':
|
|
|
|
write_cpp(eventname, p, fd)
|
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2015-11-17 03:51:51 +03:00
|
|
|
def print_cpp_file(fd, conf, incdirs):
|
2014-12-07 02:47:06 +03:00
|
|
|
idl_paths = set()
|
2013-01-19 19:38:01 +04:00
|
|
|
fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n")
|
|
|
|
fd.write('#include "xpcAccEvents.h"\n')
|
|
|
|
|
|
|
|
includes = []
|
|
|
|
for e in conf.simple_events:
|
2018-05-26 09:13:28 +03:00
|
|
|
if e not in includes:
|
2013-01-19 19:38:01 +04:00
|
|
|
includes.append(("nsIAccessible%s" % e))
|
|
|
|
|
|
|
|
types = []
|
|
|
|
for e in conf.simple_events:
|
2015-11-17 03:51:51 +03:00
|
|
|
idl, idl_path = loadEventIDL(p, incdirs, e)
|
2014-12-07 02:47:06 +03:00
|
|
|
idl_paths.add(idl_path)
|
2013-01-19 19:38:01 +04:00
|
|
|
types.extend(interfaceAttributeTypes(idl))
|
|
|
|
|
|
|
|
for c in types:
|
|
|
|
fd.write("#include \"%s.h\"\n" % c)
|
|
|
|
|
|
|
|
fd.write("\n")
|
|
|
|
for e in conf.simple_events:
|
2015-11-17 03:51:51 +03:00
|
|
|
idl, idl_path = loadEventIDL(p, incdirs, e)
|
2014-12-07 02:47:06 +03:00
|
|
|
idl_paths.add(idl_path)
|
|
|
|
print_cpp(idl, fd, conf, e)
|
|
|
|
|
|
|
|
return idl_paths
|
2013-01-19 19:38:01 +04:00
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
def attributeVariableTypeAndName(a):
|
|
|
|
if a.realtype.nativeType('in').endswith('*'):
|
|
|
|
l = ["nsCOMPtr<%s> m%s;" % (a.realtype.nativeType('in').strip('* '),
|
2018-05-26 09:13:03 +03:00
|
|
|
firstCap(a.name))]
|
2013-01-19 19:38:01 +04:00
|
|
|
elif a.realtype.nativeType('in').count("nsAString"):
|
|
|
|
l = ["nsString m%s;" % firstCap(a.name)]
|
|
|
|
elif a.realtype.nativeType('in').count("nsACString"):
|
|
|
|
l = ["nsCString m%s;" % firstCap(a.name)]
|
|
|
|
else:
|
|
|
|
l = ["%sm%s;" % (a.realtype.nativeType('in'),
|
2018-05-26 09:13:03 +03:00
|
|
|
firstCap(a.name))]
|
2013-01-19 19:38:01 +04:00
|
|
|
return ", ".join(l)
|
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
def writeAttributeGetter(fd, classname, a):
|
|
|
|
fd.write("NS_IMETHODIMP\n")
|
|
|
|
fd.write("%s::Get%s(" % (classname, firstCap(a.name)))
|
|
|
|
if a.realtype.nativeType('in').endswith('*'):
|
|
|
|
fd.write("%s** a%s" % (a.realtype.nativeType('in').strip('* '), firstCap(a.name)))
|
|
|
|
elif a.realtype.nativeType('in').count("nsAString"):
|
|
|
|
fd.write("nsAString& a%s" % firstCap(a.name))
|
|
|
|
elif a.realtype.nativeType('in').count("nsACString"):
|
|
|
|
fd.write("nsACString& a%s" % firstCap(a.name))
|
|
|
|
else:
|
|
|
|
fd.write("%s*a%s" % (a.realtype.nativeType('in'), firstCap(a.name)))
|
2018-05-26 09:13:03 +03:00
|
|
|
fd.write(")\n")
|
|
|
|
fd.write("{\n")
|
2013-01-19 19:38:01 +04:00
|
|
|
if a.realtype.nativeType('in').endswith('*'):
|
|
|
|
fd.write(" NS_IF_ADDREF(*a%s = m%s);\n" % (firstCap(a.name), firstCap(a.name)))
|
|
|
|
elif a.realtype.nativeType('in').count("nsAString"):
|
|
|
|
fd.write(" a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
|
|
|
|
elif a.realtype.nativeType('in').count("nsACString"):
|
|
|
|
fd.write(" a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
|
|
|
|
else:
|
|
|
|
fd.write(" *a%s = m%s;\n" % (firstCap(a.name), firstCap(a.name)))
|
2018-05-26 09:13:03 +03:00
|
|
|
fd.write(" return NS_OK;\n")
|
|
|
|
fd.write("}\n\n")
|
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
|
|
|
|
def interfaces(iface):
|
|
|
|
interfaces = []
|
|
|
|
while iface.base:
|
|
|
|
interfaces.append(iface)
|
2018-07-11 04:15:16 +03:00
|
|
|
iface = iface.idl.getName(xpidl.TypeId(iface.base), iface.location)
|
2013-01-19 19:38:01 +04:00
|
|
|
interfaces.append(iface)
|
|
|
|
interfaces.reverse()
|
|
|
|
return interfaces
|
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
def allAttributes(iface):
|
|
|
|
attributes = []
|
|
|
|
for i in interfaces(iface):
|
|
|
|
attrs = filter(lambda m: isinstance(m, xpidl.Attribute), i.members)
|
|
|
|
attributes.extend(attrs)
|
|
|
|
|
|
|
|
return attributes
|
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2013-01-19 19:38:01 +04:00
|
|
|
def write_cpp(eventname, iface, fd):
|
|
|
|
classname = "xpcAcc%s" % eventname
|
|
|
|
attributes = allAttributes(iface)
|
|
|
|
ccattributes = filter(lambda m: m.realtype.nativeType('in').endswith('*'), attributes)
|
2014-04-25 20:49:00 +04:00
|
|
|
fd.write("NS_IMPL_CYCLE_COLLECTION(%s" % classname)
|
2013-01-19 19:38:01 +04:00
|
|
|
for c in ccattributes:
|
|
|
|
fd.write(", m%s" % firstCap(c.name))
|
2018-05-26 09:13:03 +03:00
|
|
|
fd.write(")\n\n")
|
2013-01-19 19:38:01 +04:00
|
|
|
|
|
|
|
fd.write("NS_IMPL_CYCLE_COLLECTING_ADDREF(%s)\n" % classname)
|
|
|
|
fd.write("NS_IMPL_CYCLE_COLLECTING_RELEASE(%s)\n\n" % classname)
|
|
|
|
|
|
|
|
fd.write("NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(%s)\n" % classname)
|
|
|
|
for baseiface in interfaces(iface):
|
|
|
|
fd.write(" NS_INTERFACE_MAP_ENTRY(%s)\n" % baseiface.name)
|
|
|
|
fd.write("NS_INTERFACE_MAP_END\n\n")
|
|
|
|
|
|
|
|
for a in attributes:
|
|
|
|
writeAttributeGetter(fd, classname, a)
|
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2015-12-08 20:58:40 +03:00
|
|
|
def get_conf(conf_file):
|
2015-11-17 03:51:51 +03:00
|
|
|
conf = Configuration(conf_file)
|
2015-12-08 20:58:40 +03:00
|
|
|
inc_dir = [
|
|
|
|
mozpath.join(buildconfig.topsrcdir, 'accessible', 'interfaces'),
|
|
|
|
mozpath.join(buildconfig.topsrcdir, 'xpcom', 'base'),
|
|
|
|
]
|
|
|
|
return conf, inc_dir
|
2015-11-17 03:51:51 +03:00
|
|
|
|
2018-05-26 09:13:03 +03:00
|
|
|
|
2016-09-18 22:30:32 +03:00
|
|
|
def gen_files(fd, conf_file, xpidllex, xpidlyacc):
|
|
|
|
deps = set()
|
2015-12-08 20:58:40 +03:00
|
|
|
conf, inc_dir = get_conf(conf_file)
|
2016-09-18 22:30:32 +03:00
|
|
|
deps.update(print_header_file(fd, conf, inc_dir))
|
2016-11-22 11:05:49 +03:00
|
|
|
with open(os.path.join(os.path.dirname(fd.name), 'xpcAccEvents.cpp'), 'w') as cpp_fd:
|
2016-09-18 22:30:32 +03:00
|
|
|
deps.update(print_cpp_file(cpp_fd, conf, inc_dir))
|
|
|
|
return deps
|