Commit f554fc25 authored by yzshen's avatar yzshen Committed by Commit bot

Mojo code generator: makes the filters member methods of generator if necessary.

So that we don't need to use global variables.

BUG=718614

Review-Url: https://codereview.chromium.org/2864543002
Cr-Commit-Position: refs/heads/master@{#469530}
parent 99842054
...@@ -32,15 +32,6 @@ _kind_to_cpp_literal_suffix = { ...@@ -32,15 +32,6 @@ _kind_to_cpp_literal_suffix = {
mojom.UINT64: "ULL", mojom.UINT64: "ULL",
} }
# TODO(rockot): Get rid of these globals. This requires some refactoring of the
# generator library code so that filters can use the generator as context.
_current_typemap = {}
_for_blink = False
# TODO(rockot, yzshen): The variant handling is kind of a hack currently. Make
# it right.
_variant = None
_export_attribute = None
class _NameFormatter(object): class _NameFormatter(object):
"""A formatter for the names of kinds or values.""" """A formatter for the names of kinds or values."""
...@@ -130,56 +121,363 @@ class _NameFormatter(object): ...@@ -130,56 +121,363 @@ class _NameFormatter(object):
return [] return []
def ConstantValue(constant): def NamespaceToArray(namespace):
return ExpressionToText(constant.value, kind=constant.kind) return namespace.split(".") if namespace else []
def GetWtfHashFnNameForEnum(enum):
return _NameFormatter(
enum, None).Format("_", internal=True, add_same_module_namespaces=True,
flatten_nested_kind=True) + "HashFn"
def IsNativeOnlyKind(kind):
return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \
kind.native_only
def AllEnumValues(enum):
"""Return all enum values associated with an enum.
Args:
enum: {mojom.Enum} The enum type.
Returns:
{Set[int]} The values.
"""
return set(field.numeric_value for field in enum.fields)
def GetCppPodType(kind):
return _kind_to_cpp_type[kind]
def GetCppDataViewType(kind, qualified=False):
def _GetName(input_kind):
return _NameFormatter(input_kind, None).FormatForCpp(
add_same_module_namespaces=qualified, flatten_nested_kind=True)
if mojom.IsEnumKind(kind):
return _GetName(kind)
if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
return "%sDataView" % _GetName(kind)
if mojom.IsArrayKind(kind):
return "mojo::ArrayDataView<%s>" % GetCppDataViewType(kind.kind, qualified)
if mojom.IsMapKind(kind):
return ("mojo::MapDataView<%s, %s>" % (
GetCppDataViewType(kind.key_kind, qualified),
GetCppDataViewType(kind.value_kind, qualified)))
if mojom.IsStringKind(kind):
return "mojo::StringDataView"
if mojom.IsInterfaceKind(kind):
return "%sPtrDataView" % _GetName(kind)
if mojom.IsInterfaceRequestKind(kind):
return "%sRequestDataView" % _GetName(kind.kind)
if mojom.IsAssociatedInterfaceKind(kind):
return "%sAssociatedPtrInfoDataView" % _GetName(kind.kind)
if mojom.IsAssociatedInterfaceRequestKind(kind):
return "%sAssociatedRequestDataView" % _GetName(kind.kind)
if mojom.IsGenericHandleKind(kind):
return "mojo::ScopedHandle"
if mojom.IsDataPipeConsumerKind(kind):
return "mojo::ScopedDataPipeConsumerHandle"
if mojom.IsDataPipeProducerKind(kind):
return "mojo::ScopedDataPipeProducerHandle"
if mojom.IsMessagePipeKind(kind):
return "mojo::ScopedMessagePipeHandle"
if mojom.IsSharedBufferKind(kind):
return "mojo::ScopedSharedBufferHandle"
return _kind_to_cpp_type[kind]
def GetUnmappedTypeForSerializer(kind):
return GetCppDataViewType(kind, qualified=True)
def RequiresContextForDataView(kind):
for field in kind.fields:
if mojom.IsReferenceKind(field.kind):
return True
return False
def ShouldInlineStruct(struct):
# TODO(darin): Base this on the size of the wrapper class.
if len(struct.fields) > 4:
return False
for field in struct.fields:
if mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind):
return False
return True
def ShouldInlineUnion(union):
return not any(
mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind)
for field in union.fields)
class StructConstructor(object):
"""Represents a constructor for a generated struct.
Fields:
fields: {[Field]} All struct fields in order.
params: {[Field]} The fields that are passed as params.
"""
def __init__(self, fields, params):
self._fields = fields
self._params = set(params)
@property
def params(self):
return [field for field in self._fields if field in self._params]
@property
def fields(self):
for field in self._fields:
yield (field, field in self._params)
class Generator(generator.Generator):
def __init__(self, *args, **kwargs):
super(Generator, self).__init__(*args, **kwargs)
def _GetExtraTraitsHeaders(self):
extra_headers = set()
for typemap in self._GetAllUsedTypemaps():
extra_headers.update(typemap.get("traits_headers", []))
return sorted(extra_headers)
def _GetAllUsedTypemaps(self):
"""Returns the typemaps for types needed for serialization in this module.
A type is needed for serialization if it is contained by a struct or union
defined in this module, is a parameter of a message in an interface in
this module or is contained within another type needed for serialization.
"""
used_typemaps = []
seen_types = set()
def AddKind(kind):
if (mojom.IsIntegralKind(kind) or mojom.IsStringKind(kind) or
mojom.IsDoubleKind(kind) or mojom.IsFloatKind(kind) or
mojom.IsAnyHandleKind(kind) or
mojom.IsInterfaceKind(kind) or
mojom.IsInterfaceRequestKind(kind) or
mojom.IsAssociatedKind(kind)):
pass
elif mojom.IsArrayKind(kind):
AddKind(kind.kind)
elif mojom.IsMapKind(kind):
AddKind(kind.key_kind)
AddKind(kind.value_kind)
else:
name = self._GetFullMojomNameForKind(kind)
if name in seen_types:
return
seen_types.add(name)
typemap = self.typemap.get(name, None)
if typemap:
used_typemaps.append(typemap)
if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
for field in kind.fields:
AddKind(field.kind)
for kind in self.module.structs + self.module.unions:
for field in kind.fields:
AddKind(field.kind)
for interface in self.module.interfaces:
for method in interface.methods:
for parameter in method.parameters + (method.response_parameters or []):
AddKind(parameter.kind)
return used_typemaps
def _GetExtraPublicHeaders(self):
all_enums = list(self.module.enums)
for struct in self.module.structs:
all_enums.extend(struct.enums)
for interface in self.module.interfaces:
all_enums.extend(interface.enums)
types = set(self._GetFullMojomNameForKind(typename)
for typename in
self.module.structs + all_enums + self.module.unions)
headers = set()
for typename, typemap in self.typemap.iteritems():
if typename in types:
headers.update(typemap.get("public_headers", []))
return sorted(headers)
def _GetDirectlyUsedKinds(self):
for struct in self.module.structs + self.module.unions:
for field in struct.fields:
yield field.kind
for interface in self.module.interfaces:
for method in interface.methods:
for param in method.parameters + (method.response_parameters or []):
yield param.kind
def _GetJinjaExports(self):
structs = self.GetStructs()
interfaces = self.GetInterfaces()
all_enums = list(self.module.enums)
for struct in structs:
all_enums.extend(struct.enums)
for interface in interfaces:
all_enums.extend(interface.enums)
return {
"module": self.module,
"namespace": self.module.namespace,
"namespaces_as_array": NamespaceToArray(self.module.namespace),
"imports": self.module.imports,
"kinds": self.module.kinds,
"enums": self.module.enums,
"all_enums": all_enums,
"structs": structs,
"unions": self.GetUnions(),
"interfaces": interfaces,
"variant": self.variant,
"extra_traits_headers": self._GetExtraTraitsHeaders(),
"extra_public_headers": self._GetExtraPublicHeaders(),
"for_blink": self.for_blink,
"use_once_callback": self.use_once_callback,
"export_attribute": self.export_attribute,
"export_header": self.export_header,
}
@staticmethod
def GetTemplatePrefix():
return "cpp_templates"
def GetFilters(self):
cpp_filters = {
"all_enum_values": AllEnumValues,
"constant_value": self._ConstantValue,
"contains_handles_or_interfaces": mojom.ContainsHandlesOrInterfaces,
"contains_move_only_members": self._ContainsMoveOnlyMembers,
"cpp_wrapper_param_type": self._GetCppWrapperParamType,
"cpp_data_view_type": GetCppDataViewType,
"cpp_field_type": self._GetCppFieldType,
"cpp_union_field_type": self._GetCppUnionFieldType,
"cpp_pod_type": GetCppPodType,
"cpp_union_getter_return_type": self._GetUnionGetterReturnType,
"cpp_union_trait_getter_return_type": self._GetUnionTraitGetterReturnType,
"cpp_wrapper_type": self._GetCppWrapperType,
"default_value": self._DefaultValue,
"expression_to_text": self._ExpressionToText,
"format_constant_declaration": self._FormatConstantDeclaration,
"get_container_validate_params_ctor_args":
self._GetContainerValidateParamsCtorArgs,
"get_name_for_kind": self._GetNameForKind,
"get_pad": pack.GetPad,
"get_qualified_name_for_kind": self._GetQualifiedNameForKind,
"has_callbacks": mojom.HasCallbacks,
"has_sync_methods": mojom.HasSyncMethods,
"requires_context_for_data_view": RequiresContextForDataView,
"should_inline": ShouldInlineStruct,
"should_inline_union": ShouldInlineUnion,
"is_array_kind": mojom.IsArrayKind,
"is_enum_kind": mojom.IsEnumKind,
"is_integral_kind": mojom.IsIntegralKind,
"is_native_only_kind": IsNativeOnlyKind,
"is_any_handle_kind": mojom.IsAnyHandleKind,
"is_any_interface_kind": mojom.IsAnyInterfaceKind,
"is_any_handle_or_interface_kind": mojom.IsAnyHandleOrInterfaceKind,
"is_associated_kind": mojom.IsAssociatedKind,
"is_hashable": self._IsHashableKind,
"is_map_kind": mojom.IsMapKind,
"is_nullable_kind": mojom.IsNullableKind,
"is_object_kind": mojom.IsObjectKind,
"is_reference_kind": mojom.IsReferenceKind,
"is_string_kind": mojom.IsStringKind,
"is_struct_kind": mojom.IsStructKind,
"is_typemapped_kind": self._IsTypemappedKind,
"is_union_kind": mojom.IsUnionKind,
"passes_associated_kinds": mojom.PassesAssociatedKinds,
"struct_constructors": self._GetStructConstructors,
"under_to_camel": generator.UnderToCamel,
"unmapped_type_for_serializer": GetUnmappedTypeForSerializer,
"wtf_hash_fn_name_for_enum": GetWtfHashFnNameForEnum,
}
return cpp_filters
@UseJinja("module.h.tmpl")
def _GenerateModuleHeader(self):
return self._GetJinjaExports()
@UseJinja("module.cc.tmpl")
def _GenerateModuleSource(self):
return self._GetJinjaExports()
@UseJinja("module-shared.h.tmpl")
def _GenerateModuleSharedHeader(self):
return self._GetJinjaExports()
@UseJinja("module-shared-internal.h.tmpl")
def _GenerateModuleSharedInternalHeader(self):
return self._GetJinjaExports()
# TODO(yzshen): Revisit the default value feature. It was designed prior to @UseJinja("module-shared.cc.tmpl")
# custom type mapping. def _GenerateModuleSharedSource(self):
def DefaultValue(field): return self._GetJinjaExports()
def GenerateFiles(self, args):
if self.generate_non_variant_code:
self.Write(self._GenerateModuleSharedHeader(),
self.MatchMojomFilePath("%s-shared.h" % self.module.name))
self.Write(
self._GenerateModuleSharedInternalHeader(),
self.MatchMojomFilePath("%s-shared-internal.h" % self.module.name))
self.Write(self._GenerateModuleSharedSource(),
self.MatchMojomFilePath("%s-shared.cc" % self.module.name))
else:
suffix = "-%s" % self.variant if self.variant else ""
self.Write(self._GenerateModuleHeader(),
self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix)))
self.Write(
self._GenerateModuleSource(),
self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix)))
def _ConstantValue(self, constant):
return self._ExpressionToText(constant.value, kind=constant.kind)
# TODO(yzshen): Revisit the default value feature. It was designed prior to
# custom type mapping.
def _DefaultValue(self, field):
if field.default: if field.default:
if mojom.IsStructKind(field.kind): if mojom.IsStructKind(field.kind):
assert field.default == "default" assert field.default == "default"
if not IsTypemappedKind(field.kind): if not self._IsTypemappedKind(field.kind):
return "%s::New()" % GetNameForKind(field.kind) return "%s::New()" % self._GetNameForKind(field.kind)
return ExpressionToText(field.default, kind=field.kind) return self._ExpressionToText(field.default, kind=field.kind)
return "" return ""
def NamespaceToArray(namespace): def _GetNameForKind(self, kind, internal=False, flatten_nested_kind=False,
return namespace.split(".") if namespace else []
def GetNameForKind(kind, internal=False, flatten_nested_kind=False,
add_same_module_namespaces=False): add_same_module_namespaces=False):
return _NameFormatter(kind, _variant).FormatForCpp( return _NameFormatter(kind, self.variant).FormatForCpp(
internal=internal, flatten_nested_kind=flatten_nested_kind, internal=internal, flatten_nested_kind=flatten_nested_kind,
add_same_module_namespaces=add_same_module_namespaces) add_same_module_namespaces=add_same_module_namespaces)
def GetQualifiedNameForKind(kind, internal=False, flatten_nested_kind=False, def _GetQualifiedNameForKind(self, kind, internal=False,
include_variant=True): flatten_nested_kind=False, include_variant=True):
return _NameFormatter( return _NameFormatter(
kind, _variant if include_variant else None).FormatForCpp( kind, self.variant if include_variant else None).FormatForCpp(
internal=internal, add_same_module_namespaces=True, internal=internal, add_same_module_namespaces=True,
flatten_nested_kind=flatten_nested_kind) flatten_nested_kind=flatten_nested_kind)
def _GetFullMojomNameForKind(self, kind):
return _NameFormatter(kind, self.variant).FormatForMojom()
def GetWtfHashFnNameForEnum(enum): def _IsTypemappedKind(self, kind):
return _NameFormatter(
enum, None).Format("_", internal=True, add_same_module_namespaces=True,
flatten_nested_kind=True) + "HashFn"
def GetFullMojomNameForKind(kind):
return _NameFormatter(kind, _variant).FormatForMojom()
def IsTypemappedKind(kind):
return hasattr(kind, "name") and \ return hasattr(kind, "name") and \
GetFullMojomNameForKind(kind) in _current_typemap self._GetFullMojomNameForKind(kind) in self.typemap
def IsNativeOnlyKind(kind):
return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \
kind.native_only
def IsHashableKind(kind): def _IsHashableKind(self, kind):
"""Check if the kind can be hashed. """Check if the kind can be hashed.
Args: Args:
...@@ -196,110 +494,98 @@ def IsHashableKind(kind): ...@@ -196,110 +494,98 @@ def IsHashableKind(kind):
if mojom.IsNullableKind(kind): if mojom.IsNullableKind(kind):
return False return False
elif mojom.IsStructKind(kind): elif mojom.IsStructKind(kind):
if (IsTypemappedKind(kind) and if (self._IsTypemappedKind(kind) and
not _current_typemap[GetFullMojomNameForKind(kind)]["hashable"]): not self.typemap[self._GetFullMojomNameForKind(kind)]["hashable"]):
return False return False
return all(Check(field.kind) for field in kind.fields) return all(Check(field.kind) for field in kind.fields)
elif mojom.IsEnumKind(kind): elif mojom.IsEnumKind(kind):
return not IsTypemappedKind(kind) or _current_typemap[ return not self._IsTypemappedKind(kind) or self.typemap[
GetFullMojomNameForKind(kind)]["hashable"] self._GetFullMojomNameForKind(kind)]["hashable"]
elif mojom.IsUnionKind(kind): elif mojom.IsUnionKind(kind):
return all(Check(field.kind) for field in kind.fields) return all(Check(field.kind) for field in kind.fields)
elif mojom.IsAnyHandleKind(kind): elif mojom.IsAnyHandleKind(kind):
return False return False
elif mojom.IsAnyInterfaceKind(kind): elif mojom.IsAnyInterfaceKind(kind):
return False return False
# TODO(tibell): Arrays and maps could be made hashable. We just don't have a # TODO(tibell): Arrays and maps could be made hashable. We just don't have
# use case yet. # a use case yet.
elif mojom.IsArrayKind(kind): elif mojom.IsArrayKind(kind):
return False return False
elif mojom.IsMapKind(kind): elif mojom.IsMapKind(kind):
return False return False
else: else:
return True return True
return Check(kind) return Check(kind)
def AllEnumValues(enum):
"""Return all enum values associated with an enum.
Args:
enum: {mojom.Enum} The enum type.
Returns:
{Set[int]} The values.
"""
return set(field.numeric_value for field in enum.fields)
def GetNativeTypeName(typemapped_kind):
return _current_typemap[GetFullMojomNameForKind(typemapped_kind)]["typename"]
def GetCppPodType(kind): def _GetNativeTypeName(self, typemapped_kind):
return _kind_to_cpp_type[kind] return self.typemap[self._GetFullMojomNameForKind(typemapped_kind)][
"typename"]
def FormatConstantDeclaration(constant, nested=False): def _FormatConstantDeclaration(self, constant, nested=False):
if mojom.IsStringKind(constant.kind): if mojom.IsStringKind(constant.kind):
if nested: if nested:
return "const char %s[]" % constant.name return "const char %s[]" % constant.name
return "%sextern const char %s[]" % \ return "%sextern const char %s[]" % \
((_export_attribute + " ") if _export_attribute else "", constant.name) ((self.export_attribute + " ") if self.export_attribute else "",
return "constexpr %s %s = %s" % (GetCppPodType(constant.kind), constant.name, constant.name)
ConstantValue(constant)) return "constexpr %s %s = %s" % (
GetCppPodType(constant.kind), constant.name,
self._ConstantValue(constant))
def GetCppWrapperType(kind, add_same_module_namespaces=False): def _GetCppWrapperType(self, kind, add_same_module_namespaces=False):
def _AddOptional(type_name): def _AddOptional(type_name):
pattern = "WTF::Optional<%s>" if _for_blink else "base::Optional<%s>" pattern = "WTF::Optional<%s>" if self.for_blink else "base::Optional<%s>"
return pattern % type_name return pattern % type_name
if IsTypemappedKind(kind): if self._IsTypemappedKind(kind):
type_name = GetNativeTypeName(kind) type_name = self._GetNativeTypeName(kind)
if (mojom.IsNullableKind(kind) and if (mojom.IsNullableKind(kind) and
not _current_typemap[GetFullMojomNameForKind(kind)][ not self.typemap[self._GetFullMojomNameForKind(kind)][
"nullable_is_same_type"]): "nullable_is_same_type"]):
type_name = _AddOptional(type_name) type_name = _AddOptional(type_name)
return type_name return type_name
if mojom.IsEnumKind(kind): if mojom.IsEnumKind(kind):
return GetNameForKind( return self._GetNameForKind(
kind, add_same_module_namespaces=add_same_module_namespaces) kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
return "%sPtr" % GetNameForKind( return "%sPtr" % self._GetNameForKind(
kind, add_same_module_namespaces=add_same_module_namespaces) kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsArrayKind(kind): if mojom.IsArrayKind(kind):
pattern = "WTF::Vector<%s>" if _for_blink else "std::vector<%s>" pattern = "WTF::Vector<%s>" if self.for_blink else "std::vector<%s>"
if mojom.IsNullableKind(kind): if mojom.IsNullableKind(kind):
pattern = _AddOptional(pattern) pattern = _AddOptional(pattern)
return pattern % GetCppWrapperType( return pattern % self._GetCppWrapperType(
kind.kind, add_same_module_namespaces=add_same_module_namespaces) kind.kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsMapKind(kind): if mojom.IsMapKind(kind):
pattern = ("WTF::HashMap<%s, %s>" if _for_blink else pattern = ("WTF::HashMap<%s, %s>" if self.for_blink else
"std::unordered_map<%s, %s>") "std::unordered_map<%s, %s>")
if mojom.IsNullableKind(kind): if mojom.IsNullableKind(kind):
pattern = _AddOptional(pattern) pattern = _AddOptional(pattern)
return pattern % ( return pattern % (
GetCppWrapperType( self._GetCppWrapperType(
kind.key_kind, kind.key_kind,
add_same_module_namespaces=add_same_module_namespaces), add_same_module_namespaces=add_same_module_namespaces),
GetCppWrapperType( self._GetCppWrapperType(
kind.value_kind, kind.value_kind,
add_same_module_namespaces=add_same_module_namespaces)) add_same_module_namespaces=add_same_module_namespaces))
if mojom.IsInterfaceKind(kind): if mojom.IsInterfaceKind(kind):
return "%sPtr" % GetNameForKind( return "%sPtr" % self._GetNameForKind(
kind, add_same_module_namespaces=add_same_module_namespaces) kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsInterfaceRequestKind(kind): if mojom.IsInterfaceRequestKind(kind):
return "%sRequest" % GetNameForKind( return "%sRequest" % self._GetNameForKind(
kind.kind, add_same_module_namespaces=add_same_module_namespaces) kind.kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsAssociatedInterfaceKind(kind): if mojom.IsAssociatedInterfaceKind(kind):
return "%sAssociatedPtrInfo" % GetNameForKind( return "%sAssociatedPtrInfo" % self._GetNameForKind(
kind.kind, add_same_module_namespaces=add_same_module_namespaces) kind.kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsAssociatedInterfaceRequestKind(kind): if mojom.IsAssociatedInterfaceRequestKind(kind):
return "%sAssociatedRequest" % GetNameForKind( return "%sAssociatedRequest" % self._GetNameForKind(
kind.kind, add_same_module_namespaces=add_same_module_namespaces) kind.kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsStringKind(kind): if mojom.IsStringKind(kind):
if _for_blink: if self.for_blink:
return "WTF::String" return "WTF::String"
type_name = "std::string" type_name = "std::string"
return _AddOptional(type_name) if mojom.IsNullableKind(kind) else type_name return (_AddOptional(type_name) if mojom.IsNullableKind(kind)
else type_name)
if mojom.IsGenericHandleKind(kind): if mojom.IsGenericHandleKind(kind):
return "mojo::ScopedHandle" return "mojo::ScopedHandle"
if mojom.IsDataPipeConsumerKind(kind): if mojom.IsDataPipeConsumerKind(kind):
...@@ -314,48 +600,49 @@ def GetCppWrapperType(kind, add_same_module_namespaces=False): ...@@ -314,48 +600,49 @@ def GetCppWrapperType(kind, add_same_module_namespaces=False):
raise Exception("Unrecognized kind %s" % kind.spec) raise Exception("Unrecognized kind %s" % kind.spec)
return _kind_to_cpp_type[kind] return _kind_to_cpp_type[kind]
def IsMoveOnlyKind(kind): def _IsMoveOnlyKind(self, kind):
if IsTypemappedKind(kind): if self._IsTypemappedKind(kind):
if mojom.IsEnumKind(kind): if mojom.IsEnumKind(kind):
return False return False
return _current_typemap[GetFullMojomNameForKind(kind)]["move_only"] return self.typemap[self._GetFullMojomNameForKind(kind)]["move_only"]
if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
return True return True
if mojom.IsArrayKind(kind): if mojom.IsArrayKind(kind):
return IsMoveOnlyKind(kind.kind) return self._IsMoveOnlyKind(kind.kind)
if mojom.IsMapKind(kind): if mojom.IsMapKind(kind):
return IsMoveOnlyKind(kind.value_kind) return self._IsMoveOnlyKind(kind.value_kind)
if mojom.IsAnyHandleOrInterfaceKind(kind): if mojom.IsAnyHandleOrInterfaceKind(kind):
return True return True
return False return False
def IsCopyablePassByValue(kind): def _IsCopyablePassByValue(self, kind):
if not IsTypemappedKind(kind): if not self._IsTypemappedKind(kind):
return False return False
return _current_typemap[GetFullMojomNameForKind(kind)][ return self.typemap[self._GetFullMojomNameForKind(kind)][
"copyable_pass_by_value"] "copyable_pass_by_value"]
def ShouldPassParamByValue(kind): def _ShouldPassParamByValue(self, kind):
return ((not mojom.IsReferenceKind(kind)) or IsMoveOnlyKind(kind) or return ((not mojom.IsReferenceKind(kind)) or self._IsMoveOnlyKind(kind) or
IsCopyablePassByValue(kind)) self._IsCopyablePassByValue(kind))
def GetCppWrapperParamType(kind): def _GetCppWrapperParamType(self, kind):
cpp_wrapper_type = GetCppWrapperType(kind) cpp_wrapper_type = self._GetCppWrapperType(kind)
return (cpp_wrapper_type if ShouldPassParamByValue(kind) return (cpp_wrapper_type if self._ShouldPassParamByValue(kind)
else "const %s&" % cpp_wrapper_type) else "const %s&" % cpp_wrapper_type)
def GetCppFieldType(kind): def _GetCppFieldType(self, kind):
if mojom.IsStructKind(kind): if mojom.IsStructKind(kind):
return ("mojo::internal::Pointer<%s>" % return ("mojo::internal::Pointer<%s>" %
GetNameForKind(kind, internal=True)) self._GetNameForKind(kind, internal=True))
if mojom.IsUnionKind(kind): if mojom.IsUnionKind(kind):
return "%s" % GetNameForKind(kind, internal=True) return "%s" % self._GetNameForKind(kind, internal=True)
if mojom.IsArrayKind(kind): if mojom.IsArrayKind(kind):
return ("mojo::internal::Pointer<mojo::internal::Array_Data<%s>>" % return ("mojo::internal::Pointer<mojo::internal::Array_Data<%s>>" %
GetCppFieldType(kind.kind)) self._GetCppFieldType(kind.kind))
if mojom.IsMapKind(kind): if mojom.IsMapKind(kind):
return ("mojo::internal::Pointer<mojo::internal::Map_Data<%s, %s>>" % return ("mojo::internal::Pointer<mojo::internal::Map_Data<%s, %s>>" %
(GetCppFieldType(kind.key_kind), GetCppFieldType(kind.value_kind))) (self._GetCppFieldType(kind.key_kind),
self._GetCppFieldType(kind.value_kind)))
if mojom.IsInterfaceKind(kind): if mojom.IsInterfaceKind(kind):
return "mojo::internal::Interface_Data" return "mojo::internal::Interface_Data"
if mojom.IsInterfaceRequestKind(kind): if mojom.IsInterfaceRequestKind(kind):
...@@ -372,17 +659,18 @@ def GetCppFieldType(kind): ...@@ -372,17 +659,18 @@ def GetCppFieldType(kind):
return "mojo::internal::Handle_Data" return "mojo::internal::Handle_Data"
return _kind_to_cpp_type[kind] return _kind_to_cpp_type[kind]
def GetCppUnionFieldType(kind): def _GetCppUnionFieldType(self, kind):
if mojom.IsUnionKind(kind): if mojom.IsUnionKind(kind):
return ("mojo::internal::Pointer<%s>" % GetNameForKind(kind, internal=True)) return ("mojo::internal::Pointer<%s>" %
return GetCppFieldType(kind) self._GetNameForKind(kind, internal=True))
return self._GetCppFieldType(kind)
def GetUnionGetterReturnType(kind): def _GetUnionGetterReturnType(self, kind):
if mojom.IsReferenceKind(kind): if mojom.IsReferenceKind(kind):
return "%s&" % GetCppWrapperType(kind) return "%s&" % self._GetCppWrapperType(kind)
return GetCppWrapperType(kind) return self._GetCppWrapperType(kind)
def GetUnionTraitGetterReturnType(kind): def _GetUnionTraitGetterReturnType(self, kind):
"""Get field type used in UnionTraits template specialization. """Get field type used in UnionTraits template specialization.
The type may be qualified as UnionTraits specializations live outside the The type may be qualified as UnionTraits specializations live outside the
...@@ -395,52 +683,13 @@ def GetUnionTraitGetterReturnType(kind): ...@@ -395,52 +683,13 @@ def GetUnionTraitGetterReturnType(kind):
{str} The C++ type to use for the field. {str} The C++ type to use for the field.
""" """
if mojom.IsReferenceKind(kind): if mojom.IsReferenceKind(kind):
return "%s&" % GetCppWrapperType(kind, add_same_module_namespaces=True) return "%s&" % self._GetCppWrapperType(kind,
return GetCppWrapperType(kind, add_same_module_namespaces=True) add_same_module_namespaces=True)
return self._GetCppWrapperType(kind, add_same_module_namespaces=True)
def GetCppDataViewType(kind, qualified=False):
def _GetName(input_kind):
return _NameFormatter(input_kind, None).FormatForCpp(
add_same_module_namespaces=qualified, flatten_nested_kind=True)
if mojom.IsEnumKind(kind):
return _GetName(kind)
if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
return "%sDataView" % _GetName(kind)
if mojom.IsArrayKind(kind):
return "mojo::ArrayDataView<%s>" % GetCppDataViewType(kind.kind, qualified)
if mojom.IsMapKind(kind):
return ("mojo::MapDataView<%s, %s>" % (
GetCppDataViewType(kind.key_kind, qualified),
GetCppDataViewType(kind.value_kind, qualified)))
if mojom.IsStringKind(kind):
return "mojo::StringDataView"
if mojom.IsInterfaceKind(kind):
return "%sPtrDataView" % _GetName(kind)
if mojom.IsInterfaceRequestKind(kind):
return "%sRequestDataView" % _GetName(kind.kind)
if mojom.IsAssociatedInterfaceKind(kind):
return "%sAssociatedPtrInfoDataView" % _GetName(kind.kind)
if mojom.IsAssociatedInterfaceRequestKind(kind):
return "%sAssociatedRequestDataView" % _GetName(kind.kind)
if mojom.IsGenericHandleKind(kind):
return "mojo::ScopedHandle"
if mojom.IsDataPipeConsumerKind(kind):
return "mojo::ScopedDataPipeConsumerHandle"
if mojom.IsDataPipeProducerKind(kind):
return "mojo::ScopedDataPipeProducerHandle"
if mojom.IsMessagePipeKind(kind):
return "mojo::ScopedMessagePipeHandle"
if mojom.IsSharedBufferKind(kind):
return "mojo::ScopedSharedBufferHandle"
return _kind_to_cpp_type[kind]
def GetUnmappedTypeForSerializer(kind): def _TranslateConstants(self, token, kind):
return GetCppDataViewType(kind, qualified=True)
def TranslateConstants(token, kind):
if isinstance(token, mojom.NamedValue): if isinstance(token, mojom.NamedValue):
return GetNameForKind(token, flatten_nested_kind=True) return self._GetNameForKind(token, flatten_nested_kind=True)
if isinstance(token, mojom.BuiltinValue): if isinstance(token, mojom.BuiltinValue):
if token.value == "double.INFINITY": if token.value == "double.INFINITY":
...@@ -460,8 +709,8 @@ def TranslateConstants(token, kind): ...@@ -460,8 +709,8 @@ def TranslateConstants(token, kind):
return token if token.isdigit() else token + "f"; return token if token.isdigit() else token + "f";
# Per C++11, 2.14.2, the type of an integer literal is the first of the # Per C++11, 2.14.2, the type of an integer literal is the first of the
# corresponding list in Table 6 in which its value can be represented. In this # corresponding list in Table 6 in which its value can be represented. In
# case, the list for decimal constants with no suffix is: # this case, the list for decimal constants with no suffix is:
# int, long int, long long int # int, long int, long long int
# The standard considers a program ill-formed if it contains an integer # The standard considers a program ill-formed if it contains an integer
# literal that cannot be represented by any of the allowed types. # literal that cannot be represented by any of the allowed types.
...@@ -476,74 +725,31 @@ def TranslateConstants(token, kind): ...@@ -476,74 +725,31 @@ def TranslateConstants(token, kind):
return "%s%s" % (token, _kind_to_cpp_literal_suffix.get(kind, "")) return "%s%s" % (token, _kind_to_cpp_literal_suffix.get(kind, ""))
def ExpressionToText(value, kind=None): def _ExpressionToText(self, value, kind=None):
return TranslateConstants(value, kind) return self._TranslateConstants(value, kind)
def RequiresContextForDataView(kind):
for field in kind.fields:
if mojom.IsReferenceKind(field.kind):
return True
return False
def ShouldInlineStruct(struct):
# TODO(darin): Base this on the size of the wrapper class.
if len(struct.fields) > 4:
return False
for field in struct.fields:
if mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind):
return False
return True
def ContainsMoveOnlyMembers(struct): def _ContainsMoveOnlyMembers(self, struct):
for field in struct.fields: for field in struct.fields:
if IsMoveOnlyKind(field.kind): if self._IsMoveOnlyKind(field.kind):
return True return True
return False return False
def ShouldInlineUnion(union): def _GetStructConstructors(self, struct):
return not any(
mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind)
for field in union.fields)
class StructConstructor(object):
"""Represents a constructor for a generated struct.
Fields:
fields: {[Field]} All struct fields in order.
params: {[Field]} The fields that are passed as params.
"""
def __init__(self, fields, params):
self._fields = fields
self._params = set(params)
@property
def params(self):
return [field for field in self._fields if field in self._params]
@property
def fields(self):
for field in self._fields:
yield (field, field in self._params)
def GetStructConstructors(struct):
"""Returns a list of constructors for a struct. """Returns a list of constructors for a struct.
Params: Params:
struct: {Struct} The struct to return constructors for. struct: {Struct} The struct to return constructors for.
Returns: Returns:
{[StructConstructor]} A list of StructConstructors that should be generated {[StructConstructor]} A list of StructConstructors that should be
for |struct|. generated for |struct|.
""" """
if not mojom.IsStructKind(struct): if not mojom.IsStructKind(struct):
raise TypeError raise TypeError
# Types that are neither copyable nor movable can't be passed to a struct # Types that are neither copyable nor movable can't be passed to a struct
# constructor so only generate a default constructor. # constructor so only generate a default constructor.
if any(IsTypemappedKind(field.kind) and _current_typemap[ if any(self._IsTypemappedKind(field.kind) and self.typemap[
GetFullMojomNameForKind(field.kind)]["non_copyable_non_movable"] self._GetFullMojomNameForKind(field.kind)]["non_copyable_non_movable"]
for field in struct.fields): for field in struct.fields):
return [StructConstructor(struct.fields, [])] return [StructConstructor(struct.fields, [])]
...@@ -556,8 +762,7 @@ def GetStructConstructors(struct): ...@@ -556,8 +762,7 @@ def GetStructConstructors(struct):
return (StructConstructor(struct.fields, ordinal_fields[:param_count]) return (StructConstructor(struct.fields, ordinal_fields[:param_count])
for param_count in param_counts) for param_count in param_counts)
def _GetContainerValidateParamsCtorArgs(self, kind):
def GetContainerValidateParamsCtorArgs(kind):
if mojom.IsStringKind(kind): if mojom.IsStringKind(kind):
expected_num_elements = 0 expected_num_elements = 0
element_is_nullable = False element_is_nullable = False
...@@ -567,19 +772,19 @@ def GetContainerValidateParamsCtorArgs(kind): ...@@ -567,19 +772,19 @@ def GetContainerValidateParamsCtorArgs(kind):
elif mojom.IsMapKind(kind): elif mojom.IsMapKind(kind):
expected_num_elements = 0 expected_num_elements = 0
element_is_nullable = False element_is_nullable = False
key_validate_params = GetNewContainerValidateParams(mojom.Array( key_validate_params = self._GetNewContainerValidateParams(mojom.Array(
kind=kind.key_kind)) kind=kind.key_kind))
element_validate_params = GetNewContainerValidateParams(mojom.Array( element_validate_params = self._GetNewContainerValidateParams(mojom.Array(
kind=kind.value_kind)) kind=kind.value_kind))
enum_validate_func = "nullptr" enum_validate_func = "nullptr"
else: # mojom.IsArrayKind(kind) else: # mojom.IsArrayKind(kind)
expected_num_elements = generator.ExpectedArraySize(kind) or 0 expected_num_elements = generator.ExpectedArraySize(kind) or 0
element_is_nullable = mojom.IsNullableKind(kind.kind) element_is_nullable = mojom.IsNullableKind(kind.kind)
key_validate_params = "nullptr" key_validate_params = "nullptr"
element_validate_params = GetNewContainerValidateParams(kind.kind) element_validate_params = self._GetNewContainerValidateParams(kind.kind)
if mojom.IsEnumKind(kind.kind): if mojom.IsEnumKind(kind.kind):
enum_validate_func = ("%s::Validate" % enum_validate_func = ("%s::Validate" %
GetQualifiedNameForKind(kind.kind, internal=True, self._GetQualifiedNameForKind(kind.kind, internal=True,
flatten_nested_kind=True)) flatten_nested_kind=True))
else: else:
enum_validate_func = "nullptr" enum_validate_func = "nullptr"
...@@ -594,225 +799,10 @@ def GetContainerValidateParamsCtorArgs(kind): ...@@ -594,225 +799,10 @@ def GetContainerValidateParamsCtorArgs(kind):
else: else:
return "%d, %s" % (expected_num_elements, enum_validate_func) return "%d, %s" % (expected_num_elements, enum_validate_func)
def GetNewContainerValidateParams(kind): def _GetNewContainerValidateParams(self, kind):
if (not mojom.IsArrayKind(kind) and not mojom.IsMapKind(kind) and if (not mojom.IsArrayKind(kind) and not mojom.IsMapKind(kind) and
not mojom.IsStringKind(kind)): not mojom.IsStringKind(kind)):
return "nullptr" return "nullptr"
return "new mojo::internal::ContainerValidateParams(%s)" % ( return "new mojo::internal::ContainerValidateParams(%s)" % (
GetContainerValidateParamsCtorArgs(kind)) self._GetContainerValidateParamsCtorArgs(kind))
class Generator(generator.Generator):
cpp_filters = {
"all_enum_values": AllEnumValues,
"constant_value": ConstantValue,
"contains_handles_or_interfaces": mojom.ContainsHandlesOrInterfaces,
"contains_move_only_members": ContainsMoveOnlyMembers,
"cpp_wrapper_param_type": GetCppWrapperParamType,
"cpp_data_view_type": GetCppDataViewType,
"cpp_field_type": GetCppFieldType,
"cpp_union_field_type": GetCppUnionFieldType,
"cpp_pod_type": GetCppPodType,
"cpp_union_getter_return_type": GetUnionGetterReturnType,
"cpp_union_trait_getter_return_type": GetUnionTraitGetterReturnType,
"cpp_wrapper_type": GetCppWrapperType,
"default_value": DefaultValue,
"expression_to_text": ExpressionToText,
"format_constant_declaration": FormatConstantDeclaration,
"get_container_validate_params_ctor_args":
GetContainerValidateParamsCtorArgs,
"get_name_for_kind": GetNameForKind,
"get_pad": pack.GetPad,
"get_qualified_name_for_kind": GetQualifiedNameForKind,
"has_callbacks": mojom.HasCallbacks,
"has_sync_methods": mojom.HasSyncMethods,
"requires_context_for_data_view": RequiresContextForDataView,
"should_inline": ShouldInlineStruct,
"should_inline_union": ShouldInlineUnion,
"is_array_kind": mojom.IsArrayKind,
"is_enum_kind": mojom.IsEnumKind,
"is_integral_kind": mojom.IsIntegralKind,
"is_native_only_kind": IsNativeOnlyKind,
"is_any_handle_kind": mojom.IsAnyHandleKind,
"is_any_interface_kind": mojom.IsAnyInterfaceKind,
"is_any_handle_or_interface_kind": mojom.IsAnyHandleOrInterfaceKind,
"is_associated_kind": mojom.IsAssociatedKind,
"is_hashable": IsHashableKind,
"is_map_kind": mojom.IsMapKind,
"is_nullable_kind": mojom.IsNullableKind,
"is_object_kind": mojom.IsObjectKind,
"is_reference_kind": mojom.IsReferenceKind,
"is_string_kind": mojom.IsStringKind,
"is_struct_kind": mojom.IsStructKind,
"is_typemapped_kind": IsTypemappedKind,
"is_union_kind": mojom.IsUnionKind,
"passes_associated_kinds": mojom.PassesAssociatedKinds,
"struct_constructors": GetStructConstructors,
"stylize_method": generator.StudlyCapsToCamel,
"under_to_camel": generator.UnderToCamel,
"unmapped_type_for_serializer": GetUnmappedTypeForSerializer,
"wtf_hash_fn_name_for_enum": GetWtfHashFnNameForEnum,
}
def GetExtraTraitsHeaders(self):
extra_headers = set()
for typemap in self._GetAllUsedTypemaps():
extra_headers.update(typemap.get("traits_headers", []))
return sorted(extra_headers)
def _GetAllUsedTypemaps(self):
"""Returns the typemaps for types needed for serialization in this module.
A type is needed for serialization if it is contained by a struct or union
defined in this module, is a parameter of a message in an interface in
this module or is contained within another type needed for serialization.
"""
used_typemaps = []
seen_types = set()
def AddKind(kind):
if (mojom.IsIntegralKind(kind) or mojom.IsStringKind(kind) or
mojom.IsDoubleKind(kind) or mojom.IsFloatKind(kind) or
mojom.IsAnyHandleKind(kind) or
mojom.IsInterfaceKind(kind) or
mojom.IsInterfaceRequestKind(kind) or
mojom.IsAssociatedKind(kind)):
pass
elif mojom.IsArrayKind(kind):
AddKind(kind.kind)
elif mojom.IsMapKind(kind):
AddKind(kind.key_kind)
AddKind(kind.value_kind)
else:
name = GetFullMojomNameForKind(kind)
if name in seen_types:
return
seen_types.add(name)
typemap = _current_typemap.get(name, None)
if typemap:
used_typemaps.append(typemap)
if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
for field in kind.fields:
AddKind(field.kind)
for kind in self.module.structs + self.module.unions:
for field in kind.fields:
AddKind(field.kind)
for interface in self.module.interfaces:
for method in interface.methods:
for parameter in method.parameters + (method.response_parameters or []):
AddKind(parameter.kind)
return used_typemaps
def GetExtraPublicHeaders(self):
all_enums = list(self.module.enums)
for struct in self.module.structs:
all_enums.extend(struct.enums)
for interface in self.module.interfaces:
all_enums.extend(interface.enums)
types = set(GetFullMojomNameForKind(typename)
for typename in
self.module.structs + all_enums + self.module.unions)
headers = set()
for typename, typemap in self.typemap.iteritems():
if typename in types:
headers.update(typemap.get("public_headers", []))
return sorted(headers)
def _GetDirectlyUsedKinds(self):
for struct in self.module.structs + self.module.unions:
for field in struct.fields:
yield field.kind
for interface in self.module.interfaces:
for method in interface.methods:
for param in method.parameters + (method.response_parameters or []):
yield param.kind
def GetJinjaExports(self):
structs = self.GetStructs()
interfaces = self.GetInterfaces()
all_enums = list(self.module.enums)
for struct in structs:
all_enums.extend(struct.enums)
for interface in interfaces:
all_enums.extend(interface.enums)
return {
"module": self.module,
"namespace": self.module.namespace,
"namespaces_as_array": NamespaceToArray(self.module.namespace),
"imports": self.module.imports,
"kinds": self.module.kinds,
"enums": self.module.enums,
"all_enums": all_enums,
"structs": structs,
"unions": self.GetUnions(),
"interfaces": interfaces,
"variant": self.variant,
"extra_traits_headers": self.GetExtraTraitsHeaders(),
"extra_public_headers": self.GetExtraPublicHeaders(),
"for_blink": self.for_blink,
"use_once_callback": self.use_once_callback,
"export_attribute": self.export_attribute,
"export_header": self.export_header,
}
@staticmethod
def GetTemplatePrefix():
return "cpp_templates"
@classmethod
def GetFilters(cls):
return cls.cpp_filters
@UseJinja("module.h.tmpl")
def GenerateModuleHeader(self):
return self.GetJinjaExports()
@UseJinja("module.cc.tmpl")
def GenerateModuleSource(self):
return self.GetJinjaExports()
@UseJinja("module-shared.h.tmpl")
def GenerateModuleSharedHeader(self):
return self.GetJinjaExports()
@UseJinja("module-shared-internal.h.tmpl")
def GenerateModuleSharedInternalHeader(self):
return self.GetJinjaExports()
@UseJinja("module-shared.cc.tmpl")
def GenerateModuleSharedSource(self):
return self.GetJinjaExports()
def GenerateFiles(self, args):
if self.generate_non_variant_code:
self.Write(self.GenerateModuleSharedHeader(),
self.MatchMojomFilePath("%s-shared.h" % self.module.name))
self.Write(
self.GenerateModuleSharedInternalHeader(),
self.MatchMojomFilePath("%s-shared-internal.h" % self.module.name))
self.Write(self.GenerateModuleSharedSource(),
self.MatchMojomFilePath("%s-shared.cc" % self.module.name))
else:
global _current_typemap
_current_typemap = self.typemap
global _for_blink
_for_blink = self.for_blink
global _use_once_callback
_use_once_callback = self.use_once_callback
global _variant
_variant = self.variant
global _export_attribute
_export_attribute = self.export_attribute
suffix = "-%s" % self.variant if self.variant else ""
self.Write(self.GenerateModuleHeader(),
self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix)))
self.Write(
self.GenerateModuleSource(),
self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix)))
...@@ -403,7 +403,16 @@ def TempDir(): ...@@ -403,7 +403,16 @@ def TempDir():
shutil.rmtree(dirname) shutil.rmtree(dirname)
class Generator(generator.Generator): class Generator(generator.Generator):
def _GetJinjaExports(self):
return {
'package': GetPackage(self.module),
}
@staticmethod
def GetTemplatePrefix():
return "java_templates"
def GetFilters(self):
java_filters = { java_filters = {
'array_expected_length': GetArrayExpectedLength, 'array_expected_length': GetArrayExpectedLength,
'array': GetArrayKind, 'array': GetArrayKind,
...@@ -434,83 +443,71 @@ class Generator(generator.Generator): ...@@ -434,83 +443,71 @@ class Generator(generator.Generator):
'new_array': NewArray, 'new_array': NewArray,
'ucc': lambda x: UpperCamelCase(x.name), 'ucc': lambda x: UpperCamelCase(x.name),
} }
return java_filters
def GetJinjaExports(self): def _GetJinjaExportsForInterface(self, interface):
return { exports = self._GetJinjaExports()
'package': GetPackage(self.module),
}
@staticmethod
def GetTemplatePrefix():
return "java_templates"
@classmethod
def GetFilters(cls):
return cls.java_filters
def GetJinjaExportsForInterface(self, interface):
exports = self.GetJinjaExports()
exports.update({'interface': interface}) exports.update({'interface': interface})
return exports return exports
@UseJinja('enum.java.tmpl') @UseJinja('enum.java.tmpl')
def GenerateEnumSource(self, enum): def _GenerateEnumSource(self, enum):
exports = self.GetJinjaExports() exports = self._GetJinjaExports()
exports.update({'enum': enum}) exports.update({'enum': enum})
return exports return exports
@UseJinja('struct.java.tmpl') @UseJinja('struct.java.tmpl')
def GenerateStructSource(self, struct): def _GenerateStructSource(self, struct):
exports = self.GetJinjaExports() exports = self._GetJinjaExports()
exports.update({'struct': struct}) exports.update({'struct': struct})
return exports return exports
@UseJinja('union.java.tmpl') @UseJinja('union.java.tmpl')
def GenerateUnionSource(self, union): def _GenerateUnionSource(self, union):
exports = self.GetJinjaExports() exports = self._GetJinjaExports()
exports.update({'union': union}) exports.update({'union': union})
return exports return exports
@UseJinja('interface.java.tmpl') @UseJinja('interface.java.tmpl')
def GenerateInterfaceSource(self, interface): def _GenerateInterfaceSource(self, interface):
return self.GetJinjaExportsForInterface(interface) return self._GetJinjaExportsForInterface(interface)
@UseJinja('interface_internal.java.tmpl') @UseJinja('interface_internal.java.tmpl')
def GenerateInterfaceInternalSource(self, interface): def _GenerateInterfaceInternalSource(self, interface):
return self.GetJinjaExportsForInterface(interface) return self._GetJinjaExportsForInterface(interface)
@UseJinja('constants.java.tmpl') @UseJinja('constants.java.tmpl')
def GenerateConstantsSource(self, module): def _GenerateConstantsSource(self, module):
exports = self.GetJinjaExports() exports = self._GetJinjaExports()
exports.update({'main_entity': GetConstantsMainEntityName(module), exports.update({'main_entity': GetConstantsMainEntityName(module),
'constants': module.constants}) 'constants': module.constants})
return exports return exports
def DoGenerateFiles(self): def _DoGenerateFiles(self):
fileutil.EnsureDirectoryExists(self.output_dir) fileutil.EnsureDirectoryExists(self.output_dir)
# Keep this above the others as .GetStructs() changes the state of the # Keep this above the others as .GetStructs() changes the state of the
# module, annotating structs with required information. # module, annotating structs with required information.
for struct in self.GetStructs(): for struct in self.GetStructs():
self.Write(self.GenerateStructSource(struct), self.Write(self._GenerateStructSource(struct),
'%s.java' % GetNameForElement(struct)) '%s.java' % GetNameForElement(struct))
for union in self.module.unions: for union in self.module.unions:
self.Write(self.GenerateUnionSource(union), self.Write(self._GenerateUnionSource(union),
'%s.java' % GetNameForElement(union)) '%s.java' % GetNameForElement(union))
for enum in self.module.enums: for enum in self.module.enums:
self.Write(self.GenerateEnumSource(enum), self.Write(self._GenerateEnumSource(enum),
'%s.java' % GetNameForElement(enum)) '%s.java' % GetNameForElement(enum))
for interface in self.GetInterfaces(): for interface in self.GetInterfaces():
self.Write(self.GenerateInterfaceSource(interface), self.Write(self._GenerateInterfaceSource(interface),
'%s.java' % GetNameForElement(interface)) '%s.java' % GetNameForElement(interface))
self.Write(self.GenerateInterfaceInternalSource(interface), self.Write(self._GenerateInterfaceInternalSource(interface),
'%s_Internal.java' % GetNameForElement(interface)) '%s_Internal.java' % GetNameForElement(interface))
if self.module.constants: if self.module.constants:
self.Write(self.GenerateConstantsSource(self.module), self.Write(self._GenerateConstantsSource(self.module),
'%s.java' % GetConstantsMainEntityName(self.module)) '%s.java' % GetConstantsMainEntityName(self.module))
def GenerateFiles(self, unparsed_args): def GenerateFiles(self, unparsed_args):
...@@ -529,13 +526,13 @@ class Generator(generator.Generator): ...@@ -529,13 +526,13 @@ class Generator(generator.Generator):
zip_filename = os.path.join(self.output_dir, basename) zip_filename = os.path.join(self.output_dir, basename)
with TempDir() as temp_java_root: with TempDir() as temp_java_root:
self.output_dir = os.path.join(temp_java_root, package_path) self.output_dir = os.path.join(temp_java_root, package_path)
self.DoGenerateFiles(); self._DoGenerateFiles();
build_utils.ZipDir(zip_filename, temp_java_root) build_utils.ZipDir(zip_filename, temp_java_root)
if args.java_output_directory: if args.java_output_directory:
# If requested, generate the java files directly into indicated directory. # If requested, generate the java files directly into indicated directory.
self.output_dir = os.path.join(args.java_output_directory, package_path) self.output_dir = os.path.join(args.java_output_directory, package_path)
self.DoGenerateFiles(); self._DoGenerateFiles();
def GetJinjaParameters(self): def GetJinjaParameters(self):
return { return {
......
...@@ -342,7 +342,25 @@ def GetRelativePath(module, base_module): ...@@ -342,7 +342,25 @@ def GetRelativePath(module, base_module):
class Generator(generator.Generator): class Generator(generator.Generator):
def _GetParameters(self):
return {
"namespace": self.module.namespace,
"imports": self._GetImports(),
"kinds": self.module.kinds,
"enums": self.module.enums,
"module": self.module,
"structs": self.GetStructs() + self.GetStructsFromMethods(),
"unions": self.GetUnions(),
"use_new_js_bindings": self.use_new_js_bindings,
"interfaces": self.GetInterfaces(),
"imported_interfaces": self._GetImportedInterfaces(),
}
@staticmethod
def GetTemplatePrefix():
return "js_templates"
def GetFilters(self):
js_filters = { js_filters = {
"decode_snippet": JavaScriptDecodeSnippet, "decode_snippet": JavaScriptDecodeSnippet,
"default_value": JavaScriptDefaultValue, "default_value": JavaScriptDefaultValue,
...@@ -353,7 +371,8 @@ class Generator(generator.Generator): ...@@ -353,7 +371,8 @@ class Generator(generator.Generator):
"is_any_handle_or_interface_field": IsAnyHandleOrInterfaceField, "is_any_handle_or_interface_field": IsAnyHandleOrInterfaceField,
"is_array_pointer_field": IsArrayPointerField, "is_array_pointer_field": IsArrayPointerField,
"is_associated_interface_field": IsAssociatedInterfaceField, "is_associated_interface_field": IsAssociatedInterfaceField,
"is_associated_interface_request_field": IsAssociatedInterfaceRequestField, "is_associated_interface_request_field":
IsAssociatedInterfaceRequestField,
"is_bool_field": IsBoolField, "is_bool_field": IsBoolField,
"is_enum_field": IsEnumField, "is_enum_field": IsEnumField,
"is_handle_field": IsHandleField, "is_handle_field": IsHandleField,
...@@ -378,41 +397,20 @@ class Generator(generator.Generator): ...@@ -378,41 +397,20 @@ class Generator(generator.Generator):
"validate_struct_params": JavaScriptValidateStructParams, "validate_struct_params": JavaScriptValidateStructParams,
"validate_union_params": JavaScriptValidateUnionParams, "validate_union_params": JavaScriptValidateUnionParams,
} }
return js_filters
def GetParameters(self):
return {
"namespace": self.module.namespace,
"imports": self.GetImports(),
"kinds": self.module.kinds,
"enums": self.module.enums,
"module": self.module,
"structs": self.GetStructs() + self.GetStructsFromMethods(),
"unions": self.GetUnions(),
"use_new_js_bindings": self.use_new_js_bindings,
"interfaces": self.GetInterfaces(),
"imported_interfaces": self.GetImportedInterfaces(),
}
@staticmethod
def GetTemplatePrefix():
return "js_templates"
@classmethod
def GetFilters(cls):
return cls.js_filters
@UseJinja("module.amd.tmpl") @UseJinja("module.amd.tmpl")
def GenerateAMDModule(self): def _GenerateAMDModule(self):
return self.GetParameters() return self._GetParameters()
def GenerateFiles(self, args): def GenerateFiles(self, args):
if self.variant: if self.variant:
raise Exception("Variants not supported in JavaScript bindings.") raise Exception("Variants not supported in JavaScript bindings.")
self.Write(self.GenerateAMDModule(), self.Write(self._GenerateAMDModule(),
self.MatchMojomFilePath("%s.js" % self.module.name)) self.MatchMojomFilePath("%s.js" % self.module.name))
def GetImports(self): def _GetImports(self):
used_names = set() used_names = set()
for each_import in self.module.imports: for each_import in self.module.imports:
simple_name = each_import["module_name"].split(".")[0] simple_name = each_import["module_name"].split(".")[0]
...@@ -430,7 +428,7 @@ class Generator(generator.Generator): ...@@ -430,7 +428,7 @@ class Generator(generator.Generator):
counter += 1 counter += 1
return self.module.imports return self.module.imports
def GetImportedInterfaces(self): def _GetImportedInterfaces(self):
interface_to_import = {}; interface_to_import = {};
for each_import in self.module.imports: for each_import in self.module.imports:
for each_interface in each_import["module"].interfaces: for each_interface in each_import["module"].interfaces:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment