| Index: components/webui_generator/generator/declaration.py
|
| diff --git a/components/webui_generator/generator/declaration.py b/components/webui_generator/generator/declaration.py
|
| deleted file mode 100644
|
| index e9863b5803395d29c8f3bda7a4cd863885395752..0000000000000000000000000000000000000000
|
| --- a/components/webui_generator/generator/declaration.py
|
| +++ /dev/null
|
| @@ -1,312 +0,0 @@
|
| -# 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.
|
| -
|
| -import itertools
|
| -import json
|
| -import os.path
|
| -import re
|
| -
|
| -import util
|
| -
|
| -# Schema is described as follows:
|
| -# * for simple type:
|
| -# %simple_type%
|
| -# * for list:
|
| -# (list, %items_schema%)
|
| -# * for dict:
|
| -# (dict, { '%key_name%': (%is_key_required%, %value_schema%),
|
| -# ...
|
| -# })
|
| -DECLARATION_SCHEMA = (dict, {
|
| - 'imports': (False, (list, unicode)),
|
| - 'type': (True, unicode),
|
| - 'children': (False, (list, (dict, {
|
| - 'id': (True, unicode),
|
| - 'type': (True, unicode),
|
| - 'comment': (False, unicode)
|
| - }))),
|
| - 'context': (False, (list, (dict, {
|
| - 'name': (True, unicode),
|
| - 'type': (False, unicode),
|
| - 'default': (False, object),
|
| - 'comment': (False, unicode)
|
| - }))),
|
| - 'events': (False, (list, (dict, {
|
| - 'name': (True, unicode),
|
| - 'comment': (False, unicode)
|
| - }))),
|
| - 'strings': (False, (list, (dict, {
|
| - 'name': (True, unicode),
|
| - 'comment': (False, unicode)
|
| - }))),
|
| - 'comment': (False, unicode)
|
| -})
|
| -
|
| -# Returns (True,) if |obj| matches |schema|.
|
| -# Otherwise returns (False, msg), where |msg| is a diagnostic message.
|
| -def MatchSchema(obj, schema):
|
| - expected_type = schema[0] if isinstance(schema, tuple) else schema
|
| - if not isinstance(obj, expected_type):
|
| - return (False, 'Wrong type, expected %s, got %s.' %
|
| - (expected_type, type(obj)))
|
| - if expected_type == dict:
|
| - obj_keys = set(obj.iterkeys())
|
| - allowed_keys = set(schema[1].iterkeys())
|
| - required_keys = set(kv[0] for kv in schema[1].iteritems() if kv[1][0])
|
| - if not obj_keys.issuperset(required_keys):
|
| - missing_keys = required_keys.difference(obj_keys)
|
| - return (False, 'Missing required key%s %s.' %
|
| - ('s' if len(missing_keys) > 1 else '',
|
| - ', '.join('\'%s\'' % k for k in missing_keys)))
|
| - if not obj_keys.issubset(allowed_keys):
|
| - unknown_keys = obj_keys.difference(allowed_keys)
|
| - return (False, 'Unknown key%s %s.' %
|
| - ('s' if len(unknown_keys) > 1 else '',
|
| - ', '.join('\'%s\'' % k for k in unknown_keys)))
|
| - for key in obj:
|
| - match = MatchSchema(obj[key], schema[1][key][1])
|
| - if not match[0]:
|
| - return (False, ('[\'%s\'] ' % key) + match[1])
|
| - elif expected_type == list:
|
| - for i, item in enumerate(obj):
|
| - match = MatchSchema(item, schema[1])
|
| - if not match[0]:
|
| - return (False, ('[%d] ' % i) + match[1])
|
| - return (True,)
|
| -
|
| -def CheckDeclarationIsValid(declaration):
|
| - match = MatchSchema(declaration, DECLARATION_SCHEMA)
|
| - if not match[0]:
|
| - raise Exception('Declaration is not valid: ' + match[1])
|
| -
|
| -def CheckFieldIsUnique(list_of_dicts, field):
|
| - seen = {}
|
| - for i, d in enumerate(list_of_dicts):
|
| - value = d[field]
|
| - if value in seen:
|
| - raise Exception(
|
| - '[%d] Object with "%s" equal to "%s" already exists. See [%d].' %
|
| - (i, field, value, seen[value]))
|
| - else:
|
| - seen[value] = i
|
| -
|
| -class FieldDeclaration(object):
|
| - ALLOWED_TYPES = [
|
| - 'boolean',
|
| - 'integer',
|
| - 'double',
|
| - 'string',
|
| - 'string_list'
|
| - ]
|
| -
|
| - DEFAULTS = {
|
| - 'boolean': False,
|
| - 'integer': 0,
|
| - 'double': 0.0,
|
| - 'string': u'',
|
| - 'string_list': []
|
| - }
|
| -
|
| - def __init__(self, declaration):
|
| - self.name = declaration['name']
|
| - self.id = util.ToLowerCamelCase(self.name)
|
| - self.type = declaration['type'] if 'type' in declaration else 'string'
|
| - if self.type not in self.ALLOWED_TYPES:
|
| - raise Exception('Unknown type of context field "%s": "%s"' %
|
| - (self.name, self.type))
|
| - self.default_value = declaration['default'] if 'default' in declaration \
|
| - else self.DEFAULTS[self.type]
|
| - if type(self.default_value) != type(self.DEFAULTS[self.type]):
|
| - raise Exception('Wrong type of default for field "%s": '
|
| - 'expected "%s", got "%s"' %
|
| - (self.name,
|
| - type(self.DEFAULTS[self.type]),
|
| - type(self.default_value)))
|
| -
|
| -class Declaration(object):
|
| - class InvalidDeclaration(Exception):
|
| - def __init__(self, path, message):
|
| - super(Exception, self).__init__(
|
| - 'Invalid declaration file "%s": %s' % (path, message))
|
| -
|
| - class DeclarationsStorage(object):
|
| - def __init__(self):
|
| - self.by_path = {}
|
| - self.by_type = {}
|
| -
|
| - def Add(self, declaration):
|
| - assert declaration.path not in self.by_path
|
| - self.by_path[declaration.path] = declaration
|
| - if declaration.type in self.by_type:
|
| - raise Exception(
|
| - 'Redefinition of type "%s". ' \
|
| - 'Previous definition was in "%s".' % \
|
| - (declaration.type, self.by_type[declaration.type].path))
|
| - self.by_type[declaration.type] = declaration
|
| -
|
| - def HasPath(self, path):
|
| - return path in self.by_path
|
| -
|
| - def HasType(self, type):
|
| - return type in self.by_type
|
| -
|
| - def GetByPath(self, path):
|
| - return self.by_path[path]
|
| -
|
| - def GetByType(self, type):
|
| - return self.by_type[type]
|
| -
|
| - def GetKnownPathes(self):
|
| - return self.by_path.keys()
|
| -
|
| -
|
| - def __init__(self, path, known_declarations=None):
|
| - if known_declarations is None:
|
| - known_declarations = Declaration.DeclarationsStorage()
|
| - self.path = path
|
| - try:
|
| - self.data = json.load(open(path, 'r'))
|
| - CheckDeclarationIsValid(self.data)
|
| - filename_wo_ext = os.path.splitext(os.path.basename(self.path))[0]
|
| - if self.data['type'] != filename_wo_ext:
|
| - raise Exception(
|
| - 'File with declaration of type "%s" should be named "%s.json"' %
|
| - (self.data['type'], filename_wo_ext))
|
| -
|
| - known_declarations.Add(self)
|
| - if 'imports' in self.data:
|
| - for import_path in self.data['imports']:
|
| - #TODO(dzhioev): detect circular dependencies.
|
| - if not known_declarations.HasPath(import_path):
|
| - Declaration(import_path, known_declarations)
|
| -
|
| - for key in ['children', 'strings', 'context', 'events']:
|
| - if key in self.data:
|
| - unique_field = 'id' if key == 'children' else 'name'
|
| - try:
|
| - CheckFieldIsUnique(self.data[key], unique_field)
|
| - except Exception as e:
|
| - raise Exception('["%s"] %s' % (key, e.message))
|
| - else:
|
| - self.data[key] = []
|
| -
|
| - self.children = {}
|
| - for child_data in self.data['children']:
|
| - child_type = child_data['type']
|
| - child_id = child_data['id']
|
| - if not known_declarations.HasType(child_type):
|
| - raise Exception('Unknown type "%s" for child "%s"' %
|
| - (child_type, child_id))
|
| - self.children[child_id] = known_declarations.GetByType(child_type)
|
| -
|
| - self.fields = [FieldDeclaration(d) for d in self.data['context']]
|
| - fields_names = [field.name for field in self.fields]
|
| - if len(fields_names) > len(set(fields_names)):
|
| - raise Exception('Duplicate fields in declaration.')
|
| - self.known_declarations = known_declarations
|
| - except Declaration.InvalidDeclaration:
|
| - raise
|
| - except Exception as e:
|
| - raise Declaration.InvalidDeclaration(self.path, e.message)
|
| -
|
| - @property
|
| - def type(self):
|
| - return self.data['type']
|
| -
|
| - @property
|
| - def strings(self):
|
| - return (string['name'] for string in self.data['strings'])
|
| -
|
| - @property
|
| - def events(self):
|
| - return (event['name'] for event in self.data['events'])
|
| -
|
| - @property
|
| - def webui_view_basename(self):
|
| - return self.type + '_web_ui_view'
|
| -
|
| - @property
|
| - def webui_view_h_name(self):
|
| - return self.webui_view_basename + '.h'
|
| -
|
| - @property
|
| - def webui_view_cc_name(self):
|
| - return self.webui_view_basename + '.cc'
|
| -
|
| - @property
|
| - def webui_view_include_path(self):
|
| - return os.path.join(os.path.dirname(self.path), self.webui_view_h_name)
|
| -
|
| - @property
|
| - def export_h_name(self):
|
| - return self.type + '_export.h'
|
| -
|
| - @property
|
| - def component_export_macro(self):
|
| - return "WUG_" + self.type.upper() + "_EXPORT"
|
| -
|
| - @property
|
| - def component_impl_macro(self):
|
| - return "WUG_" + self.type.upper() + "_IMPLEMENTATION"
|
| -
|
| - @property
|
| - def export_h_include_path(self):
|
| - return os.path.join(os.path.dirname(self.path), self.export_h_name)
|
| -
|
| - @property
|
| - def view_model_basename(self):
|
| - return self.type + '_view_model'
|
| -
|
| - @property
|
| - def view_model_h_name(self):
|
| - return self.view_model_basename + '.h'
|
| -
|
| - @property
|
| - def view_model_cc_name(self):
|
| - return self.view_model_basename + '.cc'
|
| -
|
| - @property
|
| - def view_model_include_path(self):
|
| - return os.path.join(os.path.dirname(self.path), self.view_model_h_name)
|
| -
|
| - @property
|
| - def html_view_basename(self):
|
| - return '%s-view' % self.type.replace('_', '-')
|
| -
|
| - @property
|
| - def html_view_html_name(self):
|
| - return self.html_view_basename + '.html'
|
| -
|
| - @property
|
| - def html_view_js_name(self):
|
| - return self.html_view_basename + '.js'
|
| -
|
| - @property
|
| - def html_view_html_include_path(self):
|
| - return os.path.join(os.path.dirname(self.path), self.html_view_html_name)
|
| -
|
| - @property
|
| - def html_view_js_include_path(self):
|
| - return os.path.join(os.path.dirname(self.path), self.html_view_js_name)
|
| -
|
| - @property
|
| - def build_target(self):
|
| - return self.type + "_wug_generated"
|
| -
|
| - @property
|
| - def webui_view_class(self):
|
| - return util.ToUpperCamelCase(self.type) + 'WebUIView'
|
| -
|
| - @property
|
| - def view_model_class(self):
|
| - return util.ToUpperCamelCase(self.type) + 'ViewModel'
|
| -
|
| - @property
|
| - def imports(self):
|
| - res = set(self.known_declarations.GetKnownPathes())
|
| - res.remove(self.path)
|
| - return res
|
| -
|
| -
|
| -
|
|
|