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 |
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 |