OLD | NEW |
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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 return c | 132 return c |
133 | 133 |
134 def _GenerateFunctionJsDoc(self, function): | 134 def _GenerateFunctionJsDoc(self, function): |
135 """Generates the documentation for a function as a Code. | 135 """Generates the documentation for a function as a Code. |
136 | 136 |
137 Returns an empty code object if the object has no documentation. | 137 Returns an empty code object if the object has no documentation. |
138 """ | 138 """ |
139 c = Code() | 139 c = Code() |
140 c.Append('/**') | 140 c.Append('/**') |
141 | 141 |
| 142 lines = [] |
142 if function.description: | 143 if function.description: |
143 for line in function.description.split('\n'): | 144 lines.extend(function.description.splitlines()) |
144 c.Comment(line, comment_prefix=' * ') | |
145 | 145 |
146 for param in function.params: | 146 for param in function.params: |
147 js_type = self._TypeToJsType(param.type_) | 147 js_type = self._TypeToJsType(param.type_) |
148 | |
149 if param.optional: | 148 if param.optional: |
150 js_type += '=' | 149 js_type += '=' |
151 | 150 lines.append('@param {%s} %s %s' % (js_type, |
152 param_doc = '@param {%s} %s %s' % (js_type, | 151 param.name, |
153 param.name, | 152 param.description or '')) |
154 param.description or '') | |
155 c.Comment(param_doc, comment_prefix=' * ') | |
156 | 153 |
157 if function.callback: | 154 if function.callback: |
158 # TODO(tbreisacher): Convert Function to function() for better | 155 lines.append('@param {%s} %s %s' % ( |
159 # typechecking. | 156 self._FunctionToJsFunction(function.callback), |
160 js_type = 'Function' | 157 function.callback.name, |
161 if function.callback.optional: | 158 function.callback.description or '')) |
162 js_type += '=' | |
163 param_doc = '@param {%s} %s %s' % (js_type, | |
164 function.callback.name, | |
165 function.callback.description or '') | |
166 c.Comment(param_doc, comment_prefix=' * ') | |
167 | 159 |
168 if function.returns: | 160 if function.returns: |
169 return_doc = '@return {%s} %s' % (self._TypeToJsType(function.returns), | 161 lines.append('@return {%s} %s' % (self._TypeToJsType(function.returns), |
170 function.returns.description) | 162 function.returns.description or '')) |
171 c.Comment(return_doc, comment_prefix=' * ') | 163 |
| 164 if function.deprecated: |
| 165 lines.append('@deprecated %s' % function.deprecated) |
| 166 |
| 167 for line in lines: |
| 168 c.Comment(line, comment_prefix=' * '); |
172 | 169 |
173 c.Append(' */') | 170 c.Append(' */') |
174 return c | 171 return c |
175 | 172 |
| 173 def _FunctionToJsFunction(self, function): |
| 174 """Converts a model.Function to a JS type (i.e., function([params])...)""" |
| 175 params = ', '.join( |
| 176 [self._TypeToJsType(param.type_) for param in function.params]) |
| 177 return_type = ( |
| 178 self._TypeToJsType(function.returns) if function.returns else 'void') |
| 179 optional = '=' if function.optional else '' |
| 180 return 'function(%s):%s%s' % (params, return_type, optional) |
| 181 |
176 def _TypeToJsType(self, js_type): | 182 def _TypeToJsType(self, js_type): |
177 """Converts a model.Type to a JS type (number, Array, etc.)""" | 183 """Converts a model.Type to a JS type (number, Array, etc.)""" |
178 if js_type.property_type in (PropertyType.INTEGER, PropertyType.DOUBLE): | 184 if js_type.property_type in (PropertyType.INTEGER, PropertyType.DOUBLE): |
179 return 'number' | 185 return 'number' |
180 elif js_type.property_type is PropertyType.OBJECT: | 186 elif js_type.property_type is PropertyType.OBJECT: |
181 return 'Object' | 187 return 'Object' |
182 elif js_type.property_type is PropertyType.ARRAY: | 188 elif js_type.property_type is PropertyType.ARRAY: |
183 return '!Array<%s>' % self._TypeToJsType(js_type.item_type) | 189 return '!Array<%s>' % self._TypeToJsType(js_type.item_type) |
184 elif js_type.property_type is PropertyType.REF: | 190 elif js_type.property_type is PropertyType.REF: |
185 ref_type = js_type.ref_type | 191 ref_type = js_type.ref_type |
186 # Enums are defined as chrome.fooAPI.MyEnum, but types are defined simply | 192 # Enums are defined as chrome.fooAPI.MyEnum, but types are defined simply |
187 # as MyType. | 193 # as MyType. |
188 if self._namespace.types[ref_type].property_type is PropertyType.ENUM: | 194 if self._namespace.types[ref_type].property_type is PropertyType.ENUM: |
189 ref_type = '!chrome.%s.%s' % (self._namespace.name, ref_type) | 195 ref_type = '!chrome.%s.%s' % (self._namespace.name, ref_type) |
190 return ref_type | 196 return ref_type |
191 elif js_type.property_type is PropertyType.CHOICES: | 197 elif js_type.property_type is PropertyType.CHOICES: |
192 return '(%s)' % '|'.join( | 198 return '(%s)' % '|'.join( |
193 [self._TypeToJsType(choice) for choice in js_type.choices]) | 199 [self._TypeToJsType(choice) for choice in js_type.choices]) |
| 200 elif js_type.property_type is PropertyType.FUNCTION: |
| 201 return self._FunctionToJsFunction(js_type.function) |
194 elif js_type.property_type is PropertyType.ANY: | 202 elif js_type.property_type is PropertyType.ANY: |
195 return '*' | 203 return '*' |
196 elif js_type.property_type.is_fundamental: | 204 elif js_type.property_type.is_fundamental: |
197 return js_type.property_type.name | 205 return js_type.property_type.name |
198 else: | 206 else: |
199 return '?' # TODO(tbreisacher): Make this more specific. | 207 return '?' # TODO(tbreisacher): Make this more specific. |
200 | 208 |
201 def _GenerateFunction(self, function): | 209 def _GenerateFunction(self, function): |
202 """Generates the code representing a function, including its documentation. | 210 """Generates the code representing a function, including its documentation. |
203 For example: | 211 For example: |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 * @const | 250 * @const |
243 */""") | 251 */""") |
244 .Append('chrome.%s = {};' % self._namespace.name)) | 252 .Append('chrome.%s = {};' % self._namespace.name)) |
245 return c | 253 return c |
246 | 254 |
247 def _GenerateFunctionParams(self, function): | 255 def _GenerateFunctionParams(self, function): |
248 params = function.params[:] | 256 params = function.params[:] |
249 if function.callback: | 257 if function.callback: |
250 params.append(function.callback) | 258 params.append(function.callback) |
251 return ', '.join(param.name for param in params) | 259 return ', '.join(param.name for param in params) |
OLD | NEW |