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

Side by Side Diff: tools/json_schema_compiler/js_externs_generator.py

Issue 2601333002: Update json_schema_compiler to handle the Automation extension API (Closed)
Patch Set: Rebase Created 3 years, 11 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
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 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 Generator that produces an externs file for the Closure Compiler. 5 Generator that produces an externs file for the Closure Compiler.
6 Note: This is a work in progress, and generated externs may require tweaking. 6 Note: This is a work in progress, and generated externs may require tweaking.
7 7
8 See https://developers.google.com/closure/compiler/docs/api-tutorial3#externs 8 See https://developers.google.com/closure/compiler/docs/api-tutorial3#externs
9 """ 9 """
10 10
(...skipping 12 matching lines...) Expand all
23 // See https://chromium.googlesource.com/chromium/src/+/master/docs/closure_comp ilation.md 23 // See https://chromium.googlesource.com/chromium/src/+/master/docs/closure_comp ilation.md
24 """ 24 """
25 25
26 class JsExternsGenerator(object): 26 class JsExternsGenerator(object):
27 def Generate(self, namespace): 27 def Generate(self, namespace):
28 return _Generator(namespace).Generate() 28 return _Generator(namespace).Generate()
29 29
30 class _Generator(object): 30 class _Generator(object):
31 def __init__(self, namespace): 31 def __init__(self, namespace):
32 self._namespace = namespace 32 self._namespace = namespace
33 self._class_name = None
33 self._js_util = JsUtil() 34 self._js_util = JsUtil()
34 35
35 def Generate(self): 36 def Generate(self):
36 """Generates a Code object with the schema for the entire namespace. 37 """Generates a Code object with the schema for the entire namespace.
37 """ 38 """
38 c = Code() 39 c = Code()
39 (c.Append(self._GetHeader(sys.argv[0], self._namespace.name)) 40 (c.Append(self._GetHeader(sys.argv[0], self._namespace.name))
40 .Append()) 41 .Append())
41 42
42 self._AppendNamespaceObject(c) 43 self._AppendNamespaceObject(c)
(...skipping 29 matching lines...) Expand all
72 c.Append() 73 c.Append()
73 74
74 def _AppendEnumJsDoc(self, c, js_type): 75 def _AppendEnumJsDoc(self, c, js_type):
75 """ Given an Enum Type object, generates the Code for the enum's definition. 76 """ Given an Enum Type object, generates the Code for the enum's definition.
76 """ 77 """
77 (c.Sblock(line='/**', line_prefix=' * ') 78 (c.Sblock(line='/**', line_prefix=' * ')
78 .Append('@enum {string}') 79 .Append('@enum {string}')
79 .Append(self._js_util.GetSeeLink(self._namespace.name, 'type', 80 .Append(self._js_util.GetSeeLink(self._namespace.name, 'type',
80 js_type.simple_name)) 81 js_type.simple_name))
81 .Eblock(' */')) 82 .Eblock(' */'))
82 c.Append('chrome.%s.%s = {' % (self._namespace.name, js_type.name)) 83 c.Append('%s.%s = {' % (self._GetNamespace(), js_type.name))
83 84
84 def get_property_name(e): 85 def get_property_name(e):
85 # Enum properties are normified to be in ALL_CAPS_STYLE. 86 # Enum properties are normified to be in ALL_CAPS_STYLE.
86 # Assume enum '1ring-rulesThemAll'. 87 # Assume enum '1ring-rulesThemAll'.
87 # Transform to '1ring-rules_Them_All'. 88 # Transform to '1ring-rules_Them_All'.
88 e = re.sub(r'([a-z])([A-Z])', r'\1_\2', e) 89 e = re.sub(r'([a-z])([A-Z])', r'\1_\2', e)
89 # Transform to '1ring_rules_Them_All'. 90 # Transform to '1ring_rules_Them_All'.
90 e = re.sub(r'\W', '_', e) 91 e = re.sub(r'\W', '_', e)
91 # Transform to '_1ring_rules_Them_All'. 92 # Transform to '_1ring_rules_Them_All'.
92 e = re.sub(r'^(\d)', r'_\1', e) 93 e = re.sub(r'^(\d)', r'_\1', e)
93 # Transform to '_1RING_RULES_THEM_ALL'. 94 # Transform to '_1RING_RULES_THEM_ALL'.
94 return e.upper() 95 return e.upper()
95 96
96 c.Append('\n'.join( 97 c.Append('\n'.join(
97 [" %s: '%s'," % (get_property_name(v.name), v.name) 98 [" %s: '%s'," % (get_property_name(v.name), v.name)
98 for v in js_type.enum_values])) 99 for v in js_type.enum_values]))
99 c.Append('};') 100 c.Append('};')
100 101
101 def _IsTypeConstructor(self, js_type): 102 def _IsTypeConstructor(self, js_type):
102 """Returns true if the given type should be a @constructor. If this returns 103 """Returns true if the given type should be a @constructor. If this returns
103 false, the type is a typedef. 104 false, the type is a typedef.
104 """ 105 """
105 return any(prop.type_.property_type is PropertyType.FUNCTION 106 return any(prop.type_.property_type is PropertyType.FUNCTION
106 for prop in js_type.properties.values()) 107 for prop in js_type.properties.values())
107 108
108 def _AppendTypeJsDoc(self, c, js_type): 109 def _AppendTypeJsDoc(self, c, js_type, optional=False):
109 """Appends the documentation for a type as a Code. 110 """Appends the documentation for a type as a Code.
110 """ 111 """
111 c.Sblock(line='/**', line_prefix=' * ') 112 c.Sblock(line='/**', line_prefix=' * ')
112 113
113 if js_type.description: 114 if js_type.description:
114 for line in js_type.description.splitlines(): 115 for line in js_type.description.splitlines():
115 c.Append(line) 116 c.Append(line)
116 117
118 if js_type.jsexterns:
119 for line in js_type.jsexterns.splitlines():
120 c.Append(line)
121
117 is_constructor = self._IsTypeConstructor(js_type) 122 is_constructor = self._IsTypeConstructor(js_type)
118 if is_constructor: 123 if js_type.property_type is not PropertyType.OBJECT:
119 c.Comment('@constructor', comment_prefix = ' * ', wrap_indent=4) 124 self._js_util.AppendTypeJsDoc(c, self._namespace.name, js_type, optional)
125 elif is_constructor:
126 c.Comment('@constructor', comment_prefix = '', wrap_indent=4)
127 c.Comment('@private', comment_prefix = '', wrap_indent=4)
120 else: 128 else:
121 self._AppendTypedef(c, js_type.properties) 129 self._AppendTypedef(c, js_type.properties)
122 130
123 c.Append(self._js_util.GetSeeLink(self._namespace.name, 'type', 131 c.Append(self._js_util.GetSeeLink(self._namespace.name, 'type',
124 js_type.simple_name)) 132 js_type.simple_name))
125 c.Eblock(' */') 133 c.Eblock(' */')
126 134
127 var = 'chrome.%s.%s' % (js_type.namespace.name, js_type.simple_name) 135 var = '%s.%s' % (self._GetNamespace(), js_type.simple_name)
128 if is_constructor: var += ' = function() {}' 136 if is_constructor: var += ' = function() {}'
129 var += ';' 137 var += ';'
130 c.Append(var) 138 c.Append(var)
131 139
140 if is_constructor:
141 c.Append()
142 self._class_name = js_type.name
143 for prop in js_type.properties.values():
144 if prop.type_.property_type is PropertyType.FUNCTION:
145 self._AppendFunction(c, prop.type_.function)
146 else:
147 self._AppendTypeJsDoc(c, prop.type_, prop.optional)
148 c.Append()
149 self._class_name = None
150
132 def _AppendTypedef(self, c, properties): 151 def _AppendTypedef(self, c, properties):
133 """Given an OrderedDict of properties, Appends code containing a @typedef. 152 """Given an OrderedDict of properties, Appends code containing a @typedef.
134 """ 153 """
135 if not properties: return 154 if not properties: return
136 155
137 c.Append('@typedef {') 156 c.Append('@typedef {')
138 self._js_util.AppendObjectDefinition(c, self._namespace.name, properties, 157 self._js_util.AppendObjectDefinition(c, self._namespace.name, properties,
139 new_line=False) 158 new_line=False)
140 c.Append('}', new_line=False) 159 c.Append('}', new_line=False)
141 160
142 def _AppendFunction(self, c, function): 161 def _AppendFunction(self, c, function):
143 """Appends the code representing a function, including its documentation. 162 """Appends the code representing a function, including its documentation.
144 For example: 163 For example:
145 164
146 /** 165 /**
147 * @param {string} title The new title. 166 * @param {string} title The new title.
148 */ 167 */
149 chrome.window.setTitle = function(title) {}; 168 chrome.window.setTitle = function(title) {};
150 """ 169 """
151 self._js_util.AppendFunctionJsDoc(c, self._namespace.name, function) 170 self._js_util.AppendFunctionJsDoc(c, self._namespace.name, function)
152 params = self._GetFunctionParams(function) 171 params = self._GetFunctionParams(function)
153 c.Append('chrome.%s.%s = function(%s) {};' % (self._namespace.name, 172 c.Append('%s.%s = function(%s) {};' % (self._GetNamespace(),
154 function.name, params)) 173 function.name, params))
155 c.Append() 174 c.Append()
156 175
157 def _AppendEvent(self, c, event): 176 def _AppendEvent(self, c, event):
158 """Appends the code representing an event. 177 """Appends the code representing an event.
159 For example: 178 For example:
160 179
161 /** @type {!ChromeEvent} */ 180 /** @type {!ChromeEvent} */
162 chrome.bookmarks.onChildrenReordered; 181 chrome.bookmarks.onChildrenReordered;
163 """ 182 """
164 c.Sblock(line='/**', line_prefix=' * ') 183 c.Sblock(line='/**', line_prefix=' * ')
165 if (event.description): 184 if (event.description):
166 c.Comment(event.description, comment_prefix='') 185 c.Comment(event.description, comment_prefix='')
167 c.Append('@type {!ChromeEvent}') 186 c.Append('@type {!ChromeEvent}')
168 c.Append(self._js_util.GetSeeLink(self._namespace.name, 'event', 187 c.Append(self._js_util.GetSeeLink(self._namespace.name, 'event',
169 event.name)) 188 event.name))
170 c.Eblock(' */') 189 c.Eblock(' */')
171 c.Append('chrome.%s.%s;' % (self._namespace.name, event.name)) 190 c.Append('%s.%s;' % (self._GetNamespace(), event.name))
172 c.Append() 191 c.Append()
173 192
174 def _AppendNamespaceObject(self, c): 193 def _AppendNamespaceObject(self, c):
175 """Appends the code creating namespace object. 194 """Appends the code creating namespace object.
176 For example: 195 For example:
177 196
178 /** 197 /**
179 * @const 198 * @const
180 */ 199 */
181 chrome.bookmarks = {}; 200 chrome.bookmarks = {};
182 """ 201 """
183 c.Append("""/** 202 c.Append("""/**
184 * @const 203 * @const
185 */""") 204 */""")
186 c.Append('chrome.%s = {};' % self._namespace.name) 205 c.Append('chrome.%s = {};' % self._namespace.name)
187 c.Append() 206 c.Append()
188 207
189 def _GetFunctionParams(self, function): 208 def _GetFunctionParams(self, function):
190 """Returns the function params string for function. 209 """Returns the function params string for function.
191 """ 210 """
192 params = function.params[:] 211 params = function.params[:]
193 if function.callback: 212 if function.callback:
194 params.append(function.callback) 213 params.append(function.callback)
195 return ', '.join(param.name for param in params) 214 return ', '.join(param.name for param in params)
215
216 def _GetNamespace(self):
217 """Returns the namespace to be prepended to a top-level typedef.
218
219 For example, it might return "chrome.namespace".
220
221 Also optionally includes the class name if this is in the context
222 of outputting the members of a class.
223
224 For example, "chrome.namespace.ClassName.prototype"
225 """
226 if self._class_name:
227 return 'chrome.%s.%s.prototype' % (self._namespace.name, self._class_name)
228 return 'chrome.%s' % self._namespace.name
OLDNEW
« no previous file with comments | « tools/json_schema_compiler/idl_schema_test.py ('k') | tools/json_schema_compiler/js_externs_generator_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698