Index: tools/json_schema_compiler/dart_generator.py |
diff --git a/tools/json_schema_compiler/dart_generator.py b/tools/json_schema_compiler/dart_generator.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a1855b72aff7c41597b0d6c55c6299a7be7f96f3 |
--- /dev/null |
+++ b/tools/json_schema_compiler/dart_generator.py |
@@ -0,0 +1,615 @@ |
+# Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+""" |
+Generator language component for compiler.py that adds Dart language support. |
+ |
+Pass 'dart' with the -l flag to compiler.py to activate the use of this library. |
+""" |
+ |
+from collections import defaultdict |
not at google - send to devlin
2013/01/29 16:37:08
unused
sashab
2013/01/30 05:26:03
Done.
|
+ |
+from code import Code |
+from model import * |
+ |
+import os |
+from datetime import datetime |
+ |
+LICENSE = (""" |
+// Copyright (c) %s, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file.""" % |
+datetime.now().year) |
not at google - send to devlin
2013/01/29 16:37:08
indent this line?
sashab
2013/01/30 05:26:03
Done.
|
+ |
+class DartGenerator(object): |
+ """A .dart generator for a namespace. |
+ """ |
+ |
+ def __init__(self, namespace, custom_dart_folder): |
not at google - send to devlin
2013/01/29 16:37:08
IMO like you said in the doc, "overrides" would be
sashab
2013/01/30 05:26:03
Done.
|
+ self._namespace = namespace |
+ self._types = namespace.types |
+ |
+ # Build a dictionary of Type Name --> Custom Dart code. |
+ self._custom_dart = {} |
+ if custom_dart_folder: |
not at google - send to devlin
2013/01/29 16:37:08
If custom_dart_folder is optional then make the ar
sashab
2013/01/30 05:26:03
Done.
|
+ for filename in os.listdir(custom_dart_folder): |
+ if filename.startswith(namespace.unix_name): |
+ with open(os.path.join(custom_dart_folder, filename)) as f: |
+ # Split off the namespace and file extension, leaving just the type. |
+ type_path = '.'.join(filename.split('.')[1:-1]) |
+ self._custom_dart[type_path] = f.read() |
+ print self._custom_dart |
+ global x |
+ x= self._namespace |
not at google - send to devlin
2013/01/29 16:37:08
delete 3 lines above here?
sashab
2013/01/30 05:26:03
Done.
|
+ |
+ def Generate(self): |
+ """Generates a Code object with the .dart for the entire namespace. |
+ """ |
+ c = Code() |
+ (c.Append(LICENSE) |
+ .Append() |
+ .Append('part of chrome;')) |
+ |
+ # Add all types. |
not at google - send to devlin
2013/01/29 16:37:08
comment not useful
sashab
2013/01/30 05:26:03
Done.
|
+ if self._types: |
+ (c.Append() |
+ .Append('/**') |
+ .Append(' * Types') |
+ .Append(' */') |
+ ) |
+ for type_name in self._types: |
+ c.Concat(self._GenerateType(self._types[type_name])) |
+ |
+ # Add all events. |
not at google - send to devlin
2013/01/29 16:37:08
ditto
sashab
2013/01/30 05:26:03
Done.
|
+ if self._namespace.events: |
+ (c.Append() |
+ .Append('/**') |
+ .Append(' * Events') |
+ .Append(' */') |
+ ) |
+ for event_name in self._namespace.events: |
+ c.Concat(self._GenerateEvent(self._namespace.events[event_name])) |
+ |
+ # Add main class for this file. |
not at google - send to devlin
2013/01/29 16:37:08
ditto
sashab
2013/01/30 05:26:03
Done.
|
+ (c.Append() |
+ .Append('/**') |
+ .Append(' * Functions') |
+ .Append(' */') |
+ ) |
+ c.Concat(self._GenerateMainClass()) |
+ |
+ return c |
+ |
+ def _GenerateType(self, type_): |
+ """Given a Type object, returns the Code with the .dart for this |
+ type's definition. |
+ |
+ Assumes this type is a Parameter Type (creatable by user), and creates an |
+ object that extends ChromeObject. All parameters are specifiable as named |
+ arguments in the constructor, and all methods are wrapped with getters and |
+ setters that hide the JS() implementation. |
+ """ |
+ c = Code() |
+ (c.Append() |
+ .Concat(self._GenerateDocumentation(type_)) |
+ .Sblock('class %(type_name)s extends ChromeObject {') |
+ ) |
+ |
+ # Check whether this type has function members. If it does, don't allow |
+ # public construction. |
+ add_public_constructor = True |
not at google - send to devlin
2013/01/29 16:37:08
add_public_constructor = any(self._IsFunction(p)
sashab
2013/01/30 05:26:03
Done.
|
+ for prop_name in type_.properties: |
+ if self._IsFunction(type_.properties[prop_name]): |
+ add_public_constructor = False |
+ break |
+ |
+ constructor_fields = [] |
not at google - send to devlin
2013/01/29 16:37:08
constructor_fields = [self._GeneratePropertySignat
sashab
2013/01/30 05:26:03
Done.
|
+ for prop_name in type_.properties: |
+ constructor_fields.append( |
+ self._GeneratePropertySignature(type_.properties[prop_name], |
+ prepend_this = False, |
+ omitBasicTypes = False)) |
not at google - send to devlin
2013/01/29 16:37:08
prepend_this = False -> prepend_this=False
omitBas
sashab
2013/01/30 05:26:03
Done.
|
+ |
+ # Add the public constructor. |
not at google - send to devlin
2013/01/29 16:37:08
I think you can leave this comment out, the variab
sashab
2013/01/30 05:26:03
Done.
|
+ if add_public_constructor: |
+ (c.Append('/*') |
+ .Append(' * Public constructor') |
+ .Append(' */') |
+ .Sblock('%(type_name)s({%(constructor_fields)s}) {') |
+ ) |
+ |
+ for prop_name in type_.properties: |
+ c.Append('this.%s = %s;' % (prop_name, prop_name)) |
+ (c.Eblock('}') |
+ .Append() |
+ ) |
+ |
+ # Add the private constructor. |
not at google - send to devlin
2013/01/29 16:37:08
ditto
sashab
2013/01/30 05:26:03
Done.
|
+ (c.Append('/*') |
+ .Append(' * Private constructor') |
+ .Append(' */') |
+ .Append('%(type_name)s._proxy(_jsObject) : super._proxy(_jsObject);') |
+ ) |
+ |
+ # Add an accessor (getter & setter) for each property. |
+ properties = [t for t in type_.properties.values() |
+ if not self._IsFunction(t)] |
not at google - send to devlin
2013/01/29 16:37:08
nit: p would be a slighty more appropriate tempora
sashab
2013/01/30 05:26:03
Done.
|
+ if properties: |
+ (c.Append() |
+ .Append('/*') |
+ .Append(' * Public accessors') |
+ .Append(' */') |
+ ) |
+ for prop in properties: |
+ type_name = self._GetPropertyType(prop) |
+ prop_is_base_type = self._IsBaseType(prop) |
+ |
+ # Check for custom dart for this whole property. |
+ overwrite_key = '%s.%s' % (type_.name, prop.name) |
not at google - send to devlin
2013/01/29 16:37:08
overwrite -> override?
sashab
2013/01/30 05:26:03
Done.
|
+ if overwrite_key in self._custom_dart: |
not at google - send to devlin
2013/01/29 16:37:08
A common idiom is like:
override = self._custom_d
sashab
2013/01/30 05:26:03
Done.
|
+ contents = self._custom_dart[overwrite_key] |
+ if contents.strip(): |
not at google - send to devlin
2013/01/29 16:37:08
Why is this guard necessary? If it is for some rea
sashab
2013/01/30 05:26:03
If you want to "hide" a function completely, you c
not at google - send to devlin
2013/01/31 02:08:48
So is this an alternative to specifying nodart?
sashab
2013/01/31 04:41:40
Exactly. The good thing about this is its all in t
|
+ (c.Append() |
+ .Concat(self._GenerateDocumentation(prop)) |
+ ) |
+ for line in contents.split('\n'): |
+ c.Append(line) |
+ else: |
+ # Add the getter. |
+ getter_key = '%s.%s.get' % (type_.name, prop.name) |
+ if getter_key in self._custom_dart: |
+ contents = self._custom_dart[getter_key] |
+ if contents.strip(): |
+ # Add the documentation for this property. |
+ (c.Append() |
+ .Concat(self._GenerateDocumentation(prop)) |
+ ) |
+ for line in contents.split('\n'): |
+ c.Append(line) |
+ else: |
+ # Add the documentation for this property. |
+ (c.Append() |
+ .Concat(self._GenerateDocumentation(prop)) |
+ ) |
+ |
+ # TODO(sashab): Serialize generic Dart objects differently. |
+ if prop_is_base_type or self._IsObjectType(prop): |
+ c.Append("%s get %s => JS('%s', '#.%s', this._jsObject);" % |
+ (type_name, prop.name, type_name, prop.name)) |
+ elif prop.type_.property_type == PropertyType.REF: |
+ c.Append("%s get %s => new %s._proxy(JS('', '#.%s', " |
+ "this._jsObject));" |
+ % (type_name, prop.name, type_name, prop.name)) |
+ else: |
+ # TODO(sashab): What to do in this situation? Unserializable type. |
not at google - send to devlin
2013/01/29 16:37:08
throw an exception?
sashab
2013/01/30 05:26:03
Done.
|
+ c.Append("%s get %s => JS('%s', '#.%s', this._jsObject);" % |
+ (type_name, prop.name, type_name, prop.name)) |
+ |
+ # Add the setter. |
+ setter_key = '%s.%s.set' % (type_.name, prop.name) |
+ if setter_key in self._custom_dart: |
+ contents = self._custom_dart[setter_key] |
+ if contents.strip(): |
+ c.Append() |
+ for line in contents.split('\n'): |
+ c.Append(line) |
not at google - send to devlin
2013/01/29 16:37:08
This pattern (reading from custom dart and then ap
sashab
2013/01/30 05:26:03
Done.
|
+ else: |
+ wrapped_name = prop.name |
+ if not prop_is_base_type: |
+ wrapped_name = 'convertArgument(%s)' % prop.name |
+ |
+ (c.Append() |
+ .Sblock("void set %s(%s %s) {" % (prop.name, type_name, prop.name)) |
+ .Append("JS('void', '#.%s = #', this._jsObject, %s);" % |
+ (prop.name, wrapped_name)) |
+ .Eblock("}") |
+ ) |
+ |
+ # Now add all the function properties. |
not at google - send to devlin
2013/01/29 16:37:08
s/function properties/methods/ ?
sashab
2013/01/30 05:26:03
Done.
|
+ function_properties = [t for t in type_.properties.values() |
+ if self._IsFunction(t)] |
+ if function_properties: |
+ (c.Append() |
+ .Append('/*') |
+ .Append(' * Methods') |
+ .Append(' */') |
+ ) |
+ for prop in function_properties: |
+ c.Concat(self._GenerateFunction(prop.type_.function)) |
+ |
+ (c.Eblock('}') |
+ .Substitute({ |
+ 'type_name': type_.simple_name, |
+ 'constructor_fields': ', '.join(constructor_fields) |
+ }) |
+ ) |
+ |
+ return c |
+ |
+ def _GenerateDocumentation(self, prop): |
+ """Given an object, generates the documentation for this object (as a |
+ code string) and returns the Code object. |
+ |
+ Returns an empty code object if the object has no documentation. |
+ |
+ Uses triple-quotes for the string. |
+ """ |
+ c = Code() |
+ if not hasattr(prop, 'description'): |
not at google - send to devlin
2013/01/29 16:37:08
"hasattr" should no longer be necessary (and we sh
sashab
2013/01/30 05:26:03
Done.
|
+ return c |
+ |
+ if prop.description: |
not at google - send to devlin
2013/01/29 16:37:08
oh, there's a check here anyway. I prefer the chec
sashab
2013/01/30 05:26:03
Hopefully I've made it a little clearer now.
|
+ for line in prop.description.split('\n'): |
+ c.Comment(line, comment_prefix='/// ') |
+ return c |
+ |
+ |
+ def _GenerateFunction(self, f): |
+ """Returns the Code object for the given function. |
+ """ |
+ return (Code() |
+ .Append() |
+ .Concat(self._GenerateDocumentation(f)) |
+ .Append("%s => %s;" % (self._GenerateFunctionSignature(f), |
+ self._GenerateProxyCall(f))) |
+ ) |
+ |
+ def _GenerateProxyCall(self, function, callTarget='this._jsObject'): |
not at google - send to devlin
2013/01/29 16:37:08
call_target
sashab
2013/01/30 05:26:03
Done.
|
+ """Given a function, generates the code to call that function via JS(). |
+ Returns a string. |
+ |
+ |callTarget| is the name of the object to call the function on. The default |
+ is this._jsObject. |
+ |
+ e.g. |
+ JS('void', '#.resizeTo(#, #)', this._jsObject, width, height) |
+ JS('void', '#.setBounds(#)', this._jsObject, convertArgument(bounds)) |
+ """ |
+ |
+ format = ("JS('%(return_type)s', " |
+ "'#.%(name)s(%(param_hashes)s)', " |
+ "%(target)s%(params)s)") |
+ |
+ params = "" |
+ if function.params: |
+ params_wrapped = [] |
+ for param in function.params: |
+ if not self._IsBaseType(param): |
+ params_wrapped.append('convertArgument(%s)' % param.name) |
+ else: |
+ params_wrapped.append(param.name) |
+ params = ', ' + ', '.join(params_wrapped) |
not at google - send to devlin
2013/01/29 16:37:08
the adding comma stuff is a bit icky, could you ju
sashab
2013/01/30 05:26:03
Done.
|
+ |
+ return format % { |
+ 'return_type': self._GetPropertyType(function.returns), |
+ 'name': function.name, |
+ 'param_hashes': ', '.join('#' for p in function.params), |
+ 'target': callTarget, |
+ 'params': params |
+ } |
+ |
+ def _GenerateEvent(self, event): |
+ """Given a Function object, returns the Code with the .dart for this event, |
+ represented by the function. |
+ |
+ All events extend the Event base type. |
+ """ |
+ c = Code() |
+ |
+ # Add documentation for this event. |
+ (c.Append() |
+ .Concat(self._GenerateDocumentation(event)) |
+ .Sblock('class Event_%(event_name)s extends Event {') |
+ ) |
+ |
+ # Override Event callback type definitions. |
+ for ret_type, event_func in (('void', 'addListener'), |
+ ('void', 'removeListener'), |
+ ('bool', 'hasListener')): |
+ |
+ param_list = self._GenerateParameterList(event.params, event.callback, |
+ allow_optional = False) |
+ |
+ c.Append('%s %s(void callback(%s)) => super.%s(callback);' % |
+ (ret_type, event_func, param_list, event_func)) |
+ |
+ # Generate the constructor. |
+ (c.Append() |
+ .Append('Event_%(event_name)s(jsObject) : ' |
+ 'super(jsObject, %(param_num)d);') |
+ ) |
+ |
+ (c.Eblock('}') |
+ .Substitute({ |
+ 'event_name': self._namespace.unix_name + '_' + event.name, |
+ 'param_num': len(event.params) |
+ }) |
+ ) |
+ |
+ return c |
+ |
+ def _GenerateMainClass(self): |
+ """Generates the main class for this file, which links to all functions |
+ and events. |
+ |
+ Includes a ChromeApi member variable to represent the connection. |
+ |
+ Returns a code object. |
+ """ |
+ c = Code() |
+ (c.Append() |
+ .Sblock('class API_%(namespace_name)s {') |
+ .Append('/*') |
+ .Append(' * API connection') |
+ .Append(' */') |
+ .Append('Object _jsObject;') |
+ ) |
+ |
+ # Add events. |
+ if self._namespace.events: |
+ (c.Append() |
+ .Append('/*') |
+ .Append(' * Events') |
+ .Append(' */') |
+ ) |
+ for event_name in self._namespace.events: |
+ c.Append('Event_%s_%s %s;' % (self._namespace.unix_name, event_name, |
+ event_name)) |
+ |
+ # Add functions. |
+ if self._namespace.functions: |
+ (c.Append() |
+ .Append('/*') |
+ .Append(' * Functions') |
+ .Append(' */') |
+ ) |
+ for function in self._namespace.functions.values(): |
+ c.Concat(self._GenerateFunction(function)) |
+ |
+ # Add the constructor. |
+ (c.Append() |
+ .Sblock('API_%(namespace_name)s(this._jsObject) {') |
+ ) |
+ |
+ # Add events to constructor. |
+ for event_name in self._namespace.events: |
+ c.Append("%s = new Event_%s_%s(JS('', '#.%s', this._jsObject));" % |
+ (event_name, self._namespace.unix_name, event_name, event_name)) |
+ c.Eblock('}') |
+ |
+ (c.Eblock('}') |
+ .Substitute({ |
+ 'namespace_name': self._namespace.unix_name |
not at google - send to devlin
2013/01/29 16:37:08
substitution only used once, just %s it above?
sashab
2013/01/30 05:26:03
Done.
|
+ }) |
+ ) |
+ |
+ return c |
+ |
+ def _GeneratePropertySignature(self, prop, prepend_this=False, |
+ omitBasicTypes=False, |
+ functionsAsObjects=False, |
+ withGetKeyword=False): |
not at google - send to devlin
2013/01/29 16:37:08
functionsAsObjects -> functions_as_objects
withGet
sashab
2013/01/30 05:26:03
Fixed the camelcase problems. Removed the unused p
|
+ """Given a property, returns a signature for that property. |
+ Recursively generates the signature for callbacks. |
+ Returns a String for the given property. |
+ |
+ * If |prepend_this| is True, prepends "this." to all variable names. |
+ * If |omitBasicTypes| is True, only adds type names for function types. |
+ * If |functionsAsObjects| is True, treats callbacks as basic types and |
+ prepends the type 'Function'. |
+ * If |withGetKeyword| is True, adds the word 'get' between the property's |
+ type and name. Used for getters in dart. |
+ |
+ e.g. |
+ bool x |
+ void onClosed() |
+ void doSomething(bool x, void callback([String x])) |
+ |
+ e.g. If prepend_this is True: |
+ bool this.x |
+ void this.onClosed() |
+ void this.doSomething(bool x, void callback([String x])) |
+ |
+ e.g. If omitBasicTypes is True: |
+ this.x |
+ void onClosed() |
+ void doSomething(bool x, void callback([String x])) |
+ |
+ e.g. If functionsAsObjects is True: |
+ bool x |
+ Function onClosed |
+ Function doSomething |
+ |
+ e.g. If withGetKeyword and functionsAsObjects is True: |
+ bool get x |
+ Function get onClosed |
+ Function get doSomething |
+ """ |
+ if self._IsFunction(prop) and not functionsAsObjects: |
+ return self._GenerateFunctionSignature(prop.type_.function, prepend_this) |
not at google - send to devlin
2013/01/29 16:37:08
for optional arguments, be explicit, it's easier t
sashab
2013/01/30 05:26:03
Removed this parameter pass anyway, but note taken
|
+ else: |
+ name_parts = [prop.simple_name] |
+ if prepend_this: |
+ name_parts[0] = 'this.' + name_parts[0] |
not at google - send to devlin
2013/01/29 16:37:08
might be a bit more concise as
name = '%s%s' % ('
sashab
2013/01/30 05:26:03
Not used anymore anyway.
|
+ if withGetKeyword: |
+ name_parts = ['get'] + name_parts |
not at google - send to devlin
2013/01/29 16:37:08
somewhat likewise, like
if with_get_keyword:
na
sashab
2013/01/30 05:26:03
Not used anymore anyway.
|
+ |
+ name = ' '.join(name_parts) |
+ type_ = (self._GetPropertyType(prop) + ' ') if not omitBasicTypes else '' |
+ |
+ return '%(type)s%(name)s' % { |
+ 'type': type_, |
+ 'name': name |
+ } |
+ |
+ def _GenerateFunctionSignature(self, function, prepend_this=False): |
+ """Given a function object, returns the signature for that function. |
+ Recursively generates the signature for callbacks. |
+ Returns a String for the given function. |
+ |
+ If prepend_this is True, adds "this." to the function's name. |
+ |
+ e.g. |
+ void onClosed() |
+ bool isOpen([String type]) |
+ void doSomething(bool x, void callback([String x])) |
+ |
+ e.g. If prepend_this is True: |
+ void this.onClosed() |
+ bool this.isOpen([String type]) |
+ void this.doSomething(bool x, void callback([String x])) |
+ """ |
+ sig = '%(return_type)s %(name)s(%(params)s)' |
+ |
+ # Get function return type. |
+ if function.returns: |
+ return_type = self._GetPropertyType(function.returns) |
+ else: |
+ return_type = 'void' |
+ |
+ # Get function name. |
not at google - send to devlin
2013/01/29 16:37:08
comment here and above seems unnecessary
sashab
2013/01/30 05:26:03
Done.
|
+ function_name = function.simple_name |
+ if prepend_this: |
+ function_name = 'this.' + function_name |
not at google - send to devlin
2013/01/29 16:37:08
use 'this.%s' % function_name rather than string c
sashab
2013/01/30 05:26:03
No longer used, but note taken.
|
+ |
+ return sig % { |
+ 'return_type': return_type, |
+ 'name': function_name, |
+ 'params': self._GenerateParameterList(function.params, |
+ getattr(function, 'callback', None)) |
not at google - send to devlin
2013/01/29 16:37:08
getattr/reflection shouldn't be necessary, if ther
sashab
2013/01/30 05:26:03
Done.
|
+ } |
+ |
+ def _GenerateParameterList(self, params, callback=None, |
+ allow_optional=True): |
+ """Given a list of function parameters, generates their signature (as a |
+ string). |
+ |
+ e.g. |
+ [String type] |
+ bool x, void callback([String x]) |
+ |
+ If allow_optional is False, ignores optional parameters. Useful for |
+ callbacks, where optional parameters are not used. |
+ """ |
+ # params lists (required & optional), to be joined with ,'s |
+ # FIXME(sashab): assuming all optional params come after required ones |
+ params_req = [] |
+ params_opt = [] |
+ for param in params: |
+ p_sig = self._GeneratePropertySignature(param) |
+ if allow_optional and param.optional: |
+ params_opt.append(p_sig) |
+ else: |
+ params_req.append(p_sig) |
+ |
+ # Add the callback, if it exists. |
+ if callback: |
+ c_sig = self._GenerateFunctionSignature(callback) |
+ if callback.optional: |
+ params_opt.append(c_sig) |
+ else: |
+ params_req.append(c_sig) |
+ |
+ # join params |
not at google - send to devlin
2013/01/29 16:37:08
comment doesn't look right, also, can this all be
sashab
2013/01/30 05:26:03
Fixed comment.
Optional parameters have to be in
|
+ params = '' |
+ if params_req: |
+ params += ', '.join(params_req) |
+ if params_opt: |
+ params += ', ' |
+ if params_opt: |
+ params += '[' + ', '.join(params_opt) + ']' |
+ |
+ return params |
+ |
+ def _GetNamespace(self, name): |
+ """Given a name a.b.c, returns the namespace (in this case, a.b). |
+ """ |
+ return name.rsplit('.', 1)[0] |
+ |
+ def _GetBaseName(self, name): |
+ """Given a name a.b.c, returns the base name of the path (in this case, c). |
+ """ |
+ return name.rsplit('.', 1)[1] |
not at google - send to devlin
2013/01/29 16:37:08
I think there are utils for this nand GetNamespace
sashab
2013/01/30 05:26:03
Removed; replaced usages with the ones from schema
|
+ |
+ def _IsFunction(self, prop): |
+ """Given a model.Property, returns whether this type is a function. |
+ """ |
+ return prop.type_.property_type == PropertyType.FUNCTION |
+ |
+ def _IsObjectType(self, prop): |
+ """Given a model.Property, returns whether this type is an object. |
+ """ |
+ return (prop.type_.property_type == PropertyType.OBJECT or |
+ prop.type_.property_type == PropertyType.ANY) |
not at google - send to devlin
2013/01/29 16:37:08
return prop.type_.property_name in [PropertyType.O
sashab
2013/01/30 05:26:03
Done.
|
+ |
+ def _IsBaseType(self, prop): |
+ """Given a model.Property, returns whether this type is a base type |
+ (string, number or boolean). |
+ """ |
+ base_type = self._GetPropertyType(prop) |
+ if base_type in ['bool', 'num', 'int', 'double', 'String']: |
+ return True |
+ return False |
not at google - send to devlin
2013/01/29 16:37:08
return self._GetPropertyType(prop) in ['bool', 'nu
sashab
2013/01/30 05:26:03
Done.
|
+ |
+ def _GetReferencedType(self, name): |
+ """Given the name of a referenced type, returns the type object for that |
not at google - send to devlin
2013/01/29 16:37:08
unused?
sashab
2013/01/30 05:26:03
Removed.
|
+ reference. |
+ |
+ Returns None if the type is not found. |
+ """ |
+ if name in self._namespace.types: |
+ return self._namespace.types[name] |
+ return None |
+ |
+ def _GetPropertyType(self, prop): |
+ """Given a model.Property object, returns its type as a Dart string. |
+ """ |
+ if prop == None: |
not at google - send to devlin
2013/01/29 16:37:08
is None
sashab
2013/01/30 05:26:03
Done.
|
+ return 'void' |
+ |
+ dart_type = None |
+ type_ = prop.type_.property_type |
+ |
+ if type_ == None: |
not at google - send to devlin
2013/01/29 16:37:08
for all comparisons here, use "is" not ==
sashab
2013/01/30 05:26:03
Done.
|
+ dart_type = 'void' |
+ elif type_ == PropertyType.REF: |
+ if self._GetNamespace(prop.type_.ref_type) == self._namespace.name: |
+ # This type is in this namespace; just use its base name. |
+ dart_type = self._GetBaseName(prop.type_.ref_type) |
+ else: |
+ # TODO(sashab): Work out how to import this foreign type. |
+ dart_type = prop.type_.ref_type |
+ elif type_ == PropertyType.BOOLEAN: |
+ dart_type = 'bool' |
not at google - send to devlin
2013/01/29 16:37:08
return 'bool'
sashab
2013/01/30 05:26:03
Done.
|
+ elif type_ == PropertyType.INTEGER: |
+ dart_type = 'int' |
not at google - send to devlin
2013/01/29 16:37:08
return 'int'
(etc)
sashab
2013/01/30 05:26:03
Done.
|
+ elif type_ == PropertyType.INT64: |
+ dart_type = 'num' |
+ elif type_ == PropertyType.DOUBLE: |
+ dart_type = 'double' |
+ elif type_ == PropertyType.STRING: |
+ dart_type = 'String' |
+ elif type_ == PropertyType.ENUM: |
+ dart_type = 'String' |
+ elif type_ == PropertyType.CHOICES: |
+ # TODO(sashab): What is Choices? Is it closer to a Map? |
not at google - send to devlin
2013/01/29 16:37:08
who are you asking?
sashab
2013/01/30 05:26:03
Anyone who knows? ^^
What is the Dart equivalent
not at google - send to devlin
2013/01/31 02:08:48
Heh. I was just making sure you weren't asking me
sashab
2013/01/31 04:41:40
Object will support all types, but obviously stric
|
+ dart_type = 'Object' |
+ elif type_ == PropertyType.ANY: |
+ dart_type = 'Object' |
+ elif type_ == PropertyType.OBJECT: |
+ # TODO(sashab): Work out a mapped type name? |
not at google - send to devlin
2013/01/29 16:37:08
who are you asking?
sashab
2013/01/30 05:26:03
That was directed at myself; not sure what to do h
not at google - send to devlin
2013/01/31 02:08:48
uninformed idea: could you just not generate type
sashab
2013/01/31 04:41:40
Yes, that's why its "Object" if it can't figure ou
not at google - send to devlin
2013/02/02 00:45:47
Yep, I get that - but I presume ultimately that th
sashab
2013/02/04 05:09:27
Ohhhh right, I understand what you're saying now.
|
+ dart_type = prop.type_.instance_of or 'Object' |
not at google - send to devlin
2013/02/02 00:45:47
^^^
That said you could also generate for choices
sashab
2013/02/04 05:09:27
This is a great idea. Let me talk this over with t
|
+ elif type_ == PropertyType.FUNCTION: |
+ dart_type = 'Function' |
+ elif type_ == PropertyType.ARRAY: |
+ if hasattr(prop, 'item_type'): |
not at google - send to devlin
2013/01/29 16:37:08
if it's an ARRAY it will always have an item_type,
sashab
2013/01/30 05:26:03
Done.
|
+ container_type = self._GetPropertyType(prop.item_type) |
+ dart_type = 'List<%s>' % container_type |
+ else: |
+ dart_type = 'List' |
+ elif type_ == PropertyType.BINARY: |
+ dart_type = 'String' |
+ else: |
+ raise NotImplementedError(type_) |
+ |
+ return dart_type.strip() |
not at google - send to devlin
2013/01/29 16:37:08
why do you need to .strip()?
sashab
2013/01/30 05:26:03
Old fix; removed.
|