Commit 980a58e4 authored by Ken Rockot's avatar Ken Rockot Committed by Commit Bot

Apply Python formatting to mojom library

This is strictly a formatting change, generated by manually running yapf
over the affected files. It's a precursor to a subsequent move and minor
refactoring of this code, as modified files will always get yapf applied
and that would otherwise create a lot of noise in the coming CLs.

Bug: 1060467
Change-Id: I188ac6cc71fda2cd08a6f4695f67c5c0f04d2737
Tbr: oksamyt@chromium.org
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2098265Reviewed-by: default avatarKen Rockot <rockot@google.com>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#749272}
parent 515438bc
......@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
class Error(Exception):
"""Base class for Mojo IDL bindings parser/generator errors."""
......
......@@ -5,6 +5,7 @@
import errno
import os.path
def EnsureDirectoryExists(path, always_try_to_create=False):
"""A wrapper for os.makedirs that does not error if the directory already
exists. A different process could be racing to create this directory."""
......
# Copyright 2015 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.
"""Resolves the values used for constants and enums."""
from itertools import ifilter
import mojom.generate.module as mojom
def ResolveConstants(module, expression_to_text):
in_progress = set()
computed = set()
......@@ -14,7 +14,8 @@ def ResolveConstants(module, expression_to_text):
def GetResolvedValue(named_value):
assert isinstance(named_value, (mojom.EnumValue, mojom.ConstantValue))
if isinstance(named_value, mojom.EnumValue):
field = next(ifilter(lambda field: field.name == named_value.name,
field = next(
ifilter(lambda field: field.name == named_value.name,
named_value.enum.fields), None)
if not field:
raise RuntimeError(
......
# Copyright 2013 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.
"""Code shared by the various language-specific code generators."""
from __future__ import print_function
......@@ -35,6 +34,7 @@ def SplitCamelCase(identifier):
identifier = re.sub('([a-z][0-9]*)(?=[A-Z])', r'\1_', identifier)
return [x.lower() for x in identifier.split('_')]
def ToCamel(identifier, lower_initial=False, dilimiter='_'):
"""Splits |identifier| using |dilimiter|, makes the first character of each
word uppercased (but makes the first character of the first word lowercased
......@@ -47,6 +47,7 @@ def ToCamel(identifier, lower_initial=False, dilimiter='_'):
result = result[0].lower() + result[1:]
return result
def ToConstantCase(identifier):
"""Splits camel-cased |identifier| into lower case words, removes the first
word if it's "k" and joins them using "_" e.g. for "URLLoaderFactory", returns
......@@ -62,6 +63,7 @@ def ToConstantCase(identifier):
return '_'.join([word.upper() for word in words])
class Stylizer(object):
"""Stylizers specify naming rules to map mojom names to names in generated
code. For example, if you would like method_name in mojom to be mapped to
......@@ -167,7 +169,10 @@ def AddComputedData(module):
method.mojom_name)
struct = mojom.Struct(params_class, module=method.interface.module)
for param in method.parameters:
struct.AddField(param.mojom_name, param.kind, param.ordinal,
struct.AddField(
param.mojom_name,
param.kind,
param.ordinal,
attributes=param.attributes)
_AddStructComputedData(False, struct)
return struct
......@@ -178,7 +183,10 @@ def AddComputedData(module):
method.mojom_name)
struct = mojom.Struct(params_class, module=method.interface.module)
for param in method.response_parameters:
struct.AddField(param.mojom_name, param.kind, param.ordinal,
struct.AddField(
param.mojom_name,
param.kind,
param.ordinal,
attributes=param.attributes)
_AddStructComputedData(False, struct)
return struct
......@@ -194,15 +202,24 @@ def AddComputedData(module):
class Generator(object):
# Pass |output_dir| to emit files to disk. Omit |output_dir| to echo all
# files to stdout.
def __init__(self, module, output_dir=None, typemap=None, variant=None,
bytecode_path=None, for_blink=False,
def __init__(self,
module,
output_dir=None,
typemap=None,
variant=None,
bytecode_path=None,
for_blink=False,
js_bindings_mode="new",
js_generate_struct_deserializers=False,
export_attribute=None,
export_header=None, generate_non_variant_code=False,
support_lazy_serialization=False, disallow_native_types=False,
disallow_interfaces=False, generate_message_ids=False,
generate_fuzzing=False, enable_kythe_annotations=False,
export_header=None,
generate_non_variant_code=False,
support_lazy_serialization=False,
disallow_native_types=False,
disallow_interfaces=False,
generate_message_ids=False,
generate_fuzzing=False,
enable_kythe_annotations=False,
extra_cpp_template_paths=None):
self.module = module
self.output_dir = output_dir
......
......@@ -14,6 +14,7 @@ import mojom.generate.module as mojom
# Size of struct header in bytes: num_bytes [4B] + version [4B].
HEADER_SIZE = 8
class PackedField(object):
kind_to_size = {
mojom.BOOL: 1,
......@@ -45,16 +46,17 @@ class PackedField(object):
@classmethod
def GetSizeForKind(cls, kind):
if isinstance(kind, (mojom.Array, mojom.Map, mojom.Struct,
mojom.Interface, mojom.AssociatedInterface,
mojom.PendingRemote, mojom.PendingAssociatedRemote)):
if isinstance(kind, (mojom.Array, mojom.Map, mojom.Struct, mojom.Interface,
mojom.AssociatedInterface, mojom.PendingRemote,
mojom.PendingAssociatedRemote)):
return 8
if isinstance(kind, mojom.Union):
return 16
if isinstance(kind, (mojom.InterfaceRequest, mojom.PendingReceiver)):
kind = mojom.MSGPIPE
if isinstance(kind, (mojom.AssociatedInterfaceRequest,
mojom.PendingAssociatedReceiver)):
if isinstance(
kind,
(mojom.AssociatedInterfaceRequest, mojom.PendingAssociatedReceiver)):
return 4
if isinstance(kind, mojom.Enum):
# TODO(mpcomplete): what about big enums?
......@@ -98,9 +100,8 @@ def GetPad(offset, alignment):
def GetFieldOffset(field, last_field):
"""Returns a 2-tuple of the field offset and bit (for BOOLs)."""
if (field.field.kind == mojom.BOOL and
last_field.field.kind == mojom.BOOL and
last_field.bit < 7):
if (field.field.kind == mojom.BOOL and last_field.field.kind == mojom.BOOL
and last_field.bit < 7):
return (last_field.offset, last_field.bit + 1)
offset = last_field.offset + last_field.size
......@@ -152,12 +153,12 @@ class PackedStruct(object):
next_min_version = packed_field.field.min_version
packed_field.min_version = next_min_version
if (packed_field.min_version != 0 and
mojom.IsReferenceKind(packed_field.field.kind) and
not packed_field.field.kind.is_nullable):
if (packed_field.min_version != 0
and mojom.IsReferenceKind(packed_field.field.kind)
and not packed_field.field.kind.is_nullable):
raise Exception("Non-nullable fields are only allowed in version 0 of "
"a struct. %s.%s is defined with [MinVersion=%d]."
% (self.struct.name, packed_field.field.name,
"a struct. %s.%s is defined with [MinVersion=%d]." %
(self.struct.name, packed_field.field.name,
packed_field.min_version))
src_field = src_fields[0]
......@@ -247,10 +248,11 @@ def GetVersionInfo(packed_struct):
# The fields are iterated in ordinal order here. However, the size of a
# version is determined by the last field of that version in pack order,
# instead of ordinal order. Therefore, we need to calculate the max value.
last_payload_size = max(GetPayloadSizeUpToField(packed_field),
last_payload_size)
last_payload_size = max(
GetPayloadSizeUpToField(packed_field), last_payload_size)
assert len(versions) == 0 or last_num_fields != versions[-1].num_fields
versions.append(VersionInfo(last_version, last_num_fields,
versions.append(
VersionInfo(last_version, last_num_fields,
last_payload_size + HEADER_SIZE))
return versions
......@@ -16,57 +16,66 @@ import jinja2
def ApplyTemplate(mojo_generator, path_to_template, params, **kwargs):
loader = jinja2.ModuleLoader(os.path.join(
mojo_generator.bytecode_path, "%s.zip" % mojo_generator.GetTemplatePrefix(
)))
loader = jinja2.ModuleLoader(
os.path.join(mojo_generator.bytecode_path,
"%s.zip" % mojo_generator.GetTemplatePrefix()))
final_kwargs = dict(mojo_generator.GetJinjaParameters())
final_kwargs.update(kwargs)
jinja_env = jinja2.Environment(loader=loader,
keep_trailing_newline=True,
**final_kwargs)
jinja_env = jinja2.Environment(
loader=loader, keep_trailing_newline=True, **final_kwargs)
jinja_env.globals.update(mojo_generator.GetGlobals())
jinja_env.filters.update(mojo_generator.GetFilters())
template = jinja_env.get_template(path_to_template)
return template.render(params)
def UseJinja(path_to_template, **kwargs):
def RealDecorator(generator):
def GeneratorInternal(*args, **kwargs2):
parameters = generator(*args, **kwargs2)
return ApplyTemplate(args[0], path_to_template, parameters, **kwargs)
GeneratorInternal.__name__ = generator.__name__
return GeneratorInternal
return RealDecorator
def ApplyImportedTemplate(mojo_generator, path_to_template, filename, params, **kwargs):
def ApplyImportedTemplate(mojo_generator, path_to_template, filename, params,
**kwargs):
loader = jinja2.FileSystemLoader(searchpath=path_to_template)
final_kwargs = dict(mojo_generator.GetJinjaParameters())
final_kwargs.update(kwargs)
jinja_env = jinja2.Environment(loader=loader,
keep_trailing_newline=True,
**final_kwargs)
jinja_env = jinja2.Environment(
loader=loader, keep_trailing_newline=True, **final_kwargs)
jinja_env.globals.update(mojo_generator.GetGlobals())
jinja_env.filters.update(mojo_generator.GetFilters())
template = jinja_env.get_template(filename)
return template.render(params)
def UseJinjaForImportedTemplate(func):
def wrapper(*args, **kwargs):
parameters = func(*args, **kwargs)
path_to_template = args[1]
filename = args[2]
return ApplyImportedTemplate(args[0], path_to_template, filename, parameters)
return ApplyImportedTemplate(args[0], path_to_template, filename,
parameters)
wrapper.__name__ = func.__name__
return wrapper
def PrecompileTemplates(generator_modules, output_dir):
for module in generator_modules.values():
generator = module.Generator(None)
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader([os.path.join(
os.path.dirname(module.__file__), generator.GetTemplatePrefix())]))
jinja_env = jinja2.Environment(
loader=jinja2.FileSystemLoader([
os.path.join(
os.path.dirname(module.__file__), generator.GetTemplatePrefix())
]))
jinja_env.filters.update(generator.GetFilters())
jinja_env.compile_templates(
os.path.join(output_dir, "%s.zip" % generator.GetTemplatePrefix()),
......
# Copyright 2014 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.
"""Node classes for the AST for a Mojo IDL file."""
# Note: For convenience of testing, you probably want to define __eq__() methods
......@@ -393,7 +392,6 @@ class Union(Definition):
class UnionField(Definition):
def __init__(self, mojom_name, attribute_list, ordinal, typename, **kwargs):
assert isinstance(mojom_name, str)
assert attribute_list is None or isinstance(attribute_list, AttributeList)
......
# Copyright 2018 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.
"""Helpers for processing conditionally enabled features in a mojom."""
from . import ast
from ..error import Error
class EnableIfError(Error):
""" Class for errors from ."""
def __init__(self, filename, message, lineno=None):
Error.__init__(self, filename, message, lineno=lineno, addenda=None)
def _IsEnabled(definition, enabled_features):
"""Returns true if a definition is enabled.
......@@ -28,7 +29,8 @@ def _IsEnabled(definition, enabled_features):
for a in definition.attribute_list:
if a.key == 'EnableIf':
if already_defined:
raise EnableIfError(definition.filename,
raise EnableIfError(
definition.filename,
"EnableIf attribute may only be defined once per field.",
definition.lineno)
already_defined = True
......
......@@ -6,6 +6,7 @@ import imp
import os.path
import sys
def _GetDirAbove(dirname):
"""Returns the directory "above" this file containing |dirname| (which must
also be "above" this file)."""
......@@ -16,6 +17,7 @@ def _GetDirAbove(dirname):
if tail == dirname:
return path
try:
imp.find_module("ply")
except ImportError:
......@@ -35,7 +37,6 @@ class LexError(Error):
# We have methods which look like they could be functions:
# pylint: disable=R0201
class Lexer(object):
def __init__(self, filename):
self.filename = filename
......@@ -52,7 +53,6 @@ class Lexer(object):
##
keywords = (
'HANDLE',
'IMPORT',
'MODULE',
'STRUCT',
......@@ -85,7 +85,8 @@ class Lexer(object):
# Constants
'ORDINAL',
'INT_CONST_DEC', 'INT_CONST_HEX',
'INT_CONST_DEC',
'INT_CONST_HEX',
'FLOAT_CONST',
# String literals
......@@ -104,12 +105,17 @@ class Lexer(object):
'RESPONSE',
# Delimiters
'LPAREN', 'RPAREN', # ( )
'LBRACKET', 'RBRACKET', # [ ]
'LBRACE', 'RBRACE', # { }
'LANGLE', 'RANGLE', # < >
'LPAREN',
'RPAREN', # ( )
'LBRACKET',
'RBRACKET', # [ ]
'LBRACE',
'RBRACE', # { }
'LANGLE',
'RANGLE', # < >
'SEMI', # ;
'COMMA', 'DOT' # , .
'COMMA',
'DOT' # , .
)
##
......@@ -124,7 +130,7 @@ class Lexer(object):
# integer constants (K&R2: A.2.5.1)
decimal_constant = '0|([1-9][0-9]*)'
hex_constant = hex_prefix+hex_digits
hex_constant = hex_prefix + hex_digits
# Don't allow octal constants (even invalid octal).
octal_constant_disallowed = '0[0-9]+'
......@@ -144,9 +150,9 @@ class Lexer(object):
r"""(\\("""+simple_escape+'|'+decimal_escape+'|'+hex_escape+'))'
# string literals (K&R2: A.2.6)
string_char = r"""([^"\\\n]|"""+escape_sequence+')'
string_literal = '"'+string_char+'*"'
bad_string_literal = '"'+string_char+'*'+bad_escape+string_char+'*"'
string_char = r"""([^"\\\n]|""" + escape_sequence + ')'
string_literal = '"' + string_char + '*"'
bad_string_literal = '"' + string_char + '*' + bad_escape + string_char + '*"'
# floating constants (K&R2: A.2.5.3)
exponent_part = r"""([eE][-+]?[0-9]+)"""
......@@ -160,7 +166,8 @@ class Lexer(object):
missing_ordinal_value = r'@'
# Don't allow ordinal values in octal (even invalid octal, like 09) or
# hexadecimal.
octal_or_hex_ordinal_disallowed = r'@((0[0-9]+)|('+hex_prefix+hex_digits+'))'
octal_or_hex_ordinal_disallowed = (
r'@((0[0-9]+)|(' + hex_prefix + hex_digits + '))')
##
## Rules for the normal state
......
# Copyright 2014 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 a syntax tree from a Mojo IDL file."""
import os.path
......@@ -17,7 +16,6 @@ from ..error import Error
from . import ast
from .lexer import Lexer
_MAX_ORDINAL_VALUE = 0xffffffff
_MAX_ARRAY_SIZE = 0xffffffff
......@@ -26,14 +24,17 @@ class ParseError(Error):
"""Class for errors from the parser."""
def __init__(self, filename, message, lineno=None, snippet=None):
Error.__init__(self, filename, message, lineno=lineno,
Error.__init__(
self,
filename,
message,
lineno=lineno,
addenda=([snippet] if snippet else None))
# We have methods which look like they could be functions:
# pylint: disable=R0201
class Parser(object):
def __init__(self, lexer, source, filename):
self.tokens = lexer.tokens
self.source = source
......@@ -65,23 +66,28 @@ class Parser(object):
def p_root_2(self, p):
"""root : root module"""
if p[1].module is not None:
raise ParseError(self.filename,
raise ParseError(
self.filename,
"Multiple \"module\" statements not allowed:",
p[2].lineno, snippet=self._GetSnippet(p[2].lineno))
p[2].lineno,
snippet=self._GetSnippet(p[2].lineno))
if p[1].import_list.items or p[1].definition_list:
raise ParseError(
self.filename,
"\"module\" statements must precede imports and definitions:",
p[2].lineno, snippet=self._GetSnippet(p[2].lineno))
p[2].lineno,
snippet=self._GetSnippet(p[2].lineno))
p[0] = p[1]
p[0].module = p[2]
def p_root_3(self, p):
"""root : root import"""
if p[1].definition_list:
raise ParseError(self.filename,
raise ParseError(
self.filename,
"\"import\" statements must precede definitions:",
p[2].lineno, snippet=self._GetSnippet(p[2].lineno))
p[2].lineno,
snippet=self._GetSnippet(p[2].lineno))
p[0] = p[1]
p[0].import_list.Append(p[2])
......@@ -94,8 +100,8 @@ class Parser(object):
"""import : attribute_section IMPORT STRING_LITERAL SEMI"""
# 'eval' the literal to strip the quotes.
# TODO(vtl): This eval is dubious. We should unquote/unescape ourselves.
p[0] = ast.Import(p[1], eval(p[3]), filename=self.filename,
lineno=p.lineno(2))
p[0] = ast.Import(
p[1], eval(p[3]), filename=self.filename, lineno=p.lineno(2))
def p_module(self, p):
"""module : attribute_section MODULE identifier_wrapped SEMI"""
......@@ -251,8 +257,8 @@ class Parser(object):
def p_parameter(self, p):
"""parameter : attribute_section typename NAME ordinal"""
p[0] = ast.Parameter(p[3], p[1], p[4], p[2],
filename=self.filename, lineno=p.lineno(3))
p[0] = ast.Parameter(
p[3], p[1], p[4], p[2], filename=self.filename, lineno=p.lineno(3))
def p_typename(self, p):
"""typename : nonnullable_typename QSTN
......@@ -307,14 +313,13 @@ class Parser(object):
if len(p) == 2:
p[0] = p[1]
else:
if p[3] not in ('data_pipe_consumer',
'data_pipe_producer',
'message_pipe',
'shared_buffer',
'platform'):
if p[3] not in ('data_pipe_consumer', 'data_pipe_producer',
'message_pipe', 'shared_buffer', 'platform'):
# Note: We don't enable tracking of line numbers for everything, so we
# can't use |p.lineno(3)|.
raise ParseError(self.filename, "Invalid handle type %r:" % p[3],
raise ParseError(
self.filename,
"Invalid handle type %r:" % p[3],
lineno=p.lineno(1),
snippet=self._GetSnippet(p.lineno(1)))
p[0] = "handle<" + p[3] + ">"
......@@ -327,7 +332,9 @@ class Parser(object):
"""fixed_array : ARRAY LANGLE typename COMMA INT_CONST_DEC RANGLE"""
value = int(p[5])
if value == 0 or value > _MAX_ARRAY_SIZE:
raise ParseError(self.filename, "Fixed array size %d invalid:" % value,
raise ParseError(
self.filename,
"Fixed array size %d invalid:" % value,
lineno=p.lineno(5),
snippet=self._GetSnippet(p.lineno(5)))
p[0] = p[3] + "[" + p[5] + "]"
......@@ -352,7 +359,9 @@ class Parser(object):
"""ordinal : ORDINAL"""
value = int(p[1][1:])
if value > _MAX_ORDINAL_VALUE:
raise ParseError(self.filename, "Ordinal value %d too large:" % value,
raise ParseError(
self.filename,
"Ordinal value %d too large:" % value,
lineno=p.lineno(1),
snippet=self._GetSnippet(p.lineno(1)))
p[0] = ast.Ordinal(value, filename=self.filename, lineno=p.lineno(1))
......@@ -362,13 +371,13 @@ class Parser(object):
RBRACE SEMI
| attribute_section ENUM NAME LBRACE nonempty_enum_value_list \
COMMA RBRACE SEMI"""
p[0] = ast.Enum(p[3], p[1], p[5], filename=self.filename,
lineno=p.lineno(2))
p[0] = ast.Enum(
p[3], p[1], p[5], filename=self.filename, lineno=p.lineno(2))
def p_enum_2(self, p):
"""enum : attribute_section ENUM NAME SEMI"""
p[0] = ast.Enum(p[3], p[1], None, filename=self.filename,
lineno=p.lineno(2))
p[0] = ast.Enum(
p[3], p[1], None, filename=self.filename, lineno=p.lineno(2))
def p_enum_value_list_1(self, p):
"""enum_value_list : """
......@@ -391,8 +400,12 @@ class Parser(object):
"""enum_value : attribute_section NAME
| attribute_section NAME EQUALS int
| attribute_section NAME EQUALS identifier_wrapped"""
p[0] = ast.EnumValue(p[2], p[1], p[4] if len(p) == 5 else None,
filename=self.filename, lineno=p.lineno(2))
p[0] = ast.EnumValue(
p[2],
p[1],
p[4] if len(p) == 5 else None,
filename=self.filename,
lineno=p.lineno(2))
def p_const(self, p):
"""const : attribute_section CONST typename NAME EQUALS constant SEMI"""
......@@ -446,7 +459,10 @@ class Parser(object):
# TODO(vtl): Can we figure out what's missing?
raise ParseError(self.filename, "Unexpected end of file")
raise ParseError(self.filename, "Unexpected %r:" % e.value, lineno=e.lineno,
raise ParseError(
self.filename,
"Unexpected %r:" % e.value,
lineno=e.lineno,
snippet=self._GetSnippet(e.lineno))
def _GetSnippet(self, lineno):
......
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