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 9695fd6dcebed8a20b8653c536f31dafa4272e1b..5a620865b71656564167d36d3471880e9585b4ef 100644 |
| --- a/chrome/common/extensions/docs/server2/api_data_source.py |
| +++ b/chrome/common/extensions/docs/server2/api_data_source.py |
| @@ -5,7 +5,7 @@ |
| import copy |
| import logging |
| import os |
| -import collections |
| +from collections import defaultdict, Mapping |
| import third_party.json_schema_compiler.json_parse as json_parse |
| import third_party.json_schema_compiler.model as model |
| @@ -28,6 +28,53 @@ def _RemoveNoDocs(item): |
| item.remove(i) |
| return False |
| +def _DetectInlineableIdl(schema): |
| + """Look for documents that are only referenced once and mark them as inline. |
| + Actual inlining is done by _InlineDocs. |
| + """ |
| + if not schema.get('types'): |
| + return |
| + |
| + banned = frozenset(('returns', 'value', 'items')) |
|
not at google - send to devlin
2013/05/14 06:12:25
as discussed - let's remove 'returns' and 'items'
|
| + refcounts = defaultdict(int) |
| + # Use an explicit stack instead of recursion. |
| + stack = [schema] |
| + |
| + while stack: |
| + node = stack.pop() |
| + if isinstance(node, list): |
| + for i in node: |
| + stack.append(i) |
| + elif isinstance(node, Mapping): |
| + if node.get('$ref'): |
|
not at google - send to devlin
2013/05/14 05:37:56
'$ref' in node?
|
| + refcounts[node['$ref']] += 1 |
| + for k, v in node.iteritems(): |
| + if k not in banned: |
| + stack.append(v) |
| + |
| + # Do a recursive search of the json looking for ref entries and counting them. |
| + # def search_for_refs(node): |
| + # if isinstance(node, list): |
| + # for i in node: |
| + # search_for_refs(i) |
| + # elif isinstance(node, Mapping): |
| + # if node.get('nodoc'): |
| + # return |
| + # if node.get('$ref'): |
| + # refcounts[node['$ref']] += 1 |
| + # for k, v in node.iteritems(): |
| + # print '\t', k |
| + # if k == 'returns' or k == 'value' or k == 'items': |
| + # continue |
| + # search_for_refs(v) |
| + # search_for_refs(schema) |
| + |
| + for doc in schema['types']: |
| + if refcounts[doc['id']] == 1: |
| + # TODO(jshumway): get rid of this print statement. |
| + # if not doc.get('inline_doc'): |
| + # print 'Inlining %s' % doc['id'] |
| + doc['inline_doc'] = True |
| def _InlineDocs(schema): |
| """Replace '$ref's that refer to inline_docs with the json for those docs. |
| @@ -55,7 +102,7 @@ def _InlineDocs(schema): |
| if isinstance(node, list): |
| for i in node: |
| apply_inline(i) |
| - elif isinstance(node, collections.Mapping): |
| + elif isinstance(node, Mapping): |
| ref = node.get('$ref') |
| if ref and ref in inline_docs: |
| node.update(inline_docs[ref]) |
| @@ -80,13 +127,15 @@ class _JSCModel(object): |
| """Uses a Model from the JSON Schema Compiler and generates a dict that |
| a Handlebar template can use for a data source. |
| """ |
| - def __init__(self, json, ref_resolver, disable_refs): |
| + def __init__(self, json, ref_resolver, disable_refs, idl=False): |
| self._ref_resolver = ref_resolver |
| self._disable_refs = disable_refs |
| clean_json = copy.deepcopy(json) |
| if _RemoveNoDocs(clean_json): |
| self._namespace = None |
| else: |
| + if idl: |
| + _DetectInlineableIdl(clean_json) |
| _InlineDocs(clean_json) |
| self._namespace = model.Namespace(clean_json, clean_json['namespace']) |
| @@ -380,7 +429,8 @@ class APIDataSource(object): |
| return _JSCModel( |
| idl_schema.IDLSchema(idl).process()[0], |
| self._ref_resolver_factory.Create() if not disable_refs else None, |
| - disable_refs).ToDict() |
| + disable_refs, |
| + idl=True).ToDict() |
| def _GetIDLNames(self, base_dir, apis): |
| return self._GetExtNames(apis, ['idl']) |