dart_generator.py revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)""" 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Generator language component for compiler.py that adds Dart language support. 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)""" 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from code import Code 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from model import * 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from schema_util import * 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import os 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from datetime import datetime 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)LICENSE = ( 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)"""// Copyright (c) %s, the Dart project authors. Please see the AUTHORS file 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// for details. All rights reserved. Use of this source code is governed by a 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// BSD-style license that can be found in the LICENSE file.""" % 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) datetime.now().year) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DartGenerator(object): 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __init__(self, dart_overrides_dir=None): 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._dart_overrides_dir = dart_overrides_dir 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def Generate(self, namespace): 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return _Generator(namespace, self._dart_overrides_dir).Generate() 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class _Generator(object): 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """A .dart generator for a namespace. 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __init__(self, namespace, dart_overrides_dir=None): 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._namespace = namespace 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(sashab): Once inline type definitions start being added to 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # self._types, make a _FindType(self, type_) function that looks at 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # self._namespace.types. 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._types = namespace.types 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Build a dictionary of Type Name --> Custom Dart code. 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._type_overrides = {} 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if dart_overrides_dir is not None: 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for filename in os.listdir(dart_overrides_dir): 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if filename.startswith(namespace.unix_name): 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) with open(os.path.join(dart_overrides_dir, filename)) as f: 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Split off the namespace and file extension, leaving just the type. 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type_path = '.'.join(filename.split('.')[1:-1]) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._type_overrides[type_path] = f.read() 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(sashab): Add all inline type definitions to the global Types 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # dictionary here, so they have proper names, and are implemented along with 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # all other types. Also update the parameters/members with these types 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # to reference these new types instead. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def Generate(self): 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Generates a Code object with the .dart for the entire namespace. 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c = Code() 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append(LICENSE) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append() 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('// Generated from namespace: %s' % self._namespace.name) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append() 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('part of chrome;')) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._types: 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append() 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('/**') 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' * Types') 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' */') 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append() 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for type_ in self._types.values(): 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Check for custom dart for this whole type. 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) override = self._GetOverride([type_.name], document_with=type_) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Cblock(override if override is not None else self._GenerateType(type_)) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._namespace.events: 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append('/**') 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' * Events') 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' */') 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append() 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for event_name in self._namespace.events: 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Cblock(self._GenerateEvent(self._namespace.events[event_name])) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append('/**') 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' * Functions') 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' */') 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append() 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Cblock(self._GenerateMainClass()) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateType(self, type_): 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a Type object, returns the Code with the .dart for this 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type's definition. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Assumes this type is a Parameter Type (creatable by user), and creates an 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object that extends ChromeObject. All parameters are specifiable as named 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arguments in the constructor, and all methods are wrapped with getters and 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setters that hide the JS() implementation. 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c = Code() 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Since enums are just treated as strings for now, don't generate their 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # type. 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(sashab): Find a nice way to wrap enum objects. 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.property_type is PropertyType.ENUM: 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Concat(self._GenerateDocumentation(type_)) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Sblock('class %(type_name)s extends ChromeObject {') 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Check whether this type has function members. If it does, don't allow 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # public construction. 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) add_public_constructor = all(not self._IsFunction(p.type_) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for p in type_.properties.values()) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) constructor_fields = [self._GeneratePropertySignature(p) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for p in type_.properties.values()] 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if add_public_constructor: 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append('/*') 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' * Public constructor') 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' */') 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Sblock('%(type_name)s({%(constructor_fields)s}) {') 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for prop_name in type_.properties: 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Sblock('if (?%s)' % prop_name) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('this.%s = %s;' % (prop_name, prop_name)) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Eblock() 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Eblock('}') 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append() 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append('/*') 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' * Private constructor') 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' */') 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('%(type_name)s._proxy(_jsObject) : super._proxy(_jsObject);') 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Add an accessor (getter & setter) for each property. 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) properties = [p for p in type_.properties.values() 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not self._IsFunction(p.type_)] 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if properties: 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append() 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('/*') 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' * Public accessors') 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' */') 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for prop in properties: 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) override = self._GetOverride([type_.name, prop.name], document_with=prop) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Concat(override if override is not None 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else self._GenerateGetterAndSetter(type_, prop)) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Now add all the methods. 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) methods = [t for t in type_.properties.values() 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._IsFunction(t.type_)] 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if methods: 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append() 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('/*') 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' * Methods') 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' */') 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for prop in methods: 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Check if there's an override for this method. 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) override = self._GetOverride([type_.name, prop.name], document_with=prop) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Cblock(override if override is not None 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else self._GenerateFunction(prop.type_.function)) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Eblock('}') 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Substitute({ 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'type_name': self._AddPrefix(type_.simple_name), 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'constructor_fields': ', '.join(constructor_fields) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateGetterAndSetter(self, type_, prop): 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a Type and Property, returns the Code object for the getter and 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setter for that property. 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c = Code() 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) override = self._GetOverride([type_.name, prop.name, '.get'], 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) document_with=prop) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Cblock(override if override is not None 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else self._GenerateGetter(type_, prop)) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) override = self._GetOverride([type_.name, prop.name, '.set']) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Cblock(override if override is not None 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else self._GenerateSetter(type_, prop)) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateGetter(self, type_, prop): 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a Type and Property, returns the Code object for the getter for 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) that property. 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Also adds the documentation for this property before the method. 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c = Code() 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Concat(self._GenerateDocumentation(prop)) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type_name = self._GetDartType(prop.type_) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (self._IsBaseType(prop.type_)): 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Append("%s get %s => JS('%s', '#.%s', this._jsObject);" % 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (type_name, prop.name, type_name, prop.name)) 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif self._IsSerializableObjectType(prop.type_): 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Append("%s get %s => new %s._proxy(JS('', '#.%s', " 211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "this._jsObject));" % 212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) (type_name, prop.name, type_name, prop.name)) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif self._IsListOfSerializableObjects(prop.type_): 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Sblock('%s get %s {' % (type_name, prop.name)) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('%s __proxy_%s = new %s();' % (type_name, prop.name, 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type_name)) 217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) .Append("int count = JS('int', '#.%s.length', this._jsObject);" % 218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) prop.name) 219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) .Sblock("for (int i = 0; i < count; i++) {") 220b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) .Append("var item = JS('', '#.%s', this._jsObject);" % prop.name) 221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) .Append('__proxy_%s.add(new %s._proxy(item));' % (prop.name, 222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._GetDartType(prop.type_.item_type))) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Eblock('}') 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('return __proxy_%s;' % prop.name) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Eblock('}') 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif self._IsObjectType(prop.type_): 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(sashab): Think of a way to serialize generic Dart objects. 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_name in self._types: 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Append("%s get %s => new %s._proxy(JS('%s', '#.%s', " 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "this._jsObject));" % 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (type_name, prop.name, type_name, type_name, prop.name)) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Append("%s get %s => JS('%s', '#.%s', this._jsObject);" % 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (type_name, prop.name, type_name, prop.name)) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise Exception( 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Could not generate wrapper for %s.%s: unserializable type %s" % 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (type_.name, prop.name, type_name) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateSetter(self, type_, prop): 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a Type and Property, returns the Code object for the setter for 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) that property. 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c = Code() 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type_name = self._GetDartType(prop.type_) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) wrapped_name = prop.name 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not self._IsBaseType(prop.type_): 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) wrapped_name = 'convertArgument(%s)' % prop.name 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Sblock("void set %s(%s %s) {" % (prop.name, type_name, prop.name)) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append("JS('void', '#.%s = #', this._jsObject, %s);" % 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (prop.name, wrapped_name)) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Eblock("}") 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateDocumentation(self, prop): 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given an object, generates the documentation for this object (as a 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) code string) and returns the Code object. 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Returns an empty code object if the object has no documentation. 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Uses triple-quotes for the string. 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c = Code() 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if prop.description is not None: 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for line in prop.description.split('\n'): 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Comment(line, comment_prefix='/// ') 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateFunction(self, f): 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Returns the Code object for the given function. 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c = Code() 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Concat(self._GenerateDocumentation(f)) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not self._NeedsProxiedCallback(f): 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Append("%s => %s;" % (self._GenerateFunctionSignature(f), 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._GenerateProxyCall(f))) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Sblock("%s {" % self._GenerateFunctionSignature(f)) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Concat(self._GenerateProxiedFunction(f.callback, f.callback.name)) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('%s;' % self._GenerateProxyCall(f)) 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Eblock('}') 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateProxiedFunction(self, f, callback_name): 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a function (assumed to be a callback), generates the proxied 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) version of this function, which calls |callback_name| if it is defined. 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Returns a Code object. 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c = Code() 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proxied_params = [] 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # A list of Properties, containing List<*> objects that need proxying for 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # their members (by copying out each member and proxying it). 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lists_to_proxy = [] 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for p in f.params: 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._IsBaseType(p.type_): 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proxied_params.append(p.name) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif self._IsSerializableObjectType(p.type_): 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proxied_params.append('new %s._proxy(%s)' % ( 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._GetDartType(p.type_), p.name)) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif self._IsListOfSerializableObjects(p.type_): 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proxied_params.append('__proxy_%s' % p.name) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lists_to_proxy.append(p) 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif self._IsObjectType(p.type_): 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(sashab): Find a way to build generic JS objects back in Dart. 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proxied_params.append('%s' % p.name) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif p.type_.property_type is PropertyType.ARRAY: 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(sashab): This might be okay - what if this is a list of 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # FileEntry elements? In this case, a basic list will proxy the objects 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # fine. 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proxied_params.append('%s' % p.name) 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise Exception( 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Cannot automatically create proxy; can't wrap %s, type %s" % ( 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._GenerateFunctionSignature(f), self._GetDartType(p.type_))) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Sblock("void __proxy_callback(%s) {" % ', '.join(p.name for p in 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) f.params)) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Sblock('if (?%s) {' % callback_name) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Add the proxied lists. 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for list_to_proxy in lists_to_proxy: 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append("%s __proxy_%s = new %s();" % ( 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._GetDartType(list_to_proxy.type_), 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) list_to_proxy.name, 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._GetDartType(list_to_proxy.type_))) 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Sblock("for (var o in %s) {" % list_to_proxy.name) 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('__proxy_%s.add(new %s._proxy(o));' % (list_to_proxy.name, 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._GetDartType(list_to_proxy.type_.item_type))) 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Eblock("}") 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append("%s(%s);" % (callback_name, ', '.join(proxied_params))) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Eblock('}') 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Eblock('}') 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _NeedsProxiedCallback(self, f): 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a function, returns True if this function's callback needs to be 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proxied, False if not. 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Function callbacks need to be proxied if they have at least one 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non-base-type parameter. 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return f.callback and self._NeedsProxy(f.callback) 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _NeedsProxy(self, f): 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a function, returns True if it needs to be proxied, False if not. 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) A function needs to be proxied if any of its members are non-base types. 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) This means that, when the function object is passed to Javascript, it 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) needs to be wrapped in a "proxied" call that converts the JS inputs to Dart 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) objects explicitly, before calling the real function with these new objects. 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return any(not self._IsBaseType(p.type_) for p in f.params) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateProxyCall(self, function, call_target='this._jsObject'): 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a function, generates the code to call that function via JS(). 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Returns a string. 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) |call_target| is the name of the object to call the function on. The default 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is this._jsObject. 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) e.g. 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JS('void', '#.resizeTo(#, #)', this._jsObject, width, height) 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JS('void', '#.setBounds(#)', this._jsObject, convertArgument(bounds)) 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) n_params = len(function.params) 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if function.callback: 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) n_params += 1 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return_type_str = self._GetDartType(function.returns) 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params = [] 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # If this object is serializable, don't convert the type from JS - pass the 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # JS object straight into the proxy. 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._IsSerializableObjectType(function.returns): 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.append("''") 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.append("'%s'" % return_type_str) 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.append("'#.%s(%s)'" % (function.name, ', '.join(['#'] * n_params))) 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.append(call_target) 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for param in function.params: 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not self._IsBaseType(param.type_): 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.append('convertArgument(%s)' % param.name) 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.append(param.name) 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if function.callback: 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # If this isn't a base type, we need a proxied callback. 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_name = function.callback.name 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._NeedsProxiedCallback(function): 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_name = "__proxy_callback" 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.append('convertDartClosureToJS(%s, %s)' % (callback_name, 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) len(function.callback.params))) 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # If the object is serializable, call the proxy constructor for this type. 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proxy_call = 'JS(%s)' % ', '.join(params) 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._IsSerializableObjectType(function.returns): 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proxy_call = 'new %s._proxy(%s)' % (return_type_str, proxy_call) 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return proxy_call 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateEvent(self, event): 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a Function object, returns the Code with the .dart for this event, 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) represented by the function. 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) All events extend the Event base type. 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c = Code() 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Add documentation for this event. 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Concat(self._GenerateDocumentation(event)) 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Sblock('class Event_%(event_name)s extends Event {') 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # If this event needs a proxy, all calls need to be proxied. 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) needs_proxy = self._NeedsProxy(event) 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Override Event callback type definitions. 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for ret_type, event_func in (('void', 'addListener'), 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ('void', 'removeListener'), 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ('bool', 'hasListener')): 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) param_list = self._GenerateParameterList(event.params, event.callback, 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) convert_optional=True) 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if needs_proxy: 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Sblock('%s %s(void callback(%s)) {' % (ret_type, event_func, 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) param_list)) 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Concat(self._GenerateProxiedFunction(event, 'callback')) 442b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) .Append('super.%s(__proxy_callback);' % event_func) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Eblock('}') 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Append('%s %s(void callback(%s)) => super.%s(callback);' % 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (ret_type, event_func, param_list, event_func)) 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Append() 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Generate the constructor. 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append('Event_%(event_name)s(jsObject) : ' 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'super._(jsObject, %(param_num)d);') 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Eblock('}') 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Substitute({ 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'event_name': self._namespace.unix_name + '_' + event.name, 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'param_num': len(event.params) 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }) 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateMainClass(self): 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Generates the main class for this file, which links to all functions 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) and events. 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Returns a code object. 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c = Code() 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Sblock('class API_%s {' % self._namespace.unix_name) 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('/*') 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' * API connection') 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' */') 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('Object _jsObject;') 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Add events. 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._namespace.events: 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append() 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('/*') 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' * Events') 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' */') 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for event_name in self._namespace.events: 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Append('Event_%s_%s %s;' % (self._namespace.unix_name, event_name, 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_name)) 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Add functions. 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._namespace.functions: 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Append() 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append('/*') 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' * Functions') 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Append(' */') 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for function in self._namespace.functions.values(): 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Check for custom dart for this whole property. 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) override = self._GetOverride([function.name], document_with=function) 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Cblock(override if override is not None 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else self._GenerateFunction(function)) 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Add the constructor. 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Sblock('API_%s(this._jsObject) {' % self._namespace.unix_name) 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Add events to constructor. 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for event_name in self._namespace.events: 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Append("%s = new Event_%s_%s(JS('', '#.%s', this._jsObject));" % 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (event_name, self._namespace.unix_name, event_name, event_name)) 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (c.Eblock('}') 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Eblock('}') 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GeneratePropertySignature(self, prop): 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a property, returns a signature for that property. 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Recursively generates the signature for callbacks. 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Returns a String for the given property. 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) e.g. 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool x 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void onClosed() 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void doSomething(bool x, void callback([String x])) 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if self._IsFunction(prop.type_): 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._GenerateFunctionSignature(prop.type_.function) 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return '%(type)s %(name)s' % { 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'type': self._GetDartType(prop.type_), 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'name': prop.simple_name 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateFunctionSignature(self, function, convert_optional=False): 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a function object, returns the signature for that function. 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Recursively generates the signature for callbacks. 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Returns a String for the given function. 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) If convert_optional is True, changes optional parameters to be required. 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) e.g. 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void onClosed() 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool isOpen([String type]) 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void doSomething(bool x, void callback([String x])) 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sig = '%(return_type)s %(name)s(%(params)s)' 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if function.returns: 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return_type = self._GetDartType(function.returns) 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return_type = 'void' 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return sig % { 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'return_type': return_type, 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'name': function.simple_name, 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'params': self._GenerateParameterList(function.params, 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function.callback, 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) convert_optional=convert_optional) 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GenerateParameterList(self, 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params, 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback=None, 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) convert_optional=False): 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a list of function parameters, generates their signature (as a 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) string). 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) e.g. 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) [String type] 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool x, void callback([String x]) 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) If convert_optional is True, changes optional parameters to be required. 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Useful for callbacks, where optional parameters are treated as required. 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Params lists (required & optional), to be joined with commas. 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(sashab): Don't assume optional params always come after required 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # ones. 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params_req = [] 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params_opt = [] 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for param in params: 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p_sig = self._GeneratePropertySignature(param) 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if param.optional and not convert_optional: 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params_opt.append(p_sig) 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params_req.append(p_sig) 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Add the callback, if it exists. 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if callback: 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c_sig = self._GenerateFunctionSignature(callback, convert_optional=True) 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if callback.optional: 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params_opt.append(c_sig) 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params_req.append(c_sig) 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Join the parameters with commas. 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Optional parameters have to be in square brackets, e.g.: 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # required params | optional params | output 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # [] | [] | '' 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # [x, y] | [] | 'x, y' 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # [] | [a, b] | '[a, b]' 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # [x, y] | [a, b] | 'x, y, [a, b]' 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if params_opt: 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params_opt[0] = '[%s' % params_opt[0] 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params_opt[-1] = '%s]' % params_opt[-1] 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) param_sets = [', '.join(params_req), ', '.join(params_opt)] 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # The 'if p' part here is needed to prevent commas where there are no 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # parameters of a certain type. 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # If there are no optional parameters, this prevents a _trailing_ comma, 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # e.g. '(x, y,)'. Similarly, if there are no required parameters, this 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # prevents a leading comma, e.g. '(, [a, b])'. 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ', '.join(p for p in param_sets if p) 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GetOverride(self, key_chain, document_with=None): 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a list of keys, joins them with periods and searches for them in 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) the custom dart overrides. 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) If there is an override for that key, finds the override code and returns 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) the Code object. If not, returns None. 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) If document_with is not None, adds the documentation for this property 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) before the override code. 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c = Code() 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) contents = self._type_overrides.get('.'.join(key_chain)) 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if contents is None: 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return None 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if document_with is not None: 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Concat(self._GenerateDocumentation(document_with)) 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for line in contents.strip('\n').split('\n'): 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c.Append(line) 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return c 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _AddPrefix(self, name): 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given the name of a type, prefixes the namespace (as camelcase) and 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) returns the new name. 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(sashab): Split the dart library into multiple files, avoiding the 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # need for this prefixing. 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ('%s%s' % ( 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ''.join(s.capitalize() for s in self._namespace.name.split('.')), 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name)) 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _IsFunction(self, type_): 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a model.Type, returns whether this type is a function. 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return type_.property_type == PropertyType.FUNCTION 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _IsSerializableObjectType(self, type_): 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a model.Type, returns whether this type is a serializable object. 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Serializable objects are custom types defined in this namespace. 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) If this object is a reference to something not in this namespace, assumes 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) its a serializable object. 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_ is None: 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return False 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.property_type is PropertyType.CHOICES: 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return all(self._IsSerializableObjectType(c) for c in type_.choices) 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.property_type is PropertyType.REF: 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.ref_type in self._types: 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._IsObjectType(self._types[type_.ref_type]) 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return True 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type_.property_type == PropertyType.OBJECT 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) and type_.instance_of in self._types): 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._IsObjectType(self._types[type_.instance_of]) 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return False 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _IsObjectType(self, type_): 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a model.Type, returns whether this type is an object. 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (self._IsSerializableObjectType(type_) 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) or type_.property_type in [PropertyType.OBJECT, PropertyType.ANY]) 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _IsListOfSerializableObjects(self, type_): 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a model.Type, returns whether this type is a list of serializable 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) objects (or regular objects, if this list is treated as a type - in this 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case, the item type was defined inline). 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) If this type is a reference to something not in this namespace, assumes 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it is not a list of serializable objects. 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.property_type is PropertyType.CHOICES: 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return all(self._IsListOfSerializableObjects(c) for c in type_.choices) 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.property_type is PropertyType.REF: 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.ref_type in self._types: 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._IsListOfSerializableObjects(self._types[type_.ref_type]) 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return False 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (type_.property_type is PropertyType.ARRAY and 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (self._IsSerializableObjectType(type_.item_type))) 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _IsListOfBaseTypes(self, type_): 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a model.Type, returns whether this type is a list of base type 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) objects (PropertyType.REF types). 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.property_type is PropertyType.CHOICES: 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return all(self._IsListOfBaseTypes(c) for c in type_.choices) 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (type_.property_type is PropertyType.ARRAY and 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self._IsBaseType(type_.item_type)) 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _IsBaseType(self, type_): 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a model.type_, returns whether this type is a base type 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (string, number, boolean, or a list of these). 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) If type_ is a Choices object, returns True if all possible choices are base 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) types. 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(sashab): Remove 'Choices' as a base type once they are wrapped in 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # native Dart classes. 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.property_type is PropertyType.CHOICES: 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return all(self._IsBaseType(c) for c in type_.choices) 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ( 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (self._GetDartType(type_) in ['bool', 'num', 'int', 'double', 'String']) 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) or (type_.property_type is PropertyType.ARRAY 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) and self._IsBaseType(type_.item_type)) 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ) 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def _GetDartType(self, type_): 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """Given a model.Type object, returns its type as a Dart string. 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) """ 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_ is None: 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'void' 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prop_type = type_.property_type 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if prop_type is PropertyType.REF: 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.ref_type in self._types: 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._GetDartType(self._types[type_.ref_type]) 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(sashab): If the type is foreign, it might have to be imported. 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return StripNamespace(type_.ref_type) 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif prop_type is PropertyType.BOOLEAN: 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'bool' 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif prop_type is PropertyType.INTEGER: 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'int' 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif prop_type is PropertyType.INT64: 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'num' 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif prop_type is PropertyType.DOUBLE: 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'double' 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif prop_type is PropertyType.STRING: 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'String' 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif prop_type is PropertyType.ENUM: 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'String' 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif prop_type is PropertyType.CHOICES: 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(sashab): Think of a nice way to generate code for Choices objects 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # in Dart. 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'Object' 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif prop_type is PropertyType.ANY: 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'Object' 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif prop_type is PropertyType.OBJECT: 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # TODO(sashab): type_.name is the name of the function's parameter for 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # inline types defined in functions. Think of a way to generate names 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # for this, or remove all inline type definitions at the start. 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if type_.instance_of is not None: 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return type_.instance_of 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if not isinstance(type_.parent, Function): 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return self._AddPrefix(type_.name) 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'Object' 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif prop_type is PropertyType.FUNCTION: 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'Function' 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif prop_type is PropertyType.ARRAY: 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'List<%s>' % self._GetDartType(type_.item_type) 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) elif prop_type is PropertyType.BINARY: 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 'String' 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raise NotImplementedError(prop_type) 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 763