Chromium Code Reviews| Index: chrome/common/extensions/docs/server2/api_data_source.py |
| diff --git a/chrome/common/extensions/docs/server2/api_data_source.py b/chrome/common/extensions/docs/server2/api_data_source.py |
| index 6fdc6f6abd6d575845b47cd4a2e6e8c866077d3c..477dca2ed20e0d41e86547c82e7f9e00c1611f41 100644 |
| --- a/chrome/common/extensions/docs/server2/api_data_source.py |
| +++ b/chrome/common/extensions/docs/server2/api_data_source.py |
| @@ -127,19 +127,18 @@ class _APINodeCursor(object): |
| self._AssertIsValidCategory(self._lookup_path[-2]) |
| return self._lookup_path[:-2] |
| - def _LookupNodeAvailability(self): |
| + def _LookupNodeAvailability(self, lookup_path): |
| '''Returns the ChannelInfo object for this node. |
| ''' |
| return self._node_availabilities.Lookup(self._namespace_name, |
| - *self._lookup_path).annotation |
| + *lookup_path).annotation |
| def _LookupParentNodeAvailability(self): |
| '''Returns the ChannelInfo object for this node's parent. |
| ''' |
| - return self._node_availabilities.Lookup(self._namespace_name, |
| - *self._GetParentPath()).annotation |
| + return self._LookupNodeAvailability(self._GetParentPath()) |
|
not at google - send to devlin
2014/07/02 22:14:34
could you make a bunch of these @classmethod-s to
ahernandez
2014/07/02 22:25:47
I don't understand what you mean.
ahernandez
2014/07/02 22:27:22
Actually, my confusion has ended.
|
| - def _CheckNamespacePrefix(self): |
| + def _CheckNamespacePrefix(self, lookup_path): |
| '''API schemas may prepend the namespace name to top-level types |
| (e.g. declarativeWebRequest > types > declarativeWebRequest.IgnoreRules), |
| but just the base name (here, 'IgnoreRules') will be in the |lookup_path|. |
| @@ -147,44 +146,44 @@ class _APINodeCursor(object): |
| ''' |
| # lookup_path[0] is always the node category (e.g. types, functions, etc.). |
| # Thus, lookup_path[1] is always the top-level node name. |
| - self._AssertIsValidCategory(self._lookup_path[0]) |
| - base_name = self._lookup_path[1] |
| - self._lookup_path[1] = '%s.%s' % (self._namespace_name, base_name) |
| + self._AssertIsValidCategory(lookup_path[0]) |
| + base_name = lookup_path[1] |
| + lookup_path[1] = '%s.%s' % (self._namespace_name, base_name) |
| try: |
| - node_availability = self._LookupNodeAvailability() |
| + node_availability = self._LookupNodeAvailability(lookup_path) |
| if node_availability is not None: |
| return node_availability |
| finally: |
| # Restore lookup_path. |
| - self._lookup_path[1] = base_name |
| + lookup_path[1] = base_name |
| return None |
| - def _CheckEventCallback(self): |
| + def _CheckEventCallback(self, lookup_path): |
| '''Within API schemas, an event has a list of 'properties' that the event's |
| callback expects. The callback itself is not explicitly represented in the |
| schema. However, when creating an event node in _JSCModel, a callback node |
| is generated and acts as the parent for the event's properties. |
| Modify |lookup_path| to check the original schema format. |
| ''' |
| - if 'events' in self._lookup_path: |
| - assert 'callback' in self._lookup_path |
| - callback_index = self._lookup_path.index('callback') |
| + if 'events' in lookup_path: |
| + assert 'callback' in lookup_path |
| + callback_index = lookup_path.index('callback') |
| try: |
| - self._lookup_path.pop(callback_index) |
| - node_availability = self._LookupNodeAvailability() |
| + lookup_path.pop(callback_index) |
| + node_availability = self._LookupNodeAvailability(lookup_path) |
| finally: |
| - self._lookup_path.insert(callback_index, 'callback') |
| + lookup_path.insert(callback_index, 'callback') |
| return node_availability |
| return None |
| - def _LookupAvailability(self): |
| + def _LookupAvailability(self, lookup_path): |
| '''Runs all the lookup checks on self._lookup_path and |
| returns the node availability if found, None otherwise. |
| ''' |
| for lookup in (self._LookupNodeAvailability, |
| self._CheckEventCallback, |
| self._CheckNamespacePrefix): |
| - node_availability = lookup() |
| + node_availability = lookup(lookup_path) |
| if node_availability is not None: |
| return node_availability |
| return None |
| @@ -192,18 +191,13 @@ class _APINodeCursor(object): |
| def GetAvailability(self): |
| '''Returns availability information for this node. |
| ''' |
| - node_availability = self._LookupAvailability() |
| + node_availability = self._LookupAvailability(self._lookup_path) |
| if node_availability is None: |
| logging.warning('No availability found for: %s > %s' % |
| (self._namespace_name, ' > '.join(self._lookup_path))) |
| return None |
| - try: |
| - current_path = self._lookup_path |
| - self._lookup_path = self._GetParentPath() |
| - parent_node_availability = self._LookupAvailability() |
| - finally: |
| - self._lookup_path = current_path |
| + parent_node_availability = self._LookupAvailability(self._GetParentPath()) |
| # If the parent node availability couldn't be found, something |
| # is very wrong. |
| assert parent_node_availability is not None |
| @@ -287,19 +281,20 @@ class _JSCModel(object): |
| def _IsExperimental(self): |
| return self._namespace.name.startswith('experimental') |
| - def _GenerateTypes(self, types): |
| + def _GenerateTypes(self, types, no_gen=False): |
| with self._current_node.Descend('types'): |
| - return [self._GenerateType(t) for t in types] |
| + return [self._GenerateType(t, no_gen=no_gen) for t in types] |
| - def _GenerateType(self, type_): |
| + def _GenerateType(self, type_, no_gen=False): |
| with self._current_node.Descend(type_.simple_name): |
| type_dict = { |
| 'name': type_.simple_name, |
| 'description': type_.description, |
| - 'properties': self._GenerateProperties(type_.properties), |
| + 'properties': self._GenerateProperties(type_.properties, no_gen=no_gen), |
|
ahernandez
2014/07/03 02:04:14
I think eliminating the no_gen passing will make t
not at google - send to devlin
2014/07/07 15:10:31
What about if no_gen took a tuple of properties to
ahernandez
2014/07/07 20:04:56
Doing that cleans up a good portion of the code, b
|
| 'functions': self._GenerateFunctions(type_.functions), |
| 'events': self._GenerateEvents(type_.events), |
| 'id': _CreateId(type_, 'type'), |
| + 'availability': None if no_gen else self._GetAvailabilityTemplate() |
|
not at google - send to devlin
2014/07/02 22:14:34
why do you need to do this no_gen stuff?
in any c
ahernandez
2014/07/02 22:25:47
Certain nodes shouldn't have availability generate
|
| } |
| self._RenderTypeInformation(type_, type_dict) |
| return type_dict |
| @@ -321,9 +316,11 @@ class _JSCModel(object): |
| } |
| self._AddCommonProperties(function_dict, function) |
| if function.returns: |
| - function_dict['returns'] = self._GenerateType(function.returns) |
| - for param in function.params: |
| - function_dict['parameters'].append(self._GenerateProperty(param)) |
| + function_dict['returns'] = self._GenerateType(function.returns, |
| + no_gen=True) |
| + with self._current_node.Descend('parameters'): |
| + for param in function.params: |
| + function_dict['parameters'].append(self._GenerateProperty(param)) |
| if function.callback is not None: |
| # Show the callback as an extra parameter. |
| function_dict['parameters'].append( |
| @@ -347,7 +344,8 @@ class _JSCModel(object): |
| event_dict = { |
| 'name': event.simple_name, |
| 'description': event.description, |
| - 'filters': [self._GenerateProperty(f) for f in event.filters], |
| + 'filters': [self._GenerateProperty(f, no_gen=True) |
| + for f in event.filters], |
| 'conditions': [self._GetLink(condition) |
| for condition in event.conditions], |
| 'actions': [self._GetLink(action) for action in event.actions], |
| @@ -356,6 +354,7 @@ class _JSCModel(object): |
| 'properties': [], |
| 'id': _CreateId(event, 'event'), |
| 'byName': {}, |
| + 'availability': self._GetAvailabilityTemplate() |
| } |
| self._AddCommonProperties(event_dict, event) |
| # Add the Event members to each event in this object. |
| @@ -382,7 +381,7 @@ class _JSCModel(object): |
| if event.supports_dom: |
| # Treat params as properties of the custom Event object associated with |
| # this DOM Event. |
| - event_dict['properties'] += [self._GenerateProperty(param) |
| + event_dict['properties'] += [self._GenerateProperty(param, no_gen=True) |
| for param in event.params] |
| return event_dict |
| @@ -395,58 +394,67 @@ class _JSCModel(object): |
| 'optional': callback.optional, |
| 'parameters': [] |
| } |
| - for param in callback.params: |
| - callback_dict['parameters'].append(self._GenerateProperty(param)) |
| + with self._current_node.Descend('parameters', |
| + callback.simple_name, |
| + 'parameters'): |
| + for param in callback.params: |
| + callback_dict['parameters'].append(self._GenerateProperty(param)) |
| if (len(callback_dict['parameters']) > 0): |
| callback_dict['parameters'][-1]['last'] = True |
| return callback_dict |
| - def _GenerateProperties(self, properties): |
| - return [self._GenerateProperty(v) for v in properties.values()] |
| - |
| - def _GenerateProperty(self, property_): |
| - if not hasattr(property_, 'type_'): |
| - for d in dir(property_): |
| - if not d.startswith('_'): |
| - print ('%s -> %s' % (d, getattr(property_, d))) |
| - type_ = property_.type_ |
| - |
| - # Make sure we generate property info for arrays, too. |
| - # TODO(kalman): what about choices? |
| - if type_.property_type == model.PropertyType.ARRAY: |
| - properties = type_.item_type.properties |
| - else: |
| - properties = type_.properties |
| - |
| - property_dict = { |
| - 'name': property_.simple_name, |
| - 'optional': property_.optional, |
| - 'description': property_.description, |
| - 'properties': self._GenerateProperties(type_.properties), |
| - 'functions': self._GenerateFunctions(type_.functions), |
| - 'parameters': [], |
| - 'returns': None, |
| - 'id': _CreateId(property_, 'property'), |
| - } |
| - self._AddCommonProperties(property_dict, property_) |
| - |
| - if type_.property_type == model.PropertyType.FUNCTION: |
| - function = type_.function |
| - for param in function.params: |
| - property_dict['parameters'].append(self._GenerateProperty(param)) |
| - if function.returns: |
| - property_dict['returns'] = self._GenerateType(function.returns) |
| + def _GenerateProperties(self, properties, no_gen=False): |
| + with self._current_node.Descend('properties'): |
| + return [self._GenerateProperty(v, no_gen=no_gen) |
| + for v in properties.values()] |
| + |
| + def _GenerateProperty(self, property_, no_gen=False): |
| + with self._current_node.Descend(property_.simple_name): |
| + if not hasattr(property_, 'type_'): |
| + for d in dir(property_): |
| + if not d.startswith('_'): |
| + print ('%s -> %s' % (d, getattr(property_, d))) |
| + type_ = property_.type_ |
| + |
| + # Make sure we generate property info for arrays, too. |
| + # TODO(kalman): what about choices? |
| + if type_.property_type == model.PropertyType.ARRAY: |
| + properties = type_.item_type.properties |
| + else: |
| + properties = type_.properties |
| - value = property_.value |
| - if value is not None: |
| - if isinstance(value, int): |
| - property_dict['value'] = _FormatValue(value) |
| + property_dict = { |
| + 'name': property_.simple_name, |
| + 'optional': property_.optional, |
| + 'description': property_.description, |
| + 'properties': self._GenerateProperties(type_.properties, no_gen=True), |
| + 'functions': self._GenerateFunctions(type_.functions), |
| + 'parameters': [], |
| + 'returns': None, |
| + 'id': _CreateId(property_, 'property'), |
| + 'availability': None if no_gen else self._GetAvailabilityTemplate() |
| + } |
| + self._AddCommonProperties(property_dict, property_) |
| + |
| + if type_.property_type == model.PropertyType.FUNCTION: |
| + function = type_.function |
| + with self._current_node.Descend('parameters'): |
| + for param in function.params: |
| + property_dict['parameters'].append(self._GenerateProperty(param)) |
| + if function.returns: |
| + property_dict['returns'] = self._GenerateType(function.returns, |
| + no_gen=True) |
| + |
| + value = property_.value |
| + if value is not None: |
| + if isinstance(value, int): |
| + property_dict['value'] = _FormatValue(value) |
| + else: |
| + property_dict['value'] = value |
| else: |
| - property_dict['value'] = value |
| - else: |
| - self._RenderTypeInformation(type_, property_dict) |
| + self._RenderTypeInformation(type_, property_dict) |
| - return property_dict |
| + return property_dict |
| def _GenerateCallbackProperty(self, callback): |
| property_dict = { |
| @@ -465,7 +473,7 @@ class _JSCModel(object): |
| def _RenderTypeInformation(self, type_, dst_dict): |
| dst_dict['is_object'] = type_.property_type == model.PropertyType.OBJECT |
| if type_.property_type == model.PropertyType.CHOICES: |
| - dst_dict['choices'] = self._GenerateTypes(type_.choices) |
| + dst_dict['choices'] = self._GenerateTypes(type_.choices, no_gen=True) |
| # We keep track of which == last for knowing when to add "or" between |
| # choices in templates. |
| if len(dst_dict['choices']) > 0: |
| @@ -473,7 +481,7 @@ class _JSCModel(object): |
| elif type_.property_type == model.PropertyType.REF: |
| dst_dict['link'] = self._GetLink(type_.ref_type) |
| elif type_.property_type == model.PropertyType.ARRAY: |
| - dst_dict['array'] = self._GenerateType(type_.item_type) |
| + dst_dict['array'] = self._GenerateType(type_.item_type, no_gen=True) |
| elif type_.property_type == model.PropertyType.ENUM: |
| dst_dict['enum_values'] = [ |
| {'name': value.name, 'description': value.description} |