 Chromium Code Reviews
 Chromium Code Reviews Issue 12041098:
  Initial commit of the Dart Chrome Extension APIs generators  (Closed) 
  Base URL: http://git.chromium.org/chromium/src.git@file_path_bugfix
    
  
    Issue 12041098:
  Initial commit of the Dart Chrome Extension APIs generators  (Closed) 
  Base URL: http://git.chromium.org/chromium/src.git@file_path_bugfix| OLD | NEW | 
|---|---|
| (Empty) | |
| 1 from collections import defaultdict | |
| 2 | |
| 3 from code import Code | |
| 4 from model import * | |
| 5 | |
| 6 import copy | |
| 7 | |
| 8 LICENSE = """ | |
| 9 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
| 
benwells
2013/01/25 03:15:32
// lose the (c), Dart -> Chromium. Put at top of f
 
sashab
2013/01/25 05:58:12
The dart files need this header. This license goes
 | |
| 10 // for details. All rights reserved. Use of this source code is governed by a | |
| 11 // BSD-style license that can be found in the LICENSE file.""" | |
| 12 | |
| 13 class DartGenerator(object): | |
| 14 """A .dart generator for a namespace. | |
| 15 """ | |
| 16 | |
| 17 def __init__(self, namespace, custom_hooks_file): | |
| 18 self._namespace = namespace | |
| 19 self._types = namespace.types | |
| 20 self._hooks = self._parseCustomHooksFile(custom_hooks_file) | |
| 21 | |
| 22 global x | |
| 23 x = namespace | |
| 24 | |
| 25 def _parseCustomHooksFile(self, filename): | |
| 
calamity
2013/01/25 04:16:01
Style in other files seems to be _CamelCase.
 
sashab
2013/01/25 05:58:12
Done.
 | |
| 26 """Parses the custom hooks file at filename into a dictionary: | |
| 27 (type_name, method_name) -> [code_string, list of lines] | |
| 28 If the method is a getter or setter, it will be space-separated and appended | |
| 29 to the end of the method_name. | |
| 30 | |
| 31 e.g. | |
| 32 ('app.window.AppWindow', 'contentWindow'): ['void contentWindow ()'] | |
| 33 ('app.window.AppWindow', 'contentWindow get'): ['int get contentWindow()'] | |
| 34 """ | |
| 35 if filename == None: | |
| 36 return {} | |
| 37 | |
| 38 hooks = {} | |
| 39 with open(filename) as f: | |
| 40 current_key = None | |
| 41 for line in f: | |
| 42 if line.startswith('// START'): | |
| 43 # TODO(sashab): Account for any whitespace, not just spaces | |
| 44 current_key = tuple(line[len('// START'):].strip().split(' ', 1)) | |
| 45 hooks[current_key] = [] | |
| 46 elif line.startswith('// END'): | |
| 47 current_key = None | |
| 48 elif current_key: | |
| 49 hooks[current_key].append(line) | |
| 50 return hooks | |
| 51 | |
| 52 def Generate(self): | |
| 53 """Generates a Code object with the .dart for the entire namespace. | |
| 54 """ | |
| 55 c = Code() | |
| 56 (c.Append(LICENSE) | |
| 57 .Append() | |
| 58 .Append("part of chrome;")) | |
| 59 | |
| 60 # Add all types. | |
| 61 if self._types: | |
| 62 (c.Append() | |
| 63 .Append('/**') | |
| 64 .Append(' * Types') | |
| 65 .Append(' */') | |
| 66 ) | |
| 67 for type_name in self._types: | |
| 68 c.Concat(self._GenerateType(self._types[type_name])) | |
| 69 | |
| 70 # Add all events. | |
| 71 if self._namespace.events: | |
| 72 (c.Append() | |
| 73 .Append('/**') | |
| 74 .Append(' * Events') | |
| 75 .Append(' */') | |
| 76 ) | |
| 77 for event_name in self._namespace.events: | |
| 78 c.Concat(self._GenerateEvent(self._namespace.events[event_name])) | |
| 79 | |
| 80 # Add main class for this file. | |
| 81 (c.Append() | |
| 82 .Append('/**') | |
| 83 .Append(' * Functions') | |
| 84 .Append(' */') | |
| 85 ) | |
| 86 c.Concat(self._GenerateMainClass()) | |
| 87 | |
| 88 return c | |
| 89 | |
| 90 def _GenerateType(self, type_): | |
| 91 """Given a Type object, returns the Code with the .dart for this | |
| 92 type's definition. | |
| 93 | |
| 94 Assumes this type is a Parameter Type (creatable by user), and creates an | |
| 95 object that extends ChromeObject. All parameters are specifiable as named | |
| 96 arguments in the constructor, and all methods are wrapped with getters and | |
| 97 setters that hide the JS() implementation. | |
| 98 """ | |
| 99 c = Code() | |
| 100 (c.Append() | |
| 101 .Concat(self._GenerateDocumentation(type_)) | |
| 102 .Sblock("class %(type_name)s extends ChromeObject {") | |
| 103 ) | |
| 104 | |
| 105 # Check whether this type has function members. If it does, don't allow | |
| 106 # public construction. | |
| 107 add_public_constructor = True | |
| 108 for prop_name in type_.properties: | |
| 109 if self._IsFunction(type_.properties[prop_name]): | |
| 110 add_public_constructor = False | |
| 111 break | |
| 112 | |
| 113 constructor_fields = [] | |
| 114 for prop_name in type_.properties: | |
| 115 constructor_fields.append( | |
| 116 self._GeneratePropertySignature(type_.properties[prop_name], | |
| 117 prependThis = False, | |
| 118 omitBasicTypes = False)) | |
| 119 | |
| 120 # Add the public constructor. | |
| 121 if add_public_constructor: | |
| 122 (c.Append('/*') | |
| 123 .Append(' * Public constructor') | |
| 124 .Append(' */') | |
| 125 .Sblock('%(type_name)s({%(constructor_fields)s}) {') | |
| 126 ) | |
| 127 | |
| 128 for prop_name in type_.properties: | |
| 129 c.Append("this.%s = %s;" % (prop_name, prop_name)) | |
| 130 (c.Eblock("}") | |
| 131 .Append() | |
| 132 ) | |
| 133 | |
| 134 # Add the private constructor. | |
| 135 (c.Append('/*') | |
| 136 .Append(' * Private constructor') | |
| 137 .Append(' */') | |
| 138 .Append('%(type_name)s._proxy(_jsObject) : super._proxy(_jsObject);') | |
| 139 ) | |
| 140 | |
| 141 # Add an accessor (getter & setter) for each property. | |
| 142 properties = [t for t in type_.properties.values() | |
| 143 if not self._IsFunction(t))] | |
| 
calamity
2013/01/25 04:16:01
Extra ) here.
 
sashab
2013/01/25 05:58:12
Done, I'm surprised this worked at all :S Thanks
 | |
| 144 if properties: | |
| 145 (c.Append() | |
| 146 .Append('/*') | |
| 147 .Append(' * Public accessors') | |
| 148 .Append(' */') | |
| 149 ) | |
| 150 for prop in properties: | |
| 151 type_name = self._GetPropertyType(prop) | |
| 152 prop_is_base_type = self._IsBaseType(prop) | |
| 153 | |
| 154 # Add the documentation for this property | |
| 155 (c.Append() | |
| 156 .Concat(self._GenerateDocumentation(prop)) | |
| 
calamity
2013/01/25 04:16:01
Align periods. Same for rest of file.
 
sashab
2013/01/25 05:58:12
Done. Sorry, was meant to be like this. =)
 | |
| 157 ) | |
| 158 | |
| 159 # Check for custom hooks. | |
| 160 add_getter = True | |
| 161 add_setter = True | |
| 162 | |
| 163 hook_tuple = (type_.name, prop.name) | |
| 164 if hook_tuple in self._hooks: | |
| 165 for line in self._hooks[hook_tuple]: | |
| 166 c.Append(line) | |
| 167 add_getter = False | |
| 168 add_setter = False | |
| 169 | |
| 170 # Add the getter. | |
| 171 if add_getter: | |
| 172 hook_tuple_get = (type_.name, prop.name + " get") | |
| 173 if hook_tuple_get in self._hooks: | |
| 174 for line in self._hooks[hook_tuple_get]: | |
| 175 c.Append(line) | |
| 176 add_getter = False | |
| 177 | |
| 178 if add_getter: | |
| 179 # TODO(sashab): Serialize generic Dart objects differently. | |
| 180 if prop_is_base_type or self._IsObjectType(prop): | |
| 181 c.Append("%s get %s => JS('%s', '#.%s', this._jsObject);" % | |
| 182 (type_name, prop.name, type_name, prop.name)) | |
| 183 elif self._IsReferencedType(prop): | |
| 184 c.Append("%s get %s => new %s._proxy(JS('', '#.%s', this._jsObject));" | |
| 185 % (type_name, prop.name, type_name, prop.name)) | |
| 186 else: | |
| 187 print prop.type_ | |
| 188 c.Append("???%s get %s => JS('%s', '#.%s', this._jsObject);" % | |
| 189 (type_name, prop.name, type_name, prop.name)) | |
| 190 | |
| 191 # Add the setter. | |
| 192 if add_setter: | |
| 193 hook_tuple_set = (type_.name, prop.name + " set") | |
| 194 if hook_tuple_set in self._hooks: | |
| 195 for line in self._hooks[hook_tuple_set]: | |
| 196 c.Append(line) | |
| 197 add_setter = False | |
| 198 | |
| 199 if add_setter: | |
| 200 wrapped_name = prop.name | |
| 201 if not prop_is_base_type: | |
| 202 wrapped_name = "convertArgument(%s)" % prop.name | |
| 203 | |
| 204 (c.Append() | |
| 205 .Sblock("void set %s(%s %s) {" % (prop.name, type_name, prop.name)) | |
| 206 .Append("JS('void', '#.%s = #', this._jsObject, %s);" % | |
| 207 (prop.name, wrapped_name)) | |
| 208 .Eblock("}") | |
| 209 ) | |
| 210 | |
| 211 # Now add all the function properties. | |
| 212 function_properties = [t for t in type_.properties.values() | |
| 213 if self._IsFunction(t)] | |
| 214 if function_properties: | |
| 215 (c.Append() | |
| 216 .Append('/*') | |
| 217 .Append(' * Methods') | |
| 218 .Append(' */') | |
| 219 ) | |
| 220 for prop in function_properties: | |
| 221 c.Concat(self._GenerateFunction(prop)) | |
| 222 return (c.Eblock("}") | |
| 
calamity
2013/01/25 04:16:01
The h_generator and cc_generator seem to always us
 
sashab
2013/01/25 05:58:12
Done, but there's a return (Code()...) thing below
 | |
| 223 .Substitute({ | |
| 224 'type_name': type_.simple_name, | |
| 225 'constructor_fields': ', '.join(constructor_fields) | |
| 226 }) | |
| 227 ) | |
| 228 | |
| 229 def _GenerateDocumentation(self, prop): | |
| 230 """Given an object, generates the documentation for this object (as a | |
| 231 code string) and returns the Code object. | |
| 232 | |
| 233 Returns an empty code object if the object has no documentation. | |
| 234 | |
| 235 Uses triple-quotes for the string.""" | |
| 
calamity
2013/01/25 04:16:01
Triple quotes to next line?
 
sashab
2013/01/25 05:58:12
Good spotting, thanks
 | |
| 236 c = Code() | |
| 237 if not hasattr(prop, 'description'): | |
| 238 return c | |
| 239 | |
| 240 if prop.description: | |
| 241 for line in prop.description.split('\n'): | |
| 242 c.Append('/// %s' % line) | |
| 243 return c | |
| 244 | |
| 245 | |
| 246 def _GenerateFunction(self, f): | |
| 247 """Returns the Code object for the given function. | |
| 248 """ | |
| 249 return (Code() | |
| 250 .Append() | |
| 251 .Concat(self._GenerateDocumentation(f)) | |
| 252 .Append("%s => %s;" % (self._GenerateFunctionSignature(f), | |
| 253 self._GenerateProxyCall(f))) | |
| 254 ) | |
| 255 | |
| 256 def _GenerateProxyCall(self, function, callTarget='this._jsObject'): | |
| 257 """Given a function, generates the code to call that function via JS(). | |
| 258 Returns a string. | |
| 259 | |
| 260 `callTarget` is the name of the object to call the function on. The default | |
| 
calamity
2013/01/25 04:16:01
Use | instead of `.
 
sashab
2013/01/25 05:58:12
Done.
 | |
| 261 is this._jsObject. | |
| 262 | |
| 263 e.g. | |
| 264 JS("void", "#.resizeTo(#, #)", this._jsObject, width, height) | |
| 265 JS("void", "#.setBounds(#)", this._jsObject, convertArgument(bounds)) | |
| 266 """ | |
| 267 | |
| 268 format = "JS('%(return_type)s', " +\ | |
| 269 "'#.%(name)s(%(param_hashes)s)', " +\ | |
| 270 "%(target)s%(params)s)" | |
| 
calamity
2013/01/25 04:16:01
Maybe use ("text"
           "nextline"
 
sashab
2013/01/25 05:58:12
Didn't know you could do that. Thanks! :)
 | |
| 271 | |
| 272 params = "" | |
| 273 if function.params: | |
| 274 params_wrapped = [] | |
| 275 for param in function.params: | |
| 276 if not self._IsBaseType(param): | |
| 277 params_wrapped.append("convertArgument(%s)" % param.name) | |
| 278 else: | |
| 279 params_wrapped.append(param.name) | |
| 280 params = ', ' + ', '.join(params_wrapped) | |
| 281 | |
| 282 return format % { | |
| 283 "return_type": self._GetPropertyType(function.returns), | |
| 284 "name": function.name, | |
| 285 "param_hashes": ', '.join('#' for p in function.params), | |
| 286 "target": callTarget, | |
| 287 "params": params | |
| 
calamity
2013/01/25 04:16:01
I think convention is to use single quotes where c
 
sashab
2013/01/25 05:58:12
Done this where possible :)
 | |
| 288 } | |
| 289 | |
| 290 def _GenerateEvent(self, event): | |
| 291 """Given a Function object, returns the Code with the .dart for this event, | |
| 292 represented by the function. | |
| 293 | |
| 294 All events extend the Event base type. | |
| 295 """ | |
| 296 c = Code() | |
| 297 | |
| 298 # Add documentation for this event. | |
| 299 (c.Append() | |
| 300 .Concat(self._GenerateDocumentation(event)) | |
| 301 .Sblock("class Event_%(event_name)s extends Event {") | |
| 302 ) | |
| 303 | |
| 304 # Override Event callback type definitions. | |
| 305 for ret_type, event_func in (('void', 'addListener'), | |
| 306 ('void', 'removeListener'), | |
| 307 ('bool', 'hasListener')): | |
| 308 | |
| 309 param_list = self._GenerateParameterList(event.params, event.callback, | |
| 310 allow_optional = False) | |
| 311 | |
| 312 c.Append("%s %s(void callback(%s)) => super.%s(callback);" % | |
| 313 (ret_type, event_func, param_list, event_func)) | |
| 314 | |
| 315 # Generate the constructor. | |
| 316 (c.Append() | |
| 317 .Append('Event_%(event_name)s(jsObject) : super(jsObject, %(param_num)d);') | |
| 318 ) | |
| 319 | |
| 320 return (c.Eblock("}") | |
| 321 .Substitute({ | |
| 322 'event_name': self._namespace.unix_name + '_' + event.name, | |
| 323 'param_num': len(event.params) | |
| 324 }) | |
| 325 ) | |
| 326 | |
| 327 def _GenerateMainClass(self): | |
| 328 """Generates the main class for this file, which links to all functions | |
| 329 and events. | |
| 330 | |
| 331 Includes a ChromeApi member variable to represent the connection. | |
| 332 | |
| 333 Returns a code object. | |
| 334 """ | |
| 335 c = Code() | |
| 336 (c.Append() | |
| 337 .Sblock("class API_%(namespace_name)s {") | |
| 338 .Append('/*') | |
| 339 .Append(' * API connection') | |
| 340 .Append(' */') | |
| 341 .Append("Object _jsObject;") | |
| 342 ) | |
| 343 | |
| 344 # Add events. | |
| 345 if self._namespace.events: | |
| 346 (c.Append() | |
| 347 .Append('/*') | |
| 348 .Append(' * Events') | |
| 349 .Append(' */') | |
| 350 ) | |
| 351 for event_name in self._namespace.events: | |
| 352 c.Append("Event_%s_%s %s;" % (self._namespace.unix_name, event_name, | |
| 353 event_name)) | |
| 354 | |
| 355 # Add functions. | |
| 356 if self._namespace.functions: | |
| 357 (c.Append() | |
| 358 .Append('/*') | |
| 359 .Append(' * Functions') | |
| 360 .Append(' */') | |
| 361 ) | |
| 362 for function in self._namespace.functions.values(): | |
| 363 c.Concat(self._GenerateFunction(function)) | |
| 364 | |
| 365 # Add the constructor. | |
| 366 (c.Append() | |
| 367 .Sblock('API_%(namespace_name)s(this._jsObject) {') | |
| 368 ) | |
| 369 | |
| 370 # Add events to constructor. | |
| 371 for event_name in self._namespace.events: | |
| 372 c.Append("%s = new Event_%s_%s(JS('', '#.%s', this._jsObject));" % | |
| 373 (event_name, self._namespace.unix_name, event_name, event_name)) | |
| 374 c.Eblock("}") | |
| 375 | |
| 376 return (c.Eblock("}") | |
| 377 .Substitute({ | |
| 378 'namespace_name': self._namespace.unix_name | |
| 379 }) | |
| 380 ) | |
| 381 | |
| 382 def _GeneratePropertySignature(self, prop, prependThis = False, | |
| 383 omitBasicTypes = False, | |
| 384 functionsAsObjects = False, | |
| 385 withGetKeyword = False): | |
| 386 """Given a property, returns a signature for that property. | |
| 387 Recursively generates the signature for callbacks. | |
| 388 Returns a String for the given property. | |
| 389 | |
| 390 * If `prependThis` is True, prepends "this." to all variable names. | |
| 391 * If `omitBasicTypes` is True, only adds type names for function types. | |
| 392 * If `functionsAsObjects` is True, treats callbacks as basic types and | |
| 393 prepends the type 'Function'. | |
| 394 * If `withGetKeyword` is True, adds the word 'get' between the property's | |
| 395 type and name. Used for getters in dart. | |
| 396 | |
| 397 e.g. | |
| 398 bool x | |
| 399 void onClosed() | |
| 400 void doSomething(bool x, void callback([String x])) | |
| 401 | |
| 402 e.g. If prependThis is True: | |
| 403 bool this.x | |
| 404 void this.onClosed() | |
| 405 void this.doSomething(bool x, void callback([String x])) | |
| 406 | |
| 407 e.g. If omitBasicTypes is True: | |
| 408 this.x | |
| 409 void onClosed() | |
| 410 void doSomething(bool x, void callback([String x])) | |
| 411 | |
| 412 e.g. If functionsAsObjects is True: | |
| 413 bool x | |
| 414 Function onClosed | |
| 415 Function doSomething | |
| 416 | |
| 417 e.g. If withGetKeyword and functionsAsObjects is True: | |
| 418 bool get x | |
| 419 Function get onClosed | |
| 420 Function get doSomething | |
| 421 | |
| 422 """ | |
| 423 if self._IsFunction(prop) and not functionsAsObjects: | |
| 424 return self._GenerateFunctionSignature(prop, prependThis) | |
| 425 else: | |
| 426 name_parts = [prop.simple_name] | |
| 427 if prependThis: | |
| 428 name_parts[0] = 'this.' + name_parts[0] | |
| 429 if withGetKeyword: | |
| 430 name_parts = ['get'] + name_parts | |
| 431 | |
| 432 name = ' '.join(name_parts) | |
| 433 type_ = (self._GetPropertyType(prop) + ' ') if not omitBasicTypes else '' | |
| 434 | |
| 435 return "%(type)s%(name)s" % { | |
| 436 'type': type_, | |
| 437 'name': name | |
| 438 } | |
| 439 | |
| 440 def _GenerateFunctionSignature(self, function, prependThis = False): | |
| 441 """Given a function object, returns the signature for that function. | |
| 442 Recursively generates the signature for callbacks. | |
| 443 Returns a String for the given function. | |
| 444 | |
| 445 If prependThis is True, adds "this." to the function's name. | |
| 446 | |
| 447 e.g. | |
| 448 void onClosed() | |
| 449 bool isOpen([String type]) | |
| 450 void doSomething(bool x, void callback([String x])) | |
| 451 | |
| 452 e.g. If prependThis is True: | |
| 453 void this.onClosed() | |
| 454 bool this.isOpen([String type]) | |
| 455 void this.doSomething(bool x, void callback([String x])) | |
| 456 """ | |
| 457 | |
| 458 sig = "%(return_type)s %(name)s(%(params)s)" | |
| 459 | |
| 460 # Get function return type. | |
| 461 if function.returns: | |
| 462 return_type = self._GetPropertyType(function.returns) | |
| 463 else: | |
| 464 return_type = 'void' | |
| 465 | |
| 466 # Get function name. | |
| 467 function_name = function.simple_name | |
| 468 if prependThis: | |
| 469 function_name = 'this.' + function_name | |
| 470 | |
| 471 return sig % { | |
| 472 'return_type': return_type, | |
| 473 'name': function_name, | |
| 474 'params': self._GenerateParameterList(function.params, | |
| 475 getattr(function, 'callback', None)) | |
| 476 } | |
| 477 | |
| 478 def _GenerateParameterList(self, params, callback=None, | |
| 479 allow_optional = True): | |
| 480 """Given a list of function parameters, generates their signature (as a | |
| 481 string). | |
| 482 | |
| 483 e.g. | |
| 484 [String type] | |
| 485 bool x, void callback([String x]) | |
| 486 | |
| 487 If allow_optional is False, ignores optional parameters. Useful for | |
| 488 callbacks, where optional parameters are not used. | |
| 489 """ | |
| 490 # params lists (required & optional), to be joined with ,'s | |
| 491 # FIXME(sashab): assuming all optional params come after required ones | |
| 492 params_req = [] | |
| 493 params_opt = [] | |
| 494 for param in params: | |
| 495 p_sig = self._GeneratePropertySignature(param) | |
| 496 if allow_optional and param.optional: | |
| 497 params_opt.append(p_sig) | |
| 498 else: | |
| 499 params_req.append(p_sig) | |
| 500 | |
| 501 # Add the callback, if it exists. | |
| 502 if callback: | |
| 503 c_sig = self._GenerateFunctionSignature(callback) | |
| 504 if callback.optional: | |
| 505 params_opt.append(c_sig) | |
| 506 else: | |
| 507 params_req.append(c_sig) | |
| 508 | |
| 509 # join params | |
| 510 params = '' | |
| 511 if params_req: | |
| 512 params += ', '.join(params_req) | |
| 513 if params_opt: | |
| 514 params += ', ' | |
| 515 if params_opt: | |
| 516 params += '[' + ', '.join(params_opt) + ']' | |
| 517 | |
| 518 return params | |
| 519 | |
| 520 def _GetNamespace(self, name): | |
| 521 """Given a name a.b.c, returns the namespace (in this case, a.b). | |
| 522 """ | |
| 523 return name.rsplit('.', 1)[0] | |
| 524 | |
| 525 def _GetBaseName(self, name): | |
| 526 """Given a name a.b.c, returns the base name of the path (in this case, c). | |
| 527 """ | |
| 528 return name.rsplit('.', 1)[1] | |
| 529 | |
| 530 def _IsReferencedType(self, prop): | |
| 531 """Given a model.Property, returns whether this type is a referenced type. | |
| 532 """ | |
| 533 return prop.type_ == PropertyType.REF | |
| 534 | |
| 535 def _IsFunction(self, prop): | |
| 536 """Given a model.Property, returns whether this type is a function. | |
| 537 """ | |
| 538 return prop.type_ == PropertyType.FUNCTION | |
| 539 | |
| 540 def _IsObjectType(self, prop): | |
| 541 """Given a model.Property, returns whether this type is an object. | |
| 542 """ | |
| 543 return (prop.type_ == PropertyType.OBJECT or | |
| 544 prop.type_ == PropertyType.ANY) | |
| 545 | |
| 546 def _IsBaseType(self, prop): | |
| 547 """Given a model.Property, returns whether this type is a base type | |
| 548 (string, number or boolean). | |
| 549 """ | |
| 550 base_type = self._GetPropertyType(prop) | |
| 551 if base_type in ['bool', 'num', 'int', 'double', 'String']: | |
| 552 return True | |
| 553 return False | |
| 554 | |
| 555 def _GetReferencedType(self, name): | |
| 556 """Given the name of a referenced type, returns the type object for that | |
| 557 reference. | |
| 558 | |
| 559 Returns None if the type is not found. | |
| 560 """ | |
| 561 if name in self._namespace.types: | |
| 562 return self._namespace.types[name] | |
| 563 return None | |
| 564 | |
| 565 def _GetPropertyType(self, prop): | |
| 566 """Given a model.Property object, returns its type as a Dart string. | |
| 567 """ | |
| 568 if prop == None: | |
| 569 return 'void' | |
| 570 | |
| 571 dart_type = None | |
| 572 type_ = prop.type_ | |
| 573 | |
| 574 if type_ == None: | |
| 575 dart_type = 'void' | |
| 576 elif type_ == PropertyType.REF: | |
| 577 if self._GetNamespace(prop.ref_type) == self._namespace.name: | |
| 578 # This type is in this namespace; just use its base name. | |
| 579 dart_type = self._GetBaseName(prop.ref_type) | |
| 580 else: | |
| 581 # TODO(sahab): Work out how to import this foreign type. | |
| 582 dart_type = '?REF: ' + prop.ref_type | |
| 583 elif type_ == PropertyType.BOOLEAN: | |
| 584 dart_type = 'bool' | |
| 585 elif type_ == PropertyType.INTEGER: | |
| 586 dart_type = 'int' | |
| 587 elif type_ == PropertyType.INT64: | |
| 588 dart_type = 'num' | |
| 589 elif type_ == PropertyType.DOUBLE: | |
| 590 dart_type = 'double' | |
| 591 elif type_ == PropertyType.STRING: | |
| 592 dart_type = 'String' | |
| 593 elif type_ == PropertyType.ENUM: | |
| 594 dart_type = 'String' | |
| 595 elif type_ == PropertyType.ADDITIONAL_PROPERTIES: | |
| 596 dart_type = 'Map' | |
| 597 elif type_ == PropertyType.ANY: | |
| 598 dart_type = 'Object' | |
| 599 elif type_ == PropertyType.OBJECT: | |
| 600 # TODO(sashab): Work out a mapped type name? | |
| 601 dart_type = prop.instance_of | |
| 602 elif type_ == PropertyType.FUNCTION: | |
| 603 dart_type = 'Function' | |
| 604 elif type_ == PropertyType.ARRAY: | |
| 605 if hasattr(prop, 'item_type'): | |
| 606 container_type = self._GetPropertyType(prop.item_type) | |
| 607 dart_type = 'List<%s>' % container_type | |
| 608 else: | |
| 609 dart_type = 'List' | |
| 610 elif type_ == PropertyType.BINARY: | |
| 611 dart_type = 'String' | |
| 612 else: | |
| 613 raise NotImplementedError(type_) | |
| 614 | |
| 615 return dart_type.strip() | |
| OLD | NEW |