Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: chrome/common/extensions/docs/server2/schema_util.py

Issue 532423002: Inlining references to internal APIs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removing extensionTypes from chrome api features (still in extension api features) Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 from collections import defaultdict, Mapping
6 import traceback
7
8 from third_party.json_schema_compiler import json_parse, idl_schema, idl_parser
9
10
11 def RemoveNoDocs(item):
12 '''Removes nodes that should not be rendered from an API schema.
13 '''
14 if json_parse.IsDict(item):
15 if item.get('nodoc', False):
16 return True
17 for key, value in item.items():
18 if RemoveNoDocs(value):
19 del item[key]
20 elif type(item) == list:
21 to_remove = []
22 for i in item:
23 if RemoveNoDocs(i):
24 to_remove.append(i)
25 for i in to_remove:
26 item.remove(i)
27 return False
28
29
30 def DetectInlineableTypes(schema):
31 '''Look for documents that are only referenced once and mark them as inline.
32 Actual inlining is done by _InlineDocs.
33 '''
34 if not schema.get('types'):
35 return
36
37 ignore = frozenset(('value', 'choices'))
38 refcounts = defaultdict(int)
39 # Use an explicit stack instead of recursion.
40 stack = [schema]
41
42 while stack:
43 node = stack.pop()
44 if isinstance(node, list):
45 stack.extend(node)
46 elif isinstance(node, Mapping):
47 if '$ref' in node:
48 refcounts[node['$ref']] += 1
49 stack.extend(v for k, v in node.iteritems() if k not in ignore)
50
51 for type_ in schema['types']:
52 if not 'noinline_doc' in type_:
53 if refcounts[type_['id']] == 1:
54 type_['inline_doc'] = True
55
56
57 def InlineDocs(schema, retain_inlined_types):
58 '''Replace '$ref's that refer to inline_docs with the json for those docs.
59 If |retain_inlined_types| is False, then the inlined nodes are removed
60 from the schema.
61 '''
62 types = schema.get('types')
63 if types is None:
64 return
65
66 inline_docs = {}
67 types_without_inline_doc = []
68
69 # Gather the types with inline_doc.
70 for type_ in types:
71 if type_.get('inline_doc'):
72 inline_docs[type_['id']] = type_
73 if not retain_inlined_types:
74 for k in ('description', 'id', 'inline_doc'):
75 type_.pop(k, None)
76 else:
77 types_without_inline_doc.append(type_)
78 if not retain_inlined_types:
79 schema['types'] = types_without_inline_doc
80
81 def apply_inline(node):
82 if isinstance(node, list):
83 for i in node:
84 apply_inline(i)
85 elif isinstance(node, Mapping):
86 ref = node.get('$ref')
87 if ref and ref in inline_docs:
88 node.update(inline_docs[ref])
89 del node['$ref']
90 for k, v in node.iteritems():
91 apply_inline(v)
92
93 apply_inline(schema)
94
95
96 def ProcessSchema(path, file_data, retain_inlined_types=False):
97 '''Parses |file_data| using a method determined by checking the
98 extension of the file at the given |path|. Then, trims 'nodoc' and if
99 |retain_inlined_types| is given and False, removes inlineable types from
100 the parsed schema data.
101 '''
102 def trim_and_inline(schema, is_idl=False):
103 '''Modifies an API schema in place by removing nodes that shouldn't be
104 documented and inlining schema types that are only referenced once.
105 '''
106 if RemoveNoDocs(schema):
107 # A return of True signifies that the entire schema should not be
108 # documented. Otherwise, only nodes that request 'nodoc' are removed.
109 return None
110 if is_idl:
111 DetectInlineableTypes(schema)
112 InlineDocs(schema, retain_inlined_types)
113 return schema
114
115 if path.endswith('.idl'):
116 idl = idl_schema.IDLSchema(idl_parser.IDLParser().ParseData(file_data))
117 # Wrap the result in a list so that it behaves like JSON API data.
118 return [trim_and_inline(idl.process()[0], is_idl=True)]
119
120 try:
121 schemas = json_parse.Parse(file_data)
122 except:
123 raise ValueError('Cannot parse "%s" as JSON:\n%s' %
124 (path, traceback.format_exc()))
125 for schema in schemas:
126 # Schemas could consist of one API schema (data for a specific API file)
127 # or multiple (data from extension_api.json).
128 trim_and_inline(schema)
129 return schemas
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698