Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import copy | 5 import copy |
| 6 import os.path | 6 import os.path |
| 7 import re | 7 import re |
| 8 | 8 |
| 9 from json_parse import OrderedDict | 9 from json_parse import OrderedDict |
| 10 | 10 |
| 11 class ParseException(Exception): | 11 class ParseException(Exception): |
| 12 """Thrown when data in the model is invalid. | 12 """Thrown when data in the model is invalid. |
| 13 """ | 13 """ |
| 14 def __init__(self, parent, message): | 14 def __init__(self, parent, message): |
| 15 hierarchy = _GetModelHierarchy(parent) | 15 hierarchy = _GetModelHierarchy(parent) |
| 16 hierarchy.append(message) | 16 hierarchy.append(message) |
| 17 Exception.__init__( | 17 Exception.__init__( |
| 18 self, 'Model parse exception at:\n' + '\n'.join(hierarchy)) | 18 self, 'Model parse exception at:\n' + '\n'.join(hierarchy)) |
| 19 | 19 |
| 20 class Model(object): | 20 class Model(object): |
| 21 """Model of all namespaces that comprise an API. | 21 """Model of all namespaces that comprise an API. |
| 22 | 22 |
| 23 Properties: | 23 Properties: |
| 24 - |namespaces| a map of a namespace name to its model.Namespace | 24 - |namespaces| a map of a namespace name to its model.Namespace |
| 25 """ | 25 """ |
| 26 def __init__(self): | 26 def __init__(self): |
| 27 self.namespaces = {} | 27 self.namespaces = {} |
| 28 | 28 |
| 29 def AddNamespace(self, json, source_file): | 29 def AddNamespace(self, json, source_file, include_compiler_options=False): |
| 30 """Add a namespace's json to the model and returns the namespace. | 30 """Add a namespace's json to the model and returns the namespace. |
| 31 """ | 31 """ |
| 32 namespace = Namespace(json, source_file) | 32 namespace = Namespace(json, |
| 33 source_file, | |
| 34 include_compiler_options=include_compiler_options) | |
| 33 self.namespaces[namespace.name] = namespace | 35 self.namespaces[namespace.name] = namespace |
| 34 return namespace | 36 return namespace |
| 35 | 37 |
| 36 class Namespace(object): | 38 class Namespace(object): |
| 37 """An API namespace. | 39 """An API namespace. |
| 38 | 40 |
| 39 Properties: | 41 Properties: |
| 40 - |name| the name of the namespace | 42 - |name| the name of the namespace |
| 41 - |unix_name| the unix_name of the namespace | 43 - |unix_name| the unix_name of the namespace |
| 42 - |source_file| the file that contained the namespace definition | 44 - |source_file| the file that contained the namespace definition |
| 43 - |source_file_dir| the directory component of |source_file| | 45 - |source_file_dir| the directory component of |source_file| |
| 44 - |source_file_filename| the filename component of |source_file| | 46 - |source_file_filename| the filename component of |source_file| |
| 47 - |platforms| if not None, the list of platforms that the namespace is | |
| 48 available to. | |
| 45 - |types| a map of type names to their model.Type | 49 - |types| a map of type names to their model.Type |
| 46 - |functions| a map of function names to their model.Function | 50 - |functions| a map of function names to their model.Function |
| 47 - |events| a map of event names to their model.Function | 51 - |events| a map of event names to their model.Function |
| 48 - |properties| a map of property names to their model.Property | 52 - |properties| a map of property names to their model.Property |
| 53 - |compiler_options| the compiler_options dict, only present if | |
| 54 |include_compiler_options| is True | |
| 49 """ | 55 """ |
| 50 def __init__(self, json, source_file): | 56 def __init__(self, json, source_file, include_compiler_options=False): |
| 51 self.name = json['namespace'] | 57 self.name = json['namespace'] |
| 52 self.unix_name = UnixName(self.name) | 58 self.unix_name = UnixName(self.name) |
| 53 self.source_file = source_file | 59 self.source_file = source_file |
| 54 self.source_file_dir, self.source_file_filename = os.path.split(source_file) | 60 self.source_file_dir, self.source_file_filename = os.path.split(source_file) |
| 55 self.parent = None | 61 self.parent = None |
| 62 self.platforms = _GetPlatforms(json) | |
| 56 _AddTypes(self, json, self) | 63 _AddTypes(self, json, self) |
| 57 _AddFunctions(self, json, self) | 64 _AddFunctions(self, json, self) |
| 58 _AddEvents(self, json, self) | 65 _AddEvents(self, json, self) |
| 59 _AddProperties(self, json, self) | 66 _AddProperties(self, json, self) |
| 67 if include_compiler_options: | |
| 68 self.compiler_options = json.get('compiler_options', {}) | |
| 60 | 69 |
| 61 class Type(object): | 70 class Type(object): |
| 62 """A Type defined in the json. | 71 """A Type defined in the json. |
| 63 | 72 |
| 64 Properties: | 73 Properties: |
| 65 - |name| the type name | 74 - |name| the type name |
| 66 - |description| the description of the type (if provided) | 75 - |description| the description of the type (if provided) |
| 67 - |properties| a map of property unix_names to their model.Property | 76 - |properties| a map of property unix_names to their model.Property |
| 68 - |functions| a map of function names to their model.Function | 77 - |functions| a map of function names to their model.Function |
| 69 - |events| a map of event names to their model.Event | 78 - |events| a map of event names to their model.Event |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 additional_properties_key, | 129 additional_properties_key, |
| 121 additional_properties, | 130 additional_properties, |
| 122 namespace, | 131 namespace, |
| 123 is_additional_properties=True) | 132 is_additional_properties=True) |
| 124 | 133 |
| 125 class Function(object): | 134 class Function(object): |
| 126 """A Function defined in the API. | 135 """A Function defined in the API. |
| 127 | 136 |
| 128 Properties: | 137 Properties: |
| 129 - |name| the function name | 138 - |name| the function name |
| 139 - |platforms| if not None, the list of platforms that the function is | |
| 140 available to. | |
|
Yoyo Zhou
2013/01/04 23:54:33
nit: it bugs me that some of these end in . and so
not at google - send to devlin
2013/01/05 00:15:36
ok
| |
| 130 - |params| a list of parameters to the function (order matters). A separate | 141 - |params| a list of parameters to the function (order matters). A separate |
| 131 parameter is used for each choice of a 'choices' parameter. | 142 parameter is used for each choice of a 'choices' parameter. |
| 132 - |description| a description of the function (if provided) | 143 - |description| a description of the function (if provided) |
| 133 - |callback| the callback parameter to the function. There should be exactly | 144 - |callback| the callback parameter to the function. There should be exactly |
| 134 one | 145 one |
| 135 - |optional| whether the Function is "optional"; this only makes sense to be | 146 - |optional| whether the Function is "optional"; this only makes sense to be |
| 136 present when the Function is representing a callback property. | 147 present when the Function is representing a callback property. |
| 137 - |simple_name| the name of this Function without a namespace | 148 - |simple_name| the name of this Function without a namespace |
| 138 """ | 149 """ |
| 139 def __init__(self, | 150 def __init__(self, |
| 140 parent, | 151 parent, |
| 141 json, | 152 json, |
| 142 namespace, | 153 namespace, |
| 143 from_json=False, | 154 from_json=False, |
| 144 from_client=False): | 155 from_client=False): |
| 145 self.name = json['name'] | 156 self.name = json['name'] |
| 146 self.simple_name = _StripNamespace(self.name, namespace) | 157 self.simple_name = _StripNamespace(self.name, namespace) |
| 158 self.platforms = _GetPlatforms(json) | |
| 147 self.params = [] | 159 self.params = [] |
| 148 self.description = json.get('description') | 160 self.description = json.get('description') |
| 149 self.callback = None | 161 self.callback = None |
| 150 self.optional = json.get('optional', False) | 162 self.optional = json.get('optional', False) |
| 151 self.parent = parent | 163 self.parent = parent |
| 152 self.nocompile = json.get('nocompile') | 164 self.nocompile = json.get('nocompile') |
| 153 options = json.get('options', {}) | 165 options = json.get('options', {}) |
| 154 self.conditions = options.get('conditions', []) | 166 self.conditions = options.get('conditions', []) |
| 155 self.actions = options.get('actions', []) | 167 self.actions = options.get('actions', []) |
| 156 self.supports_listeners = options.get('supportsListeners', True) | 168 self.supports_listeners = options.get('supportsListeners', True) |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 def Copy(self): | 362 def Copy(self): |
| 351 """Makes a copy of this model.Property object and allow the unix_name to be | 363 """Makes a copy of this model.Property object and allow the unix_name to be |
| 352 set again. | 364 set again. |
| 353 """ | 365 """ |
| 354 property_copy = copy.copy(self) | 366 property_copy = copy.copy(self) |
| 355 property_copy._unix_name_used = False | 367 property_copy._unix_name_used = False |
| 356 return property_copy | 368 return property_copy |
| 357 | 369 |
| 358 unix_name = property(GetUnixName, SetUnixName) | 370 unix_name = property(GetUnixName, SetUnixName) |
| 359 | 371 |
| 360 class _PropertyTypeInfo(object): | 372 class _Enum(object): |
| 361 """This class is not an inner class of |PropertyType| so it can be pickled. | 373 """Superclass for enum types with a "name" field, setting up repr/eq/ne. |
| 374 Enums need to do this so that equality/non-equality work over pickling. | |
| 362 """ | 375 """ |
| 363 def __init__(self, is_fundamental, name): | 376 |
| 364 self.is_fundamental = is_fundamental | 377 @staticmethod |
| 378 def GetAll(cls): | |
| 379 """Yields all _Enum objects declared in |cls|. | |
| 380 """ | |
| 381 for prop_key in dir(cls): | |
| 382 prop_value = getattr(cls, prop_key) | |
| 383 if isinstance(prop_value, _Enum): | |
| 384 yield prop_value | |
| 385 | |
| 386 def __init__(self, name): | |
| 365 self.name = name | 387 self.name = name |
| 366 | 388 |
| 367 def __repr__(self): | 389 def __repr(self): |
| 368 return self.name | 390 return self.name |
| 369 | 391 |
| 370 def __eq__(self, other): | 392 def __eq__(self, other): |
| 371 return isinstance(other, _PropertyTypeInfo) and self.name == other.name | 393 return type(other) == type(self) and other.name == self.name |
| 372 | 394 |
| 373 def __ne__(self, other): | 395 def __ne__(self, other): |
| 374 # Yes. You seriously do need this. | |
| 375 return not (self == other) | 396 return not (self == other) |
| 376 | 397 |
| 398 class _PropertyTypeInfo(_Enum): | |
| 399 def __init__(self, is_fundamental, name): | |
| 400 _Enum.__init__(self, name) | |
| 401 self.is_fundamental = is_fundamental | |
| 402 | |
| 377 class PropertyType(object): | 403 class PropertyType(object): |
| 378 """Enum of different types of properties/parameters. | 404 """Enum of different types of properties/parameters. |
| 379 """ | 405 """ |
| 380 INTEGER = _PropertyTypeInfo(True, "INTEGER") | 406 INTEGER = _PropertyTypeInfo(True, "INTEGER") |
| 381 INT64 = _PropertyTypeInfo(True, "INT64") | 407 INT64 = _PropertyTypeInfo(True, "INT64") |
| 382 DOUBLE = _PropertyTypeInfo(True, "DOUBLE") | 408 DOUBLE = _PropertyTypeInfo(True, "DOUBLE") |
| 383 BOOLEAN = _PropertyTypeInfo(True, "BOOLEAN") | 409 BOOLEAN = _PropertyTypeInfo(True, "BOOLEAN") |
| 384 STRING = _PropertyTypeInfo(True, "STRING") | 410 STRING = _PropertyTypeInfo(True, "STRING") |
| 385 ENUM = _PropertyTypeInfo(False, "ENUM") | 411 ENUM = _PropertyTypeInfo(False, "ENUM") |
| 386 ARRAY = _PropertyTypeInfo(False, "ARRAY") | 412 ARRAY = _PropertyTypeInfo(False, "ARRAY") |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 """ | 480 """ |
| 455 model.properties = OrderedDict() | 481 model.properties = OrderedDict() |
| 456 for name, property_json in json.get('properties', {}).items(): | 482 for name, property_json in json.get('properties', {}).items(): |
| 457 model.properties[name] = Property( | 483 model.properties[name] = Property( |
| 458 model, | 484 model, |
| 459 name, | 485 name, |
| 460 property_json, | 486 property_json, |
| 461 namespace, | 487 namespace, |
| 462 from_json=from_json, | 488 from_json=from_json, |
| 463 from_client=from_client) | 489 from_client=from_client) |
| 490 | |
| 491 class _PlatformInfo(_Enum): | |
| 492 def __init__(self, name): | |
| 493 _Enum.__init__(self, name) | |
| 494 | |
| 495 class Platforms(object): | |
| 496 """Enum of the possible platforms. | |
| 497 """ | |
| 498 CHROMEOS = _PlatformInfo("chromeos") | |
| 499 CHROMEOS_TOUCH = _PlatformInfo("chromeos_touch") | |
| 500 LINUX = _PlatformInfo("linux") | |
| 501 MAC = _PlatformInfo("mac") | |
| 502 WIN = _PlatformInfo("win") | |
| 503 | |
| 504 def _GetPlatforms(json): | |
| 505 if 'platforms' not in json: | |
| 506 return None | |
| 507 platforms = [] | |
| 508 for platform_name in json['platforms']: | |
| 509 for platform_enum in _Enum.GetAll(Platforms): | |
| 510 if platform_name == platform_enum.name: | |
| 511 platforms.append(platform_enum) | |
| 512 break | |
| 513 return platforms | |
| OLD | NEW |