blob: f063ad8751ee37ae42477a2f7e7460382935cb45 [file] [log] [blame]
# 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 functools import partial
import os.path
import module as mojom
import pack
def GetStructFromMethod(interface, method):
"""Converts a method's parameters into the fields of a struct."""
params_class = "%s_%s_Params" % (interface.name, method.name)
struct = mojom.Struct(params_class, module=interface.module)
for param in method.parameters:
struct.AddField(param.name, param.kind, param.ordinal)
struct.packed = pack.PackedStruct(struct)
return struct
def GetResponseStructFromMethod(interface, method):
"""Converts a method's response_parameters into the fields of a struct."""
params_class = "%s_%s_ResponseParams" % (interface.name, method.name)
struct = mojom.Struct(params_class, module=interface.module)
for param in method.response_parameters:
struct.AddField(param.name, param.kind, param.ordinal)
struct.packed = pack.PackedStruct(struct)
return struct
def GetStructInfo(exported, struct):
struct.packed = pack.PackedStruct(struct)
struct.bytes = pack.GetByteLayout(struct.packed)
struct.exported = exported
return struct
def IsStringKind(kind):
return kind.spec == 's'
def IsEnumKind(kind):
return isinstance(kind, mojom.Enum)
def IsObjectKind(kind):
return isinstance(kind, (mojom.Struct, mojom.Array)) or IsStringKind(kind)
def IsHandleKind(kind):
return kind.spec.startswith('h') or isinstance(kind, mojom.Interface)
def StudlyCapsToCamel(studly):
return studly[0].lower() + studly[1:]
def VerifyTokenType(token, expected):
"""Used to check that arrays and objects are used correctly as default
values. Arrays are tokens that look like ('ARRAY', element0, element1...).
See mojom_parser.py for their representation.
"""
if not isinstance(token, tuple):
raise Exception("Expected token type '%s'. Invalid token '%s'." %
(expected, token))
if token[0] != expected:
raise Exception("Expected token type '%s'. Got '%s'." %
(expected, token[0]))
def ExpressionMapper(expression, mapper):
if isinstance(expression, tuple) and expression[0] == 'EXPRESSION':
result = []
for each in expression[1]:
result.extend(ExpressionMapper(each, mapper))
return result
return [mapper(expression)]
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):
self.module = module
self.output_dir = output_dir
def GetStructsFromMethods(self):
result = []
for interface in self.module.interfaces:
for method in interface.methods:
result.append(GetStructFromMethod(interface, method))
if method.response_parameters != None:
result.append(GetResponseStructFromMethod(interface, method))
return map(partial(GetStructInfo, False), result)
def GetStructs(self):
return map(partial(GetStructInfo, True), self.module.structs)
def Write(self, contents, filename):
if self.output_dir is None:
print contents
return
with open(os.path.join(self.output_dir, filename), "w+") as f:
f.write(contents)
def GenerateFiles(self):
raise NotImplementedError("Subclasses must override/implement this method")