| Index: mojo/public/bindings/generators/mojom_cpp_generator.py
|
| diff --git a/mojo/public/bindings/generators/mojom_cpp_generator.py b/mojo/public/bindings/generators/mojom_cpp_generator.py
|
| index a86341932343b20faa8dcc127e4a125e1f3ae657..e5c764e08ba645ee41a4a64b3709157fba898b65 100644
|
| --- a/mojo/public/bindings/generators/mojom_cpp_generator.py
|
| +++ b/mojo/public/bindings/generators/mojom_cpp_generator.py
|
| @@ -17,32 +17,11 @@ from string import Template
|
| # cpp = mojom_cpp_generator.CPPGenerator(module)
|
| # cpp.GenerateFiles("/tmp/g")
|
|
|
| -class DependentKinds(set):
|
| - """Set subclass to find the unique set of non POD types."""
|
| - def AddKind(self, kind):
|
| - if isinstance(kind, mojom.Struct):
|
| - self.add(kind)
|
| - if isinstance(kind, mojom.Array):
|
| - self.AddKind(kind.kind)
|
| -
|
| -
|
| -class Forwards(object):
|
| - """Helper class to maintain unique set of forward declarations."""
|
| - def __init__(self):
|
| - self.kinds = DependentKinds()
|
| -
|
| - def Add(self, kind):
|
| - self.kinds.AddKind(kind)
|
| -
|
| - def __repr__(self):
|
| - return '\n'.join(
|
| - sorted(map(lambda kind: "class %s;" % kind.name, self.kinds)))
|
| -
|
| -
|
| class Lines(object):
|
| """Helper class to maintain list of template expanded lines."""
|
| - def __init__(self, template):
|
| + def __init__(self, template, indent = None):
|
| self.template = template
|
| + self.indent = indent
|
| self.lines = []
|
|
|
| def Add(self, map = {}, **substitutions):
|
| @@ -53,6 +32,10 @@ class Lines(object):
|
| self.lines.append(self.template.substitute(map))
|
|
|
| def __repr__(self):
|
| + if self.indent is not None:
|
| + prefix = "".ljust(self.indent, ' ')
|
| + repr = '\n'.join(self.lines)
|
| + self.lines = map(lambda l: prefix + l, repr.splitlines())
|
| return '\n'.join(self.lines)
|
|
|
|
|
| @@ -103,8 +86,6 @@ class CPPGenerator(object):
|
| ptr_getter_template = \
|
| Template(" $TYPE $FIELD() const { return ${FIELD}_.ptr; }")
|
| pad_template = Template(" uint8_t _pad${COUNT}_[$PAD];")
|
| - name_template = \
|
| - Template("const uint32_t k${INTERFACE}_${METHOD}_Name = $NAME;")
|
| templates = {}
|
| HEADER_SIZE = 8
|
|
|
| @@ -220,9 +201,7 @@ class CPPGenerator(object):
|
| def GetHeaderFile(self, *components):
|
| components = map(lambda c: CamelToUnderscores(c), components)
|
| component_string = '_'.join(components)
|
| - return os.path.join(
|
| - self.header_dir,
|
| - "%s_%s.h" % (CamelToUnderscores(self.module.name), component_string))
|
| + return os.path.join(self.header_dir, "%s.h" % component_string)
|
|
|
| # Pass |output_dir| to emit files to disk. Omit |output_dir| to echo all files
|
| # to stdout.
|
| @@ -231,13 +210,10 @@ class CPPGenerator(object):
|
| self.header_dir = header_dir
|
| self.output_dir = output_dir
|
|
|
| - def WriteTemplateToFile(self, template_name, name, **substitutions):
|
| - template_name = CamelToUnderscores(template_name)
|
| - name = CamelToUnderscores(name)
|
| + def WriteTemplateToFile(self, template_name, **substitutions):
|
| template = self.GetTemplate(template_name)
|
| - filename = "%s_%s" % (CamelToUnderscores(self.module.name), template_name)
|
| - filename = filename.replace("interface", name)
|
| - filename = filename.replace("struct", name)
|
| + filename = \
|
| + template_name.replace("module", CamelToUnderscores(self.module.name))
|
| substitutions['YEAR'] = datetime.date.today().year
|
| substitutions['NAMESPACE'] = self.module.namespace
|
| if self.output_dir is None:
|
| @@ -250,8 +226,7 @@ class CPPGenerator(object):
|
| if self.output_dir is not None:
|
| file.close()
|
|
|
| - def GetStructDeclaration(self, name, ps):
|
| - params_template = self.GetTemplate("struct_declaration")
|
| + def GetStructDeclaration(self, name, ps, template, subs = {}):
|
| fields = []
|
| setters = []
|
| getters = []
|
| @@ -280,24 +255,23 @@ class CPPGenerator(object):
|
| size = offset + pad
|
| else:
|
| size = 0
|
| - return params_template.substitute(
|
| + subs.update(
|
| CLASS = name,
|
| SETTERS = '\n'.join(setters),
|
| GETTERS = '\n'.join(getters),
|
| FIELDS = '\n'.join(fields),
|
| SIZE = size + self.HEADER_SIZE)
|
| + return template.substitute(subs)
|
|
|
| - def GetStructImplementation(self, name, ps):
|
| - return self.GetTemplate("struct_implementation").substitute(
|
| - CLASS = name,
|
| - NUM_FIELDS = len(ps.packed_fields))
|
| -
|
| - def GetStructSerialization(self, class_name, param_name, ps):
|
| + def GetStructSerialization(
|
| + self, class_name, param_name, ps, template, indent = None):
|
| struct = ps.struct
|
| - encodes = Lines(self.struct_serialization_encode_template)
|
| - encode_handles = Lines(self.struct_serialization_encode_handle_template)
|
| - decodes = Lines(self.struct_serialization_decode_template)
|
| - decode_handles = Lines(self.struct_serialization_decode_handle_template)
|
| + encodes = Lines(self.struct_serialization_encode_template, indent)
|
| + encode_handles = \
|
| + Lines(self.struct_serialization_encode_handle_template, indent)
|
| + decodes = Lines(self.struct_serialization_decode_template, indent)
|
| + decode_handles = \
|
| + Lines(self.struct_serialization_decode_handle_template, indent)
|
| fields = self.GetSerializedFields(ps)
|
| handle_fields = self.GetHandleFields(ps)
|
| for field in fields:
|
| @@ -308,7 +282,7 @@ class CPPGenerator(object):
|
| substitutions = {'NAME': param_name, 'FIELD': field.name}
|
| encode_handles.Add(substitutions)
|
| decode_handles.Add(substitutions)
|
| - return self.GetTemplate("struct_serialization").substitute(
|
| + return template.substitute(
|
| CLASS = "%s::%s" % (self.module.namespace, class_name),
|
| NAME = param_name,
|
| ENCODES = encodes,
|
| @@ -316,174 +290,84 @@ class CPPGenerator(object):
|
| ENCODE_HANDLES = encode_handles,
|
| DECODE_HANDLES = decode_handles)
|
|
|
| - def GenerateStructHeader(self, ps):
|
| - struct = ps.struct
|
| - forwards = Forwards()
|
| - for field in struct.fields:
|
| - forwards.Add(field.kind)
|
| -
|
| - self.WriteTemplateToFile("struct.h", struct.name,
|
| - HEADER_GUARD = self.GetHeaderGuard(struct.name),
|
| - CLASS = struct.name,
|
| - FORWARDS = forwards,
|
| - DECLARATION = self.GetStructDeclaration(struct.name, ps))
|
| -
|
| - def GenerateStructSource(self, ps):
|
| - struct = ps.struct
|
| - header = self.GetHeaderFile(struct.name)
|
| - implementation = self.GetStructImplementation(struct.name, ps)
|
| - self.WriteTemplateToFile("struct.cc", struct.name,
|
| - CLASS = struct.name,
|
| - NUM_FIELDS = len(struct.fields),
|
| - HEADER = header,
|
| - IMPLEMENTATION = implementation)
|
| -
|
| - def GenerateStructSerializationHeader(self, ps):
|
| - struct = ps.struct
|
| - self.WriteTemplateToFile("struct_serialization.h", struct.name,
|
| - HEADER_GUARD = self.GetHeaderGuard(struct.name + "_SERIALIZATION"),
|
| - CLASS = struct.name,
|
| - NAME = CamelToUnderscores(struct.name),
|
| - FULL_CLASS = "%s::%s" % \
|
| - (self.module.namespace, struct.name))
|
| -
|
| - def GenerateStructSerializationSource(self, ps):
|
| - struct = ps.struct
|
| - serialization_header = self.GetHeaderFile(struct.name, "serialization")
|
| - param_name = CamelToUnderscores(struct.name)
|
| -
|
| - kinds = DependentKinds()
|
| - for field in struct.fields:
|
| - kinds.AddKind(field.kind)
|
| - headers = \
|
| - map(lambda kind: self.GetHeaderFile(kind.name, "serialization"), kinds)
|
| - headers.append(self.GetHeaderFile(struct.name))
|
| - includes = map(lambda header: "#include \"%s\"" % header, sorted(headers))
|
| -
|
| - class_header = self.GetHeaderFile(struct.name)
|
| - clones = Lines(self.struct_serialization_clone_template)
|
| - sizes = " return sizeof(*%s)" % param_name
|
| - fields = self.GetSerializedFields(ps)
|
| - for field in fields:
|
| - substitutions = {'NAME': param_name, 'FIELD': field.name}
|
| - sizes += \
|
| - self.struct_serialization_compute_template.substitute(substitutions)
|
| - clones.Add(substitutions)
|
| - sizes += ";"
|
| - serialization = self.GetStructSerialization(struct.name, param_name, ps)
|
| - self.WriteTemplateToFile("struct_serialization.cc", struct.name,
|
| - NAME = param_name,
|
| - CLASS = "%s::%s" % (self.module.namespace, struct.name),
|
| - SERIALIZATION_HEADER = serialization_header,
|
| - INCLUDES = '\n'.join(includes),
|
| - SIZES = sizes,
|
| - CLONES = clones,
|
| - SERIALIZATION = serialization)
|
| -
|
| - def GenerateInterfaceHeader(self, interface):
|
| + def GetStructClassDeclarations(self):
|
| + struct_decls = map(
|
| + lambda s: self.GetStructDeclaration(
|
| + s.name,
|
| + mojom_pack.PackedStruct(s),
|
| + self.GetTemplate("struct_declaration"),
|
| + {}),
|
| + self.module.structs)
|
| + return '\n'.join(struct_decls)
|
| +
|
| + def GetInterfaceClassDeclaration(self, interface, template, method_postfix):
|
| methods = []
|
| - forwards = Forwards()
|
| for method in interface.methods:
|
| params = []
|
| for param in method.parameters:
|
| - forwards.Add(param.kind)
|
| params.append("%s %s" % (self.GetConstType(param.kind), param.name))
|
| methods.append(
|
| - " virtual void %s(%s) = 0;" % (method.name, ", ".join(params)))
|
| -
|
| - self.WriteTemplateToFile("interface.h", interface.name,
|
| - HEADER_GUARD = self.GetHeaderGuard(interface.name),
|
| - CLASS = interface.name,
|
| - FORWARDS = forwards,
|
| - METHODS = '\n'.join(methods))
|
| -
|
| - def GenerateInterfaceStubHeader(self, interface):
|
| - header = self.GetHeaderFile(interface.name)
|
| - self.WriteTemplateToFile("interface_stub.h", interface.name,
|
| - HEADER_GUARD = self.GetHeaderGuard(interface.name + "_STUB"),
|
| - CLASS = interface.name,
|
| - HEADER = header)
|
| -
|
| - def GenerateInterfaceStubSource(self, interface):
|
| - stub_header = self.GetHeaderFile(interface.name, "stub")
|
| - serialization_header = self.GetHeaderFile(interface.name, "serialization")
|
| + " virtual void %s(%s) %s;" %
|
| + (method.name, ", ".join(params), method_postfix))
|
| + return template.substitute(
|
| + CLASS=interface.name,
|
| + METHODS='.\n'.join(methods))
|
| +
|
| + def GetInterfaceClassDeclarations(self):
|
| + template = self.GetTemplate("interface_declaration")
|
| + interface_decls = \
|
| + map(lambda i:
|
| + self.GetInterfaceClassDeclaration(i, template, " = 0"),
|
| + self.module.interfaces)
|
| + return '\n'.join(interface_decls)
|
| +
|
| + def GetInterfaceProxyDeclarations(self):
|
| + template = self.GetTemplate("interface_proxy_declaration")
|
| + interface_decls = \
|
| + map(lambda i:
|
| + self.GetInterfaceClassDeclaration(i, template, "MOJO_OVERRIDE"),
|
| + self.module.interfaces)
|
| + return '\n'.join(interface_decls)
|
| +
|
| + def GetInterfaceStubDeclarations(self):
|
| + template = self.GetTemplate("interface_stub_declaration")
|
| + interface_decls = \
|
| + map(lambda i: template.substitute(CLASS=i.name), self.module.interfaces)
|
| + return '\n'.join(interface_decls)
|
| +
|
| + def GenerateModuleHeader(self):
|
| + self.WriteTemplateToFile("module.h",
|
| + HEADER_GUARD = self.GetHeaderGuard(self.module.name),
|
| + STRUCT_CLASS_DECLARARTIONS = self.GetStructClassDeclarations(),
|
| + INTERFACE_CLASS_DECLARATIONS = self.GetInterfaceClassDeclarations(),
|
| + INTERFACE_PROXY_DECLARATIONS = self.GetInterfaceProxyDeclarations(),
|
| + INTERFACE_STUB_DECLARATIONS = self.GetInterfaceStubDeclarations())
|
| +
|
| + def GetParamsDefinition(self, interface, method, next_id):
|
| + struct = GetStructFromMethod(interface, method)
|
| + method_name = "k%s_%s_Name" % (interface.name, method.name)
|
| + if method.ordinal is not None:
|
| + next_id = method.ordinal
|
| + params_def = self.GetStructDeclaration(
|
| + struct.name,
|
| + mojom_pack.PackedStruct(struct),
|
| + self.GetTemplate("params_definition"),
|
| + {'METHOD_NAME': method_name, 'METHOD_ID': next_id})
|
| + return params_def, next_id + 1
|
| +
|
| + def GetStructDefinitions(self):
|
| + template = self.GetTemplate("struct_definition")
|
| + return '\n'.join(map(
|
| + lambda s: template.substitute(
|
| + CLASS = s.name, NUM_FIELDS = len(s.fields)),
|
| + self.module.structs));
|
| +
|
| + def GetInterfaceDefinition(self, interface):
|
| cases = []
|
| - for method in interface.methods:
|
| - cases.append(self.GetCaseLine(interface, method))
|
| - self.WriteTemplateToFile("interface_stub.cc", interface.name,
|
| - CLASS = interface.name,
|
| - CASES = '\n'.join(cases),
|
| - STUB_HEADER = stub_header,
|
| - SERIALIZATION_HEADER = serialization_header)
|
| -
|
| - def GenerateInterfaceSerializationHeader(self, interface):
|
| - kinds = DependentKinds()
|
| - for method in interface.methods:
|
| - for param in method.parameters:
|
| - kinds.AddKind(param.kind)
|
| - headers = \
|
| - map(lambda kind: self.GetHeaderFile(kind.name, "serialization"), kinds)
|
| - headers.append(self.GetHeaderFile(interface.name))
|
| - headers.append("mojo/public/bindings/lib/bindings_serialization.h")
|
| - includes = map(lambda header: "#include \"%s\"" % header, sorted(headers))
|
| -
|
| - names = []
|
| - name = 1
|
| - param_classes = []
|
| - param_templates = []
|
| - template_declaration = self.GetTemplate("template_declaration")
|
| - for method in interface.methods:
|
| - names.append(self.name_template.substitute(
|
| - INTERFACE = interface.name,
|
| - METHOD = method.name,
|
| - NAME = name))
|
| - name += 1
|
| -
|
| - struct = GetStructFromMethod(interface, method)
|
| - ps = mojom_pack.PackedStruct(struct)
|
| - param_classes.append(self.GetStructDeclaration(struct.name, ps))
|
| - param_templates.append(template_declaration.substitute(CLASS=struct.name))
|
| -
|
| - self.WriteTemplateToFile("interface_serialization.h", interface.name,
|
| - HEADER_GUARD = self.GetHeaderGuard(interface.name + "_SERIALIZATION"),
|
| - INCLUDES = '\n'.join(includes),
|
| - NAMES = '\n'.join(names),
|
| - PARAM_CLASSES = '\n'.join(param_classes),
|
| - PARAM_TEMPLATES = '\n'.join(param_templates))
|
| -
|
| - def GenerateInterfaceSerializationSource(self, interface):
|
| - implementations = []
|
| - serializations = []
|
| - for method in interface.methods:
|
| - struct = GetStructFromMethod(interface, method)
|
| - ps = mojom_pack.PackedStruct(struct)
|
| - implementations.append(self.GetStructImplementation(struct.name, ps))
|
| - serializations.append(
|
| - self.GetStructSerialization("internal::" + struct.name, "params", ps))
|
| - self.WriteTemplateToFile("interface_serialization.cc", interface.name,
|
| - HEADER = self.GetHeaderFile(interface.name, "serialization"),
|
| - IMPLEMENTATIONS = '\n'.join(implementations),
|
| - SERIALIZATIONS = '\n'.join(serializations))
|
| -
|
| - def GenerateInterfaceProxyHeader(self, interface):
|
| - methods = []
|
| - for method in interface.methods:
|
| - params = map(
|
| - lambda param: "%s %s" % (self.GetConstType(param.kind), param.name),
|
| - method.parameters)
|
| - methods.append(
|
| - " virtual void %s(%s) MOJO_OVERRIDE;" \
|
| - % (method.name, ", ".join(params)))
|
| -
|
| - self.WriteTemplateToFile("interface_proxy.h", interface.name,
|
| - HEADER_GUARD = self.GetHeaderGuard(interface.name + "_PROXY"),
|
| - HEADER = self.GetHeaderFile(interface.name),
|
| - CLASS = interface.name,
|
| - METHODS = '\n'.join(methods))
|
| -
|
| - def GenerateInterfaceProxySource(self, interface):
|
| implementations = Lines(self.GetTemplate("proxy_implementation"))
|
| +
|
| for method in interface.methods:
|
| + cases.append(self.GetCaseLine(interface, method))
|
| sets = []
|
| computes = Lines(self.param_struct_compute_template)
|
| for param in method.parameters:
|
| @@ -496,8 +380,8 @@ class CPPGenerator(object):
|
| params_list = map(
|
| lambda param: "%s %s" % (self.GetConstType(param.kind), param.name),
|
| method.parameters)
|
| - name = "internal::k%s_%s_Name" % (interface.name, method.name)
|
| - params_name = "internal::%s_%s_Params" % (interface.name, method.name)
|
| + name = "k%s_%s_Name" % (interface.name, method.name)
|
| + params_name = "%s_%s_Params" % (interface.name, method.name)
|
|
|
| implementations.Add(
|
| CLASS = interface.name,
|
| @@ -507,25 +391,93 @@ class CPPGenerator(object):
|
| PARAMS_LIST = ', '.join(params_list),
|
| COMPUTES = computes,
|
| SETS = '\n'.join(sets))
|
| - self.WriteTemplateToFile("interface_proxy.cc", interface.name,
|
| - HEADER = self.GetHeaderFile(interface.name, "proxy"),
|
| - SERIALIZATION_HEADER = \
|
| - self.GetHeaderFile(interface.name, "serialization"),
|
| + stub_definition = self.GetTemplate("interface_stub_definition").substitute(
|
| CLASS = interface.name,
|
| - IMPLEMENTATIONS = implementations)
|
| + CASES = '\n'.join(cases))
|
| + return self.GetTemplate("interface_definition").substitute(
|
| + CLASS = interface.name + "Proxy",
|
| + PROXY_DEFINITIONS = implementations,
|
| + STUB_DEFINITION = stub_definition)
|
|
|
| - def GenerateFiles(self):
|
| - for struct in self.module.structs:
|
| - ps = mojom_pack.PackedStruct(struct)
|
| - self.GenerateStructHeader(ps)
|
| - self.GenerateStructSource(ps)
|
| - self.GenerateStructSerializationHeader(ps)
|
| - self.GenerateStructSerializationSource(ps)
|
| + def GetInterfaceDefinitions(self):
|
| + return '\n'.join(
|
| + map(lambda i: self.GetInterfaceDefinition(i), self.module.interfaces))
|
| +
|
| + def GetStructSerializationDefinition(self, struct):
|
| + ps = mojom_pack.PackedStruct(struct)
|
| + param_name = CamelToUnderscores(struct.name)
|
| +
|
| + clones = Lines(self.struct_serialization_clone_template)
|
| + sizes = " return sizeof(*%s)" % param_name
|
| + fields = self.GetSerializedFields(ps)
|
| + for field in fields:
|
| + substitutions = {'NAME': param_name, 'FIELD': field.name}
|
| + sizes += \
|
| + self.struct_serialization_compute_template.substitute(substitutions)
|
| + clones.Add(substitutions)
|
| + sizes += ";"
|
| + serialization = self.GetStructSerialization(
|
| + struct.name, param_name, ps, self.GetTemplate("struct_serialization"))
|
| + return self.GetTemplate("struct_serialization_definition").substitute(
|
| + NAME = param_name,
|
| + CLASS = "%s::%s" % (self.module.namespace, struct.name),
|
| + SIZES = sizes,
|
| + CLONES = clones,
|
| + SERIALIZATION = serialization)
|
| +
|
| + def GetStructSerializationDefinitions(self):
|
| + return '\n'.join(
|
| + map(lambda i: self.GetStructSerializationDefinition(i),
|
| + self.module.structs))
|
| +
|
| + def GetInterfaceSerializationDefinitions(self):
|
| + serializations = []
|
| + for interface in self.module.interfaces:
|
| + for method in interface.methods:
|
| + struct = GetStructFromMethod(interface, method)
|
| + ps = mojom_pack.PackedStruct(struct)
|
| + serializations.append(self.GetStructSerialization(
|
| + struct.name,
|
| + "params",
|
| + ps,
|
| + self.GetTemplate("params_serialization"),
|
| + 2))
|
| + return '\n'.join(serializations)
|
| +
|
| + def GetParamsDefinitions(self):
|
| + params_defs = []
|
| for interface in self.module.interfaces:
|
| - self.GenerateInterfaceHeader(interface)
|
| - self.GenerateInterfaceStubHeader(interface)
|
| - self.GenerateInterfaceStubSource(interface)
|
| - self.GenerateInterfaceSerializationHeader(interface)
|
| - self.GenerateInterfaceSerializationSource(interface)
|
| - self.GenerateInterfaceProxyHeader(interface)
|
| - self.GenerateInterfaceProxySource(interface)
|
| + next_id = 0
|
| + for method in interface.methods:
|
| + (params_def, next_id) = \
|
| + self.GetParamsDefinition(interface, method, next_id)
|
| + params_defs.append(params_def)
|
| + return '\n'.join(params_defs)
|
| +
|
| + def GenerateModuleSource(self):
|
| + self.WriteTemplateToFile("module.cc",
|
| + HEADER = self.GetHeaderFile(self.module.name),
|
| + INTERNAL_HEADER = self.GetHeaderFile(self.module.name, "internal"),
|
| + PARAM_DEFINITIONS = self.GetParamsDefinitions(),
|
| + STRUCT_DEFINITIONS = self.GetStructDefinitions(),
|
| + INTERFACE_DEFINITIONS = self.GetInterfaceDefinitions(),
|
| + STRUCT_SERIALIZATION_DEFINITIONS =
|
| + self.GetStructSerializationDefinitions(),
|
| + INTERFACE_SERIALIZATION_DEFINITIONS =
|
| + self.GetInterfaceSerializationDefinitions())
|
| +
|
| + def GenerateModuleInternalHeader(self):
|
| + traits = map(
|
| + lambda s: self.GetTemplate("struct_serialization_traits").substitute(
|
| + NAME = CamelToUnderscores(s.name),
|
| + FULL_CLASS = "%s::%s" % (self.module.namespace, s.name)),
|
| + self.module.structs);
|
| + self.WriteTemplateToFile("module_internal.h",
|
| + HEADER_GUARD = self.GetHeaderGuard(self.module.name + "_INTERNAL"),
|
| + HEADER = self.GetHeaderFile(self.module.name),
|
| + TRAITS = '\n'.join(traits))
|
| +
|
| + def GenerateFiles(self):
|
| + self.GenerateModuleHeader()
|
| + self.GenerateModuleInternalHeader()
|
| + self.GenerateModuleSource()
|
|
|