Index: tools/json_schema_compiler/ppapi_generator.py |
diff --git a/tools/json_schema_compiler/ppapi_generator.py b/tools/json_schema_compiler/ppapi_generator.py |
deleted file mode 100644 |
index e47b9540e34654e1dceb617e8a4d2d3e7f571d42..0000000000000000000000000000000000000000 |
--- a/tools/json_schema_compiler/ppapi_generator.py |
+++ /dev/null |
@@ -1,289 +0,0 @@ |
-# 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. |
- |
-import collections |
-import datetime |
-import os.path |
-import sys |
- |
-import code |
-import cpp_util |
-import model |
- |
-try: |
- import jinja2 |
-except ImportError: |
- sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', |
- 'third_party')) |
- import jinja2 |
- |
- |
-class _PpapiGeneratorBase(object): |
- """A base class for ppapi generators. |
- |
- Implementations should set TEMPLATE_NAME to a string containing the name of |
- the template file without its extension. The template will be rendered with |
- the following symbols available: |
- name: A string containing the name of the namespace. |
- enums: A list of enums within the namespace. |
- types: A list of types within the namespace, sorted such that no element |
- depends on an earlier element. |
- events: A dict of events within the namespace. |
- functions: A dict of functions within the namespace. |
- year: An int containing the current year. |
- source_file: The name of the input file. |
- """ |
- |
- def __init__(self, namespace): |
- self._namespace = namespace |
- self._required_types = {} |
- self._array_types = set() |
- self._optional_types = set() |
- self._optional_array_types = set() |
- self._dependencies = collections.OrderedDict() |
- self._types = [] |
- self._enums = [] |
- |
- self.jinja_environment = jinja2.Environment( |
- loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__), |
- 'templates', 'ppapi'))) |
- self._SetupFilters() |
- self._ResolveTypeDependencies() |
- |
- def _SetupFilters(self): |
- self.jinja_environment.filters.update({ |
- 'ppapi_type': self.ToPpapiType, |
- 'classname': cpp_util.Classname, |
- 'enum_value': self.EnumValueName, |
- 'return_type': self.GetFunctionReturnType, |
- 'format_param_type': self.FormatParamType, |
- 'needs_optional': self.NeedsOptional, |
- 'needs_array': self.NeedsArray, |
- 'needs_optional_array': self.NeedsOptionalArray, |
- 'has_array_outs': self.HasArrayOuts, |
- }) |
- |
- def Render(self, template_name, values): |
- generated_code = code.Code() |
- template = self.jinja_environment.get_template( |
- '%s.template' % template_name) |
- generated_code.Append(template.render(values)) |
- return generated_code |
- |
- def Generate(self): |
- """Generates a Code object for a single namespace.""" |
- return self.Render(self.TEMPLATE_NAME, { |
- 'name': self._namespace.name, |
- 'enums': self._enums, |
- 'types': self._types, |
- 'events': self._namespace.events, |
- 'functions': self._namespace.functions, |
- # TODO(sammc): Don't change years when regenerating existing output files. |
- 'year': datetime.date.today().year, |
- 'source_file': self._namespace.source_file, |
- }) |
- |
- def _ResolveTypeDependencies(self): |
- """Calculates the transitive closure of the types in _required_types. |
- |
- Returns a tuple containing the list of struct types and the list of enum |
- types. The list of struct types is ordered such that no type depends on a |
- type later in the list. |
- |
- """ |
- if self._namespace.functions: |
- for function in self._namespace.functions.itervalues(): |
- self._FindFunctionDependencies(function) |
- |
- if self._namespace.events: |
- for event in self._namespace.events.itervalues(): |
- self._FindFunctionDependencies(event) |
- resolved_types = set() |
- while resolved_types < set(self._required_types): |
- for typename in sorted(set(self._required_types) - resolved_types): |
- type_ = self._required_types[typename] |
- self._dependencies.setdefault(typename, set()) |
- for member in type_.properties.itervalues(): |
- self._RegisterDependency(member, self._NameComponents(type_)) |
- resolved_types.add(typename) |
- while self._dependencies: |
- for name, deps in self._dependencies.items(): |
- if not deps: |
- if (self._required_types[name].property_type == |
- model.PropertyType.ENUM): |
- self._enums.append(self._required_types[name]) |
- else: |
- self._types.append(self._required_types[name]) |
- for deps in self._dependencies.itervalues(): |
- deps.discard(name) |
- del self._dependencies[name] |
- break |
- else: |
- raise ValueError('Circular dependency %s' % self._dependencies) |
- |
- def _FindFunctionDependencies(self, function): |
- for param in function.params: |
- self._RegisterDependency(param, None) |
- if function.callback: |
- for param in function.callback.params: |
- self._RegisterDependency(param, None) |
- if function.returns: |
- self._RegisterTypeDependency(function.returns, None, False, False) |
- |
- def _RegisterDependency(self, member, depender): |
- self._RegisterTypeDependency(member.type_, depender, member.optional, False) |
- |
- def _RegisterTypeDependency(self, type_, depender, optional, array): |
- if type_.property_type == model.PropertyType.ARRAY: |
- self._RegisterTypeDependency(type_.item_type, depender, optional, True) |
- elif type_.property_type == model.PropertyType.REF: |
- self._RegisterTypeDependency(self._namespace.types[type_.ref_type], |
- depender, optional, array) |
- elif type_.property_type in (model.PropertyType.OBJECT, |
- model.PropertyType.ENUM): |
- name_components = self._NameComponents(type_) |
- self._required_types[name_components] = type_ |
- if depender: |
- self._dependencies.setdefault(depender, set()).add( |
- name_components) |
- if array: |
- self._array_types.add(name_components) |
- if optional: |
- self._optional_array_types.add(name_components) |
- elif optional: |
- self._optional_types.add(name_components) |
- |
- @staticmethod |
- def _NameComponents(entity): |
- """Returns a tuple of the fully-qualified name of an entity.""" |
- names = [] |
- while entity: |
- if (not isinstance(entity, model.Type) or |
- entity.property_type != model.PropertyType.ARRAY): |
- names.append(entity.name) |
- entity = entity.parent |
- return tuple(reversed(names[:-1])) |
- |
- def ToPpapiType(self, type_, array=False, optional=False): |
- """Returns a string containing the name of the Pepper C type for |type_|. |
- |
- If array is True, returns the name of an array of |type_|. If optional is |
- True, returns the name of an optional |type_|. If both array and optional |
- are True, returns the name of an optional array of |type_|. |
- """ |
- if isinstance(type_, model.Function) or type_.property_type in ( |
- model.PropertyType.OBJECT, model.PropertyType.ENUM): |
- return self._FormatPpapiTypeName( |
- array, optional, '_'.join( |
- cpp_util.Classname(s) for s in self._NameComponents(type_)), |
- namespace=cpp_util.Classname(self._namespace.name)) |
- elif type_.property_type == model.PropertyType.REF: |
- return self.ToPpapiType(self._namespace.types[type_.ref_type], |
- optional=optional, array=array) |
- elif type_.property_type == model.PropertyType.ARRAY: |
- return self.ToPpapiType(type_.item_type, array=True, |
- optional=optional) |
- elif type_.property_type == model.PropertyType.STRING and not array: |
- return 'PP_Var' |
- elif array or optional: |
- if type_.property_type in self._PPAPI_COMPOUND_PRIMITIVE_TYPE_MAP: |
- return self._FormatPpapiTypeName( |
- array, optional, |
- self._PPAPI_COMPOUND_PRIMITIVE_TYPE_MAP[type_.property_type], '') |
- return self._PPAPI_PRIMITIVE_TYPE_MAP.get(type_.property_type, 'PP_Var') |
- |
- _PPAPI_PRIMITIVE_TYPE_MAP = { |
- model.PropertyType.BOOLEAN: 'PP_Bool', |
- model.PropertyType.DOUBLE: 'double_t', |
- model.PropertyType.INT64: 'int64_t', |
- model.PropertyType.INTEGER: 'int32_t', |
- } |
- _PPAPI_COMPOUND_PRIMITIVE_TYPE_MAP = { |
- model.PropertyType.BOOLEAN: 'Bool', |
- model.PropertyType.DOUBLE: 'Double', |
- model.PropertyType.INT64: 'Int64', |
- model.PropertyType.INTEGER: 'Int32', |
- model.PropertyType.STRING: 'String', |
- } |
- |
- @staticmethod |
- def _FormatPpapiTypeName(array, optional, name, namespace=''): |
- if namespace: |
- namespace = '%s_' % namespace |
- if array: |
- if optional: |
- return 'PP_%sOptional_%s_Array' % (namespace, name) |
- return 'PP_%s%s_Array' % (namespace, name) |
- if optional: |
- return 'PP_%sOptional_%s' % (namespace, name) |
- return 'PP_%s%s' % (namespace, name) |
- |
- def NeedsOptional(self, type_): |
- """Returns True if an optional |type_| is required.""" |
- return self._NameComponents(type_) in self._optional_types |
- |
- def NeedsArray(self, type_): |
- """Returns True if an array of |type_| is required.""" |
- return self._NameComponents(type_) in self._array_types |
- |
- def NeedsOptionalArray(self, type_): |
- """Returns True if an optional array of |type_| is required.""" |
- return self._NameComponents(type_) in self._optional_array_types |
- |
- def FormatParamType(self, param): |
- """Formats the type of a parameter or property.""" |
- return self.ToPpapiType(param.type_, optional=param.optional) |
- |
- @staticmethod |
- def GetFunctionReturnType(function): |
- return 'int32_t' if function.callback or function.returns else 'void' |
- |
- def EnumValueName(self, enum_value, enum_type): |
- """Returns a string containing the name for an enum value.""" |
- return '%s_%s' % (self.ToPpapiType(enum_type).upper(), |
- enum_value.name.upper()) |
- |
- def _ResolveType(self, type_): |
- if type_.property_type == model.PropertyType.REF: |
- return self._ResolveType(self._namespace.types[type_.ref_type]) |
- if type_.property_type == model.PropertyType.ARRAY: |
- return self._ResolveType(type_.item_type) |
- return type_ |
- |
- def _IsOrContainsArray(self, type_): |
- if type_.property_type == model.PropertyType.ARRAY: |
- return True |
- type_ = self._ResolveType(type_) |
- if type_.property_type == model.PropertyType.OBJECT: |
- return any(self._IsOrContainsArray(param.type_) |
- for param in type_.properties.itervalues()) |
- return False |
- |
- def HasArrayOuts(self, function): |
- """Returns True if the function produces any arrays as outputs. |
- |
- This includes arrays that are properties of other objects. |
- """ |
- if function.callback: |
- for param in function.callback.params: |
- if self._IsOrContainsArray(param.type_): |
- return True |
- return function.returns and self._IsOrContainsArray(function.returns) |
- |
- |
-class _IdlGenerator(_PpapiGeneratorBase): |
- TEMPLATE_NAME = 'idl' |
- |
- |
-class _GeneratorWrapper(object): |
- def __init__(self, generator_factory): |
- self._generator_factory = generator_factory |
- |
- def Generate(self, namespace): |
- return self._generator_factory(namespace).Generate() |
- |
- |
-class PpapiGenerator(object): |
- def __init__(self): |
- self.idl_generator = _GeneratorWrapper(_IdlGenerator) |