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, include_compiler_options=False): | 29 def AddNamespace(self, json, source_file): |
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, | 32 namespace = Namespace(json, source_file) |
33 source_file, | |
34 include_compiler_options=include_compiler_options) | |
35 self.namespaces[namespace.name] = namespace | 33 self.namespaces[namespace.name] = namespace |
36 return namespace | 34 return namespace |
37 | 35 |
38 class Namespace(object): | 36 class Namespace(object): |
39 """An API namespace. | 37 """An API namespace. |
40 | 38 |
41 Properties: | 39 Properties: |
42 - |name| the name of the namespace | 40 - |name| the name of the namespace |
43 - |unix_name| the unix_name of the namespace | 41 - |unix_name| the unix_name of the namespace |
44 - |source_file| the file that contained the namespace definition | 42 - |source_file| the file that contained the namespace definition |
45 - |source_file_dir| the directory component of |source_file| | 43 - |source_file_dir| the directory component of |source_file| |
46 - |source_file_filename| the filename component of |source_file| | 44 - |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 | |
49 - |types| a map of type names to their model.Type | 45 - |types| a map of type names to their model.Type |
50 - |functions| a map of function names to their model.Function | 46 - |functions| a map of function names to their model.Function |
51 - |events| a map of event names to their model.Function | 47 - |events| a map of event names to their model.Function |
52 - |properties| a map of property names to their model.Property | 48 - |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 | |
55 """ | 49 """ |
56 def __init__(self, json, source_file, include_compiler_options=False): | 50 def __init__(self, json, source_file): |
57 self.name = json['namespace'] | 51 self.name = json['namespace'] |
58 self.unix_name = UnixName(self.name) | 52 self.unix_name = UnixName(self.name) |
59 self.source_file = source_file | 53 self.source_file = source_file |
60 self.source_file_dir, self.source_file_filename = os.path.split(source_file) | 54 self.source_file_dir, self.source_file_filename = os.path.split(source_file) |
61 self.parent = None | 55 self.parent = None |
62 self.platforms = _GetPlatforms(json) | |
63 _AddTypes(self, json, self) | 56 _AddTypes(self, json, self) |
64 _AddFunctions(self, json, self) | 57 _AddFunctions(self, json, self) |
65 _AddEvents(self, json, self) | 58 _AddEvents(self, json, self) |
66 _AddProperties(self, json, self) | 59 _AddProperties(self, json, self) |
67 if include_compiler_options: | |
68 self.compiler_options = json.get('compiler_options', {}) | |
69 | 60 |
70 class Type(object): | 61 class Type(object): |
71 """A Type defined in the json. | 62 """A Type defined in the json. |
72 | 63 |
73 Properties: | 64 Properties: |
74 - |name| the type name | 65 - |name| the type name |
75 - |description| the description of the type (if provided) | 66 - |description| the description of the type (if provided) |
76 - |properties| a map of property unix_names to their model.Property | 67 - |properties| a map of property unix_names to their model.Property |
77 - |functions| a map of function names to their model.Function | 68 - |functions| a map of function names to their model.Function |
78 - |events| a map of event names to their model.Event | 69 - |events| a map of event names to their model.Event |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 additional_properties_key, | 120 additional_properties_key, |
130 additional_properties, | 121 additional_properties, |
131 namespace, | 122 namespace, |
132 is_additional_properties=True) | 123 is_additional_properties=True) |
133 | 124 |
134 class Function(object): | 125 class Function(object): |
135 """A Function defined in the API. | 126 """A Function defined in the API. |
136 | 127 |
137 Properties: | 128 Properties: |
138 - |name| the function name | 129 - |name| the function name |
139 - |platforms| if not None, the list of platforms that the function is | |
140 available to | |
141 - |params| a list of parameters to the function (order matters). A separate | 130 - |params| a list of parameters to the function (order matters). A separate |
142 parameter is used for each choice of a 'choices' parameter | 131 parameter is used for each choice of a 'choices' parameter. |
143 - |description| a description of the function (if provided) | 132 - |description| a description of the function (if provided) |
144 - |callback| the callback parameter to the function. There should be exactly | 133 - |callback| the callback parameter to the function. There should be exactly |
145 one | 134 one |
146 - |optional| whether the Function is "optional"; this only makes sense to be | 135 - |optional| whether the Function is "optional"; this only makes sense to be |
147 present when the Function is representing a callback property | 136 present when the Function is representing a callback property. |
148 - |simple_name| the name of this Function without a namespace | 137 - |simple_name| the name of this Function without a namespace |
149 """ | 138 """ |
150 def __init__(self, | 139 def __init__(self, |
151 parent, | 140 parent, |
152 json, | 141 json, |
153 namespace, | 142 namespace, |
154 from_json=False, | 143 from_json=False, |
155 from_client=False): | 144 from_client=False): |
156 self.name = json['name'] | 145 self.name = json['name'] |
157 self.simple_name = _StripNamespace(self.name, namespace) | 146 self.simple_name = _StripNamespace(self.name, namespace) |
158 self.platforms = _GetPlatforms(json) | |
159 self.params = [] | 147 self.params = [] |
160 self.description = json.get('description') | 148 self.description = json.get('description') |
161 self.callback = None | 149 self.callback = None |
162 self.optional = json.get('optional', False) | 150 self.optional = json.get('optional', False) |
163 self.parent = parent | 151 self.parent = parent |
164 self.nocompile = json.get('nocompile') | 152 self.nocompile = json.get('nocompile') |
165 options = json.get('options', {}) | 153 options = json.get('options', {}) |
166 self.conditions = options.get('conditions', []) | 154 self.conditions = options.get('conditions', []) |
167 self.actions = options.get('actions', []) | 155 self.actions = options.get('actions', []) |
168 self.supports_listeners = options.get('supportsListeners', True) | 156 self.supports_listeners = options.get('supportsListeners', True) |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 def Copy(self): | 350 def Copy(self): |
363 """Makes a copy of this model.Property object and allow the unix_name to be | 351 """Makes a copy of this model.Property object and allow the unix_name to be |
364 set again. | 352 set again. |
365 """ | 353 """ |
366 property_copy = copy.copy(self) | 354 property_copy = copy.copy(self) |
367 property_copy._unix_name_used = False | 355 property_copy._unix_name_used = False |
368 return property_copy | 356 return property_copy |
369 | 357 |
370 unix_name = property(GetUnixName, SetUnixName) | 358 unix_name = property(GetUnixName, SetUnixName) |
371 | 359 |
372 class _Enum(object): | 360 class _PropertyTypeInfo(object): |
373 """Superclass for enum types with a "name" field, setting up repr/eq/ne. | 361 """This class is not an inner class of |PropertyType| so it can be pickled. |
374 Enums need to do this so that equality/non-equality work over pickling. | |
375 """ | 362 """ |
376 | 363 def __init__(self, is_fundamental, name): |
377 @staticmethod | 364 self.is_fundamental = is_fundamental |
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): | |
387 self.name = name | 365 self.name = name |
388 | 366 |
389 def __repr(self): | 367 def __repr__(self): |
390 return self.name | 368 return self.name |
391 | 369 |
392 def __eq__(self, other): | 370 def __eq__(self, other): |
393 return type(other) == type(self) and other.name == self.name | 371 return isinstance(other, _PropertyTypeInfo) and self.name == other.name |
394 | 372 |
395 def __ne__(self, other): | 373 def __ne__(self, other): |
| 374 # Yes. You seriously do need this. |
396 return not (self == other) | 375 return not (self == other) |
397 | 376 |
398 class _PropertyTypeInfo(_Enum): | |
399 def __init__(self, is_fundamental, name): | |
400 _Enum.__init__(self, name) | |
401 self.is_fundamental = is_fundamental | |
402 | |
403 class PropertyType(object): | 377 class PropertyType(object): |
404 """Enum of different types of properties/parameters. | 378 """Enum of different types of properties/parameters. |
405 """ | 379 """ |
406 INTEGER = _PropertyTypeInfo(True, "INTEGER") | 380 INTEGER = _PropertyTypeInfo(True, "INTEGER") |
407 INT64 = _PropertyTypeInfo(True, "INT64") | 381 INT64 = _PropertyTypeInfo(True, "INT64") |
408 DOUBLE = _PropertyTypeInfo(True, "DOUBLE") | 382 DOUBLE = _PropertyTypeInfo(True, "DOUBLE") |
409 BOOLEAN = _PropertyTypeInfo(True, "BOOLEAN") | 383 BOOLEAN = _PropertyTypeInfo(True, "BOOLEAN") |
410 STRING = _PropertyTypeInfo(True, "STRING") | 384 STRING = _PropertyTypeInfo(True, "STRING") |
411 ENUM = _PropertyTypeInfo(False, "ENUM") | 385 ENUM = _PropertyTypeInfo(False, "ENUM") |
412 ARRAY = _PropertyTypeInfo(False, "ARRAY") | 386 ARRAY = _PropertyTypeInfo(False, "ARRAY") |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 """ | 454 """ |
481 model.properties = OrderedDict() | 455 model.properties = OrderedDict() |
482 for name, property_json in json.get('properties', {}).items(): | 456 for name, property_json in json.get('properties', {}).items(): |
483 model.properties[name] = Property( | 457 model.properties[name] = Property( |
484 model, | 458 model, |
485 name, | 459 name, |
486 property_json, | 460 property_json, |
487 namespace, | 461 namespace, |
488 from_json=from_json, | 462 from_json=from_json, |
489 from_client=from_client) | 463 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 |