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