Commit d82bb5b5 authored by Karel Král's avatar Karel Král Committed by Commit Bot

Refactor mojo parameter tracing code into a module

Refactor python code responsible for generating C++ function parameter
tracing of mojo methods into a standalone module.

Bug: 1103623
Change-Id: I39dff196c8227534a6141b0984559e2323ceaaec
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2346808
Commit-Queue: Karel Král <karelkral@google.com>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797586}
parent c3e35c92
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Generates C++ source code to trace mojo method parameters."""
from generators.cpp_util import IsNativeOnlyKind
import mojom.generate.module as mojom
from abc import ABCMeta
from abc import abstractmethod
class _OutputContext(object):
__metaclass__ = ABCMeta
"""Represents the context in which |self.value| should be used.
This is a base class for _ArrayItem, _DictionaryItemWithLiteralKey, and
_DictionaryItemWithCopiedKey. The distinction between _ArrayItem and
_DictionaryItemWithLiteralKey/_DictionaryItemWithCopiedKey is that
_ArrayItem has no name. The distinction between
_DictionaryItemWithLiteralKey and _DictionaryItemWithCopiedKey is whether
the name is expected to be long lived or can be temporary.
"""
def __init__(self, value):
self.value = value
@abstractmethod
def AddSingleValue(self, trace_type, parameter_value):
pass
@abstractmethod
def BeginContainer(self, container_type):
pass
def EndContainer(self, container_type):
"""Return a line of C++ code to close a container on self.value.
Args:
container_type: {string} Either 'Dictionary' or 'Array'.
Returns:
A single line of C++ which closes a container on self.value.
"""
return '%s->End%s();' % (self.value, container_type)
def AsValueInto(self, cpp_expression):
"""Return a line of C++ code to trace a variable to self.value.
Most probably the user of this method wants to yield
|self.BeginContainer('Dictionary')| immediately before and
|self.EndContainer('Dictionary')| immediately after a call to
|AsValueInto| (see documentation of |cpp_expression::AsValueInto|).
Args:
cpp_expression: {string} The C++ expression on which |->AsValueInto|
will be called.
Returns:
A single line of C++ which calls |AsValueInto| on |cpp_expression|
with self.value as the parameter.
"""
return '%s->AsValueInto(%s);' % (cpp_expression, self.value)
def TraceContainer(self, container_type, iterator_name, container_name,
loop_body):
"""Generate the C++ for-loop to trace the container |container_name|.
Args:
container_type: {string} Either 'Array' or 'Dictionary'.
iterator_name: {string} The iterator variable name to be used.
container_name: {string} The name of the variable holding the container.
loop_body: {iterable} Lines of C++ code that trace individual elements.
Yields:
Lines of C++ for-loop to trace the container.
"""
yield self.BeginContainer(container_type)
yield 'for (const auto& %s : %s) {' % (iterator_name, container_name)
for line in loop_body:
yield ' ' + line
yield '}'
yield self.EndContainer(container_type)
class _ArrayItem(_OutputContext):
"""Represents a |TracedValue| which expects to receive an array item (of no
name). This means that |AddSingleValue| will return a call on self.value
which is an Append and |BeginContainer| will start a container with no
name.
Attributes:
value: {string} The name of the C++ variable of type
|base::trace_event::TracedValue*| this object represents.
"""
def __init__(self, value):
super(_ArrayItem, self).__init__(value)
def AddSingleValue(self, trace_type, parameter_value):
"""Return a line of C++ code that will append a single value to
|self.value|.
Args:
trace_type: {string} The type of the appended value. Can be one of:
'Integer', 'Double', 'Boolean', 'String'.
parameter_value: {string} The C++ expression to be passed as the
appended value.
Returns:
A single line of C++ which appends |parameter_value| to self.value.
"""
return '%s->Append%s(%s);' % (self.value, trace_type, parameter_value)
def BeginContainer(self, container_type):
"""Return a line of C++ code to open a container on self.value.
Args:
container_type: {string} Either 'Dictionary' or 'Array'.
Returns:
A single line of C++ which starts a container on self.value.
"""
return '%s->Begin%s();' % (self.value, container_type)
class _DictionaryItemWithLiteralKey(_OutputContext):
"""Represents a |TracedValue| which expects to receive a dictionary item
(with a long lived name). This means that |AddSingleValue| will return a
call on self.value which is a Set and |BeginContainer| will start a
container with self.name used in a string literal.
|base::trace_event::TracedValue| has two sets of methods -- ones with copied
name and ones with long lived name. This class corresponds to using the long
lived name.
_DictionaryItemWithLiteralKey generates calls on
|base::trace_event::TracedValue| which do not copy the name (assume that
the used name is long lived. Thus self.name is used inside a "quoted" long
lived string.
Attributes:
value: {string} The name of the C++ variable of type
|base::trace_event::TracedValue*| this object represents.
name: {string} The name of the mojo variable that is currently being
traced. Used inside double-quotes in method calls.
"""
def __init__(self, name, value):
super(_DictionaryItemWithLiteralKey, self).__init__(value)
self.name = name
def AddSingleValue(self, trace_type, parameter_value):
"""Return a line of C++ code that will set a single value to |self.value|.
Uses |self.name| inside a "quoted" string.
Args:
trace_type: {string} The type of the set value. Can be one of:
'Integer', 'Double', 'Boolean', 'String', 'Value'.
parameter_value: {string} The C++ expression to be passed as the
set value.
Returns:
A single line of C++ that sets |parameter_value| of name |"self.name"|
on self.value.
"""
return '%s->Set%s("%s", %s);' % (self.value, trace_type, self.name,
parameter_value)
def BeginContainer(self, container_type):
return '%s->Begin%s("%s");' % (self.value, container_type, self.name)
class _DictionaryItemWithCopiedKey(_OutputContext):
"""Represents a |TracedValue| which expects to receive a dictionary item
(with a name which is a temporary string). This means that
|AddSingleValue| will return a call on self.value which is an
SetXWithCopiedName and |BeginContainer| will start a container with
self.name used as a temporary string.
|base::trace_event::TracedValue| has two sets of methods -- ones with copied
name and ones with long lived name. This class corresponds to using the
copied name.
_DictionaryItemWithCopiedKey generates calls on
|base::trace_event::TracedValue| which do copy the name (assume that
self.name is a C++ expression evaluating to a temporary string).
Attributes:
value: {string} The name of the C++ variable of type
|base::trace_event::TracedValue*| this object represents.
name: {string} The name of the mojo variable that is currently being
traced. Used directly (not in double quotes) in method calls.
"""
def __init__(self, name, value):
super(_DictionaryItemWithCopiedKey, self).__init__(value)
self.name = name
def AddSingleValue(self, trace_type, parameter_value):
"""Return a line of C++ code that will set a single value to |self.value|.
Uses |self.name| directly as a parameter that is expected to be copied
(can be a temporary string).
Args:
trace_type: {string} The type of the set value. Can be one of:
'Integer', 'Double', 'Boolean', 'String', 'Value'.
parameter_value: {string} The C++ expression to be passed as the
set value.
Returns:
A single line of C++ that sets |parameter_value| of name |self.name|
on self.value (with copied name).
"""
return '%s->Set%sWithCopiedName(%s, %s);' % (self.value, trace_type,
self.name, parameter_value)
def BeginContainer(self, container_type):
return '%s->Begin%sWithCopiedName(%s);' % (self.value, container_type,
self.name)
def _WriteInputParamForTracingImpl(generator, kind, cpp_parameter_name,
output_context):
"""Generates lines of C++ to log a parameter into TracedValue
|output_context.value|. Use |output_context.name| if |output_context| is of
inhereted type from _OutputContext.
Args:
kind: {Kind} The kind of the parameter (corresponds to its C++ type).
cpp_parameter_name: {string} The actual C++ variable name corresponding to
the mojom parameter |parameter_name|. Can be a valid C++ expression
(e.g., dereferenced variable |"(*var)"|).
output_context: {_OutputContext} Represents the TracedValue* variable to be
written into. Possibly also holds the mojo parameter name corresponding to
|cpp_parameter_name|.
Yields:
{string} C++ lines of code that trace a |cpp_parameter_name| into
|output_context.value|.
"""
def _WrapIfNullable(inner_lines):
"""Check if kind is nullable if so yield code to check whether it has
value.
Args:
inner_lines: {function} Function taking single argument and returning
iterable. If kind is nullable, yield from this method with
|cpp_parameter_name+'.value()'| otherwise yield with the parameter
|cpp_parameter_name|.
Args from the surrounding method:
kind
cpp_parameter_name
output_context.AddSingleValue
"""
if mojom.IsNullableKind(kind):
yield 'if (%s.has_value()) {' % cpp_parameter_name
for line in inner_lines(cpp_parameter_name + '.value()'):
yield ' ' + line
yield '} else {'
yield ' ' + output_context.AddSingleValue('String', '"base::nullopt"')
yield '}'
else:
# |yield from| is introduced in Python3.3.
for line in inner_lines(cpp_parameter_name):
yield line
# TODO(crbug.com/1103623): Support more involved types.
if mojom.IsEnumKind(kind):
if generator._IsTypemappedKind(kind) or IsNativeOnlyKind(kind):
yield output_context.AddSingleValue(
'Integer', 'static_cast<int>(%s)' % cpp_parameter_name)
else:
yield output_context.AddSingleValue(
'String', 'base::trace_event::ValueToString(%s)' % cpp_parameter_name)
return
if mojom.IsStringKind(kind):
if generator.for_blink:
# WTF::String is nullable on its own.
yield output_context.AddSingleValue('String',
'%s.Utf8()' % cpp_parameter_name)
return
# The type might be base::Optional<std::string> or std::string.
for line in _WrapIfNullable(lambda cpp_parameter_name: [
output_context.AddSingleValue('String', cpp_parameter_name)
]):
yield line
return
if kind == mojom.BOOL:
yield output_context.AddSingleValue('Boolean', cpp_parameter_name)
return
# TODO(crbug.com/1103623): Make TracedValue support int64_t, then move to
# mojom.IsIntegralKind.
if kind in [mojom.INT8, mojom.UINT8, mojom.INT16, mojom.UINT16, mojom.INT32]:
# Parameter is representable as 32bit int.
yield output_context.AddSingleValue('Integer', cpp_parameter_name)
return
if kind in [mojom.UINT32, mojom.INT64, mojom.UINT64]:
yield output_context.AddSingleValue(
'String', 'base::NumberToString(%s)' % cpp_parameter_name)
return
if mojom.IsFloatKind(kind) or mojom.IsDoubleKind(kind):
yield output_context.AddSingleValue('Double', cpp_parameter_name)
return
if (mojom.IsStructKind(kind) and not generator._IsTypemappedKind(kind)
and not IsNativeOnlyKind(kind)):
yield 'if (%s.is_null()) {' % cpp_parameter_name
yield ' ' + output_context.AddSingleValue('String', '"nullptr"')
yield '} else {'
yield ' ' + output_context.BeginContainer('Dictionary')
yield ' ' + output_context.AsValueInto(cpp_parameter_name)
yield ' ' + output_context.EndContainer('Dictionary')
yield '}'
return
if mojom.IsArrayKind(kind):
iterator_name = 'item'
loop_body = _WriteInputParamForTracingImpl(generator=generator,
kind=kind.kind,
cpp_parameter_name=iterator_name,
output_context=_ArrayItem(
output_context.value))
loop_generator = lambda cpp_parameter_name: output_context.TraceContainer(
container_type='Array',
iterator_name=iterator_name,
container_name=cpp_parameter_name,
loop_body=loop_body)
# Array might be a nullable kind.
for line in _WrapIfNullable(loop_generator):
yield line
return
def _TraceEventToString(cpp_parameter_name=cpp_parameter_name, kind=kind):
return 'base::trace_event::ValueToString(%s, "<value of type %s>")' % (
cpp_parameter_name, generator._GetCppWrapperParamType(kind))
if mojom.IsMapKind(kind):
iterator_name = 'item'
if generator.for_blink:
# WTF::HashMap<,>
key_access = '.key'
value_access = '.value'
else:
# base::flat_map<,>
key_access = '.first'
value_access = '.second'
loop_body = _WriteInputParamForTracingImpl(
generator=generator,
kind=kind.value_kind,
cpp_parameter_name=iterator_name + value_access,
output_context=_DictionaryItemWithCopiedKey(
value=output_context.value,
name=_TraceEventToString(cpp_parameter_name=iterator_name +
key_access,
kind=kind.key_kind)))
loop_generator = lambda cpp_parameter_name: output_context.TraceContainer(
container_type="Dictionary",
iterator_name=iterator_name,
container_name=cpp_parameter_name,
loop_body=loop_body)
# Dictionary might be a nullable kind.
for line in _WrapIfNullable(loop_generator):
yield line
return
yield output_context.AddSingleValue('String', _TraceEventToString())
def WriteInputParamForTracing(generator, kind, parameter_name,
cpp_parameter_name, value):
"""Generates lines of C++ to log parameter |parameter_name| into TracedValue
|value|.
Args:
kind: {Kind} The kind of the parameter (corresponds to its C++ type).
cpp_parameter_name: {string} The actual C++ variable name corresponding to
the mojom parameter |parameter_name|. Can be a valid C++ expression
(e.g., dereferenced variable |"(*var)"|).
value: {string} The C++ |TracedValue*| variable name to be logged into.
Yields:
{string} C++ lines of code that trace |parameter_name| into |value|.
"""
for line in _WriteInputParamForTracingImpl(
generator=generator,
kind=kind,
cpp_parameter_name=cpp_parameter_name,
output_context=_DictionaryItemWithLiteralKey(name=parameter_name,
value=value)):
yield line
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Implement the common methods used in mojom_cpp_generator.py and
mojom_cpp_parameter_tracing.py in order to get rid of circular dependency."""
import mojom.generate.module as mojom
def IsNativeOnlyKind(kind):
return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \
kind.native_only
...@@ -7,8 +7,8 @@ import os ...@@ -7,8 +7,8 @@ import os
import mojom.generate.generator as generator import mojom.generate.generator as generator
import mojom.generate.module as mojom import mojom.generate.module as mojom
import mojom.generate.pack as pack import mojom.generate.pack as pack
from abc import ABCMeta from generators.cpp_util import IsNativeOnlyKind
from abc import abstractmethod from generators.cpp_tracing_support import WriteInputParamForTracing
from mojom.generate.template_expander import UseJinja, UseJinjaForImportedTemplate from mojom.generate.template_expander import UseJinja, UseJinjaForImportedTemplate
...@@ -139,11 +139,6 @@ def GetEnumNameWithoutNamespace(enum): ...@@ -139,11 +139,6 @@ def GetEnumNameWithoutNamespace(enum):
return full_enum_name.split("::")[-1] return full_enum_name.split("::")[-1]
def IsNativeOnlyKind(kind):
return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \
kind.native_only
def UseCustomSerializer(kind): def UseCustomSerializer(kind):
return mojom.IsStructKind(kind) and kind.custom_serializer return mojom.IsStructKind(kind) and kind.custom_serializer
...@@ -670,358 +665,6 @@ class Generator(generator.Generator): ...@@ -670,358 +665,6 @@ class Generator(generator.Generator):
GetCppPodType(constant.kind), constant.name, GetCppPodType(constant.kind), constant.name,
self._ConstantValue(constant)) self._ConstantValue(constant))
class _OutputContext(object):
__metaclass__ = ABCMeta
"""Represents the context in which |self.value| should be used.
This is a base class for _ArrayItem, _DictionaryItemWithLiteralKey, and
_DictionaryItemWithCopiedKey. The distinction between _ArrayItem and
_DictionaryItemWithLiteralKey/_DictionaryItemWithCopiedKey is that
_ArrayItem has no name. The distinction between
_DictionaryItemWithLiteralKey and _DictionaryItemWithCopiedKey is whether
the name is expected to be long lived or can be temporary.
"""
def __init__(self, value):
self.value = value
@abstractmethod
def AddSingleValue(self, trace_type, parameter_value):
pass
@abstractmethod
def BeginContainer(self, container_type):
pass
def EndContainer(self, container_type):
"""Return a line of C++ code to close a container on self.value.
Args:
container_type: {string} Either 'Dictionary' or 'Array'.
Returns:
A single line of C++ which closes a container on self.value.
"""
return '%s->End%s();' % (self.value, container_type)
def AsValueInto(self, cpp_expression):
"""Return a line of C++ code to trace a variable to self.value.
Most probably the user of this method wants to yield
|self.BeginContainer('Dictionary')| immediately before and
|self.EndContainer('Dictionary')| immediately after a call to
|AsValueInto| (see documentation of |cpp_expression::AsValueInto|).
Args:
cpp_expression: {string} The C++ expression on which |->AsValueInto|
will be called.
Returns:
A single line of C++ which calls |AsValueInto| on |cpp_expression|
with self.value as the parameter.
"""
return '%s->AsValueInto(%s);' % (cpp_expression, self.value)
def TraceContainer(self, container_type, iterator_name, container_name,
loop_body):
"""Generate the C++ for-loop to trace the container |container_name|.
Args:
container_type: {string} Either 'Array' or 'Dictionary'.
iterator_name: {string} The iterator variable name to be used.
container_name: {string} The name of the variable holding the container.
loop_body: {iterable} Lines of C++ code that trace individual elements.
Yields:
Lines of C++ for-loop to trace the container.
"""
yield self.BeginContainer(container_type)
yield 'for (const auto& %s : %s) {' % (iterator_name, container_name)
for line in loop_body:
yield ' ' + line
yield '}'
yield self.EndContainer(container_type)
class _ArrayItem(_OutputContext):
"""Represents a |TracedValue| which expects to receive an array item (of no
name). This means that |AddSingleValue| will return a call on self.value
which is an Append and |BeginContainer| will start a container with no
name.
Attributes:
value: {string} The name of the C++ variable of type
|base::trace_event::TracedValue*| this object represents.
"""
def __init__(self, value):
super(Generator._ArrayItem, self).__init__(value)
def AddSingleValue(self, trace_type, parameter_value):
"""Return a line of C++ code that will append a single value to
|self.value|.
Args:
trace_type: {string} The type of the appended value. Can be one of:
'Integer', 'Double', 'Boolean', 'String'.
parameter_value: {string} The C++ expression to be passed as the
appended value.
Returns:
A single line of C++ which appends |parameter_value| to self.value.
"""
return '%s->Append%s(%s);' % (self.value, trace_type, parameter_value)
def BeginContainer(self, container_type):
"""Return a line of C++ code to open a container on self.value.
Args:
container_type: {string} Either 'Dictionary' or 'Array'.
Returns:
A single line of C++ which starts a container on self.value.
"""
return '%s->Begin%s();' % (self.value, container_type)
class _DictionaryItemWithLiteralKey(_OutputContext):
"""Represents a |TracedValue| which expects to receive a dictionary item
(with a long lived name). This means that |AddSingleValue| will return a
call on self.value which is a Set and |BeginContainer| will start a
container with self.name used in a string literal.
|base::trace_event::TracedValue| has two sets of methods -- ones with copied
name and ones with long lived name. This class corresponds to using the long
lived name.
_DictionaryItemWithLiteralKey generates calls on
|base::trace_event::TracedValue| which do not copy the name (assume that
the used name is long lived. Thus self.name is used inside a "quoted" long
lived string.
Attributes:
value: {string} The name of the C++ variable of type
|base::trace_event::TracedValue*| this object represents.
name: {string} The name of the mojo variable that is currently being
traced. Used inside double-quotes in method calls.
"""
def __init__(self, name, value):
super(Generator._DictionaryItemWithLiteralKey, self).__init__(value)
self.name = name
def AddSingleValue(self, trace_type, parameter_value):
"""Return a line of C++ code that will set a single value to |self.value|.
Uses |self.name| inside a "quoted" string.
Args:
trace_type: {string} The type of the set value. Can be one of:
'Integer', 'Double', 'Boolean', 'String', 'Value'.
parameter_value: {string} The C++ expression to be passed as the
set value.
Returns:
A single line of C++ that sets |parameter_value| of name |"self.name"|
on self.value.
"""
return '%s->Set%s("%s", %s);' % (self.value, trace_type, self.name,
parameter_value)
def BeginContainer(self, container_type):
return '%s->Begin%s("%s");' % (self.value, container_type, self.name)
class _DictionaryItemWithCopiedKey(_OutputContext):
"""Represents a |TracedValue| which expects to receive a dictionary item
(with a name which is a temporary string). This means that
|AddSingleValue| will return a call on self.value which is an
SetXWithCopiedName and |BeginContainer| will start a container with
self.name used as a temporary string.
|base::trace_event::TracedValue| has two sets of methods -- ones with copied
name and ones with long lived name. This class corresponds to using the
copied name.
_DictionaryItemWithCopiedKey generates calls on
|base::trace_event::TracedValue| which do copy the name (assume that
self.name is a C++ expression evaluating to a temporary string).
Attributes:
value: {string} The name of the C++ variable of type
|base::trace_event::TracedValue*| this object represents.
name: {string} The name of the mojo variable that is currently being
traced. Used directly (not in double quotes) in method calls.
"""
def __init__(self, name, value):
super(Generator._DictionaryItemWithCopiedKey, self).__init__(value)
self.name = name
def AddSingleValue(self, trace_type, parameter_value):
"""Return a line of C++ code that will set a single value to |self.value|.
Uses |self.name| directly as a parameter that is expected to be copied
(can be a temporary string).
Args:
trace_type: {string} The type of the set value. Can be one of:
'Integer', 'Double', 'Boolean', 'String', 'Value'.
parameter_value: {string} The C++ expression to be passed as the
set value.
Returns:
A single line of C++ that sets |parameter_value| of name |self.name|
on self.value (with copied name).
"""
return '%s->Set%sWithCopiedName(%s, %s);' % (self.value, trace_type,
self.name, parameter_value)
def BeginContainer(self, container_type):
return '%s->Begin%sWithCopiedName(%s);' % (self.value, container_type,
self.name)
def _WriteInputParamForTracingImpl(self, kind, cpp_parameter_name,
output_context):
"""Generates lines of C++ to log a parameter into TracedValue
|output_context.value|. Use |output_context.name| if |output_context| is of
inhereted type from Generator._OutputContext.
Args:
kind: {Kind} The kind of the parameter (corresponds to its C++ type).
cpp_parameter_name: {string} The actual C++ variable name corresponding to
the mojom parameter |parameter_name|. Can be a valid C++ expression
(e.g., dereferenced variable |"(*var)"|).
output_context: {Generator._OutputContext} Represents the TracedValue*
variable to be written into. Possibly also holds the mojo parameter name
corresponding to |cpp_parameter_name|.
Yields:
{string} C++ lines of code that trace a |cpp_parameter_name| into
|output_context.value|.
"""
def _WrapIfNullable(inner_lines):
"""Check if kind is nullable if so yield code to check whether it has
value.
Args:
inner_lines: {function} Function taking single argument and returning
iterable. If kind is nullable, yield from this method with
|cpp_parameter_name+'.value()'| otherwise yield with the parameter
|cpp_parameter_name|.
Args from the surrounding method:
kind
cpp_parameter_name
output_context.AddSingleValue
"""
if mojom.IsNullableKind(kind):
yield 'if (%s.has_value()) {' % cpp_parameter_name
for line in inner_lines(cpp_parameter_name + '.value()'):
yield ' ' + line
yield '} else {'
yield ' ' + output_context.AddSingleValue('String', '"base::nullopt"')
yield '}'
else:
# |yield from| is introduced in Python3.3.
for line in inner_lines(cpp_parameter_name):
yield line
# TODO(crbug.com/1103623): Support more involved types.
if mojom.IsEnumKind(kind):
if self._IsTypemappedKind(kind) or IsNativeOnlyKind(kind):
yield output_context.AddSingleValue(
'Integer', 'static_cast<int>(%s)' % cpp_parameter_name)
else:
yield output_context.AddSingleValue(
'String',
'base::trace_event::ValueToString(%s)' % cpp_parameter_name)
return
if mojom.IsStringKind(kind):
if self.for_blink:
# WTF::String is nullable on its own.
yield output_context.AddSingleValue('String',
'%s.Utf8()' % cpp_parameter_name)
return
# The type might be base::Optional<std::string> or std::string.
for line in _WrapIfNullable(lambda cpp_parameter_name: [
output_context.AddSingleValue('String', cpp_parameter_name)
]):
yield line
return
if kind == mojom.BOOL:
yield output_context.AddSingleValue('Boolean', cpp_parameter_name)
return
# TODO(crbug.com/1103623): Make TracedValue support int64_t, then move to
# mojom.IsIntegralKind.
if kind in [
mojom.INT8, mojom.UINT8, mojom.INT16, mojom.UINT16, mojom.INT32
]:
# Parameter is representable as 32bit int.
yield output_context.AddSingleValue('Integer', cpp_parameter_name)
return
if kind in [mojom.UINT32, mojom.INT64, mojom.UINT64]:
yield output_context.AddSingleValue(
'String', 'base::NumberToString(%s)' % cpp_parameter_name)
return
if mojom.IsFloatKind(kind) or mojom.IsDoubleKind(kind):
yield output_context.AddSingleValue('Double', cpp_parameter_name)
return
if (mojom.IsStructKind(kind) and not self._IsTypemappedKind(kind)
and not IsNativeOnlyKind(kind)):
yield 'if (%s.is_null()) {' % cpp_parameter_name
yield ' ' + output_context.AddSingleValue('String', '"nullptr"')
yield '} else {'
yield ' ' + output_context.BeginContainer('Dictionary')
yield ' ' + output_context.AsValueInto(cpp_parameter_name)
yield ' ' + output_context.EndContainer('Dictionary')
yield '}'
return
if mojom.IsArrayKind(kind):
iterator_name = 'item'
loop_body = self._WriteInputParamForTracingImpl(
kind=kind.kind,
cpp_parameter_name=iterator_name,
output_context=Generator._ArrayItem(output_context.value))
loop_generator = lambda cpp_parameter_name: output_context.TraceContainer(
container_type='Array',
iterator_name=iterator_name,
container_name=cpp_parameter_name,
loop_body=loop_body)
# Array might be a nullable kind.
for line in _WrapIfNullable(loop_generator):
yield line
return
def _TraceEventToString(cpp_parameter_name=cpp_parameter_name, kind=kind):
return 'base::trace_event::ValueToString(%s, "<value of type %s>")' % (
cpp_parameter_name, self._GetCppWrapperParamType(kind))
if mojom.IsMapKind(kind):
iterator_name = 'item'
if self.for_blink:
# WTF::HashMap<,>
key_access = '.key'
value_access = '.value'
else:
# base::flat_map<,>
key_access = '.first'
value_access = '.second'
loop_body = self._WriteInputParamForTracingImpl(
kind=kind.value_kind,
cpp_parameter_name=iterator_name + value_access,
output_context=Generator._DictionaryItemWithCopiedKey(
value=output_context.value,
name=_TraceEventToString(cpp_parameter_name=iterator_name +
key_access,
kind=kind.key_kind)))
loop_generator = lambda cpp_parameter_name: output_context.TraceContainer(
container_type="Dictionary",
iterator_name=iterator_name,
container_name=cpp_parameter_name,
loop_body=loop_body)
# Dictionary might be a nullable kind.
for line in _WrapIfNullable(loop_generator):
yield line
return
yield output_context.AddSingleValue('String', _TraceEventToString())
def _WriteInputParamForTracing(self, kind, parameter_name, cpp_parameter_name, def _WriteInputParamForTracing(self, kind, parameter_name, cpp_parameter_name,
value): value):
"""Generates lines of C++ to log parameter |parameter_name| into TracedValue """Generates lines of C++ to log parameter |parameter_name| into TracedValue
...@@ -1037,11 +680,11 @@ class Generator(generator.Generator): ...@@ -1037,11 +680,11 @@ class Generator(generator.Generator):
Yields: Yields:
{string} C++ lines of code that trace |parameter_name| into |value|. {string} C++ lines of code that trace |parameter_name| into |value|.
""" """
for line in self._WriteInputParamForTracingImpl( for line in WriteInputParamForTracing(generator=self,
kind=kind, kind=kind,
cpp_parameter_name=cpp_parameter_name, parameter_name=parameter_name,
output_context=Generator._DictionaryItemWithLiteralKey( cpp_parameter_name=cpp_parameter_name,
name=parameter_name, value=value)): value=value):
yield line yield line
def _GetCppWrapperType(self, def _GetCppWrapperType(self,
......
...@@ -93,7 +93,9 @@ mojom_generator_root = "$_mojom_tools_root/bindings" ...@@ -93,7 +93,9 @@ mojom_generator_root = "$_mojom_tools_root/bindings"
mojom_generator_script = "$mojom_generator_root/mojom_bindings_generator.py" mojom_generator_script = "$mojom_generator_root/mojom_bindings_generator.py"
mojom_generator_sources = mojom_generator_sources =
mojom_parser_sources + [ mojom_parser_sources + [
"$mojom_generator_root/generators/cpp_util.py",
"$mojom_generator_root/generators/mojom_cpp_generator.py", "$mojom_generator_root/generators/mojom_cpp_generator.py",
"$mojom_generator_root/generators/cpp_tracing_support.py",
"$mojom_generator_root/generators/mojom_java_generator.py", "$mojom_generator_root/generators/mojom_java_generator.py",
"$mojom_generator_root/generators/mojom_mojolpm_generator.py", "$mojom_generator_root/generators/mojom_mojolpm_generator.py",
"$mojom_generator_root/generators/mojom_js_generator.py", "$mojom_generator_root/generators/mojom_js_generator.py",
......
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