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 |
deleted file mode 100644 |
index 74ffd11a4548a3744e6aa428f860c8308ffd8a69..0000000000000000000000000000000000000000 |
--- a/tools/json_schema_compiler/dart_generator.py |
+++ /dev/null |
@@ -1,763 +0,0 @@ |
-# 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. |
-""" |
- |
-from code import Code |
-from model import Function, PropertyType |
-from schema_util import StripNamespace |
- |
-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) |
- |
-class DartGenerator(object): |
- def __init__(self, dart_overrides_dir=None): |
- self._dart_overrides_dir = dart_overrides_dir |
- |
- def Generate(self, namespace): |
- return _Generator(namespace, self._dart_overrides_dir).Generate() |
- |
- |
-class _Generator(object): |
- """A .dart generator for a namespace. |
- """ |
- |
- def __init__(self, namespace, dart_overrides_dir=None): |
- self._namespace = namespace |
- # TODO(sashab): Once inline type definitions start being added to |
- # self._types, make a _FindType(self, type_) function that looks at |
- # self._namespace.types. |
- self._types = namespace.types |
- |
- # Build a dictionary of Type Name --> Custom Dart code. |
- self._type_overrides = {} |
- if dart_overrides_dir is not None: |
- for filename in os.listdir(dart_overrides_dir): |
- if filename.startswith(namespace.unix_name): |
- with open(os.path.join(dart_overrides_dir, filename)) as f: |
- # Split off the namespace and file extension, leaving just the type. |
- type_path = '.'.join(filename.split('.')[1:-1]) |
- self._type_overrides[type_path] = f.read() |
- |
- # TODO(sashab): Add all inline type definitions to the global Types |
- # dictionary here, so they have proper names, and are implemented along with |
- # all other types. Also update the parameters/members with these types |
- # to reference these new types instead. |
- |
- def Generate(self): |
- """Generates a Code object with the .dart for the entire namespace. |
- """ |
- c = Code() |
- (c.Append(LICENSE) |
- .Append() |
- .Append('// Generated from namespace: %s' % self._namespace.name) |
- .Append() |
- .Append('part of chrome;')) |
- |
- if self._types: |
- (c.Append() |
- .Append('/**') |
- .Append(' * Types') |
- .Append(' */') |
- .Append() |
- ) |
- for type_ in self._types.values(): |
- # Check for custom dart for this whole type. |
- override = self._GetOverride([type_.name], document_with=type_) |
- c.Cblock(override if override is not None else self._GenerateType(type_)) |
- |
- if self._namespace.events: |
- (c.Append('/**') |
- .Append(' * Events') |
- .Append(' */') |
- .Append() |
- ) |
- for event_name in self._namespace.events: |
- c.Cblock(self._GenerateEvent(self._namespace.events[event_name])) |
- |
- (c.Append('/**') |
- .Append(' * Functions') |
- .Append(' */') |
- .Append() |
- ) |
- c.Cblock(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() |
- |
- # Since enums are just treated as strings for now, don't generate their |
- # type. |
- # TODO(sashab): Find a nice way to wrap enum objects. |
- if type_.property_type is PropertyType.ENUM: |
- return c |
- |
- (c.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 = all(not self._IsFunction(p.type_) |
- for p in type_.properties.values()) |
- constructor_fields = [self._GeneratePropertySignature(p) |
- for p in type_.properties.values()] |
- |
- if add_public_constructor: |
- (c.Append('/*') |
- .Append(' * Public constructor') |
- .Append(' */') |
- .Sblock('%(type_name)s({%(constructor_fields)s}) {') |
- ) |
- |
- for prop_name in type_.properties: |
- (c.Sblock('if (%s != null)' % prop_name) |
- .Append('this.%s = %s;' % (prop_name, prop_name)) |
- .Eblock() |
- ) |
- (c.Eblock('}') |
- .Append() |
- ) |
- |
- (c.Append('/*') |
- .Append(' * Private constructor') |
- .Append(' */') |
- .Append('%(type_name)s._proxy(_jsObject) : super._proxy(_jsObject);') |
- ) |
- |
- # Add an accessor (getter & setter) for each property. |
- properties = [p for p in type_.properties.values() |
- if not self._IsFunction(p.type_)] |
- if properties: |
- (c.Append() |
- .Append('/*') |
- .Append(' * Public accessors') |
- .Append(' */') |
- ) |
- for prop in properties: |
- override = self._GetOverride([type_.name, prop.name], document_with=prop) |
- c.Concat(override if override is not None |
- else self._GenerateGetterAndSetter(type_, prop)) |
- |
- # Now add all the methods. |
- methods = [t for t in type_.properties.values() |
- if self._IsFunction(t.type_)] |
- if methods: |
- (c.Append() |
- .Append('/*') |
- .Append(' * Methods') |
- .Append(' */') |
- ) |
- for prop in methods: |
- # Check if there's an override for this method. |
- override = self._GetOverride([type_.name, prop.name], document_with=prop) |
- c.Cblock(override if override is not None |
- else self._GenerateFunction(prop.type_.function)) |
- |
- (c.Eblock('}') |
- .Substitute({ |
- 'type_name': self._AddPrefix(type_.simple_name), |
- 'constructor_fields': ', '.join(constructor_fields) |
- }) |
- ) |
- |
- return c |
- |
- def _GenerateGetterAndSetter(self, type_, prop): |
- """Given a Type and Property, returns the Code object for the getter and |
- setter for that property. |
- """ |
- c = Code() |
- override = self._GetOverride([type_.name, prop.name, '.get'], |
- document_with=prop) |
- c.Cblock(override if override is not None |
- else self._GenerateGetter(type_, prop)) |
- override = self._GetOverride([type_.name, prop.name, '.set']) |
- c.Cblock(override if override is not None |
- else self._GenerateSetter(prop)) |
- return c |
- |
- def _GenerateGetter(self, type_, prop): |
- """Given a Type and Property, returns the Code object for the getter for |
- that property. |
- |
- Also adds the documentation for this property before the method. |
- """ |
- c = Code() |
- c.Concat(self._GenerateDocumentation(prop)) |
- |
- type_name = self._GetDartType(prop.type_) |
- if (self._IsBaseType(prop.type_)): |
- c.Append("%s get %s => JS('%s', '#.%s', this._jsObject);" % |
- (type_name, prop.name, type_name, prop.name)) |
- elif self._IsSerializableObjectType(prop.type_): |
- c.Append("%s get %s => new %s._proxy(JS('', '#.%s', " |
- "this._jsObject));" % |
- (type_name, prop.name, type_name, prop.name)) |
- elif self._IsListOfSerializableObjects(prop.type_): |
- (c.Sblock('%s get %s {' % (type_name, prop.name)) |
- .Append('%s __proxy_%s = new %s();' % (type_name, prop.name, |
- type_name)) |
- .Append("int count = JS('int', '#.%s.length', this._jsObject);" % |
- prop.name) |
- .Sblock("for (int i = 0; i < count; i++) {") |
- .Append("var item = JS('', '#.%s[#]', this._jsObject, i);" % prop.name) |
- .Append('__proxy_%s.add(new %s._proxy(item));' % (prop.name, |
- self._GetDartType(prop.type_.item_type))) |
- .Eblock('}') |
- .Append('return __proxy_%s;' % prop.name) |
- .Eblock('}') |
- ) |
- elif self._IsObjectType(prop.type_): |
- # TODO(sashab): Think of a way to serialize generic Dart objects. |
- if type_name in self._types: |
- c.Append("%s get %s => new %s._proxy(JS('%s', '#.%s', " |
- "this._jsObject));" % |
- (type_name, prop.name, type_name, type_name, prop.name)) |
- else: |
- c.Append("%s get %s => JS('%s', '#.%s', this._jsObject);" % |
- (type_name, prop.name, type_name, prop.name)) |
- else: |
- raise Exception( |
- "Could not generate wrapper for %s.%s: unserializable type %s" % |
- (type_.name, prop.name, type_name) |
- ) |
- return c |
- |
- def _GenerateSetter(self, prop): |
- """Given a Property, returns the Code object for the setter for |
- that property. |
- """ |
- c = Code() |
- type_name = self._GetDartType(prop.type_) |
- wrapped_name = prop.name |
- if not self._IsBaseType(prop.type_): |
- wrapped_name = 'convertArgument(%s)' % prop.name |
- |
- (c.Sblock("void set %s(%s %s) {" % (prop.name, type_name, prop.name)) |
- .Append("JS('void', '#.%s = #', this._jsObject, %s);" % |
- (prop.name, wrapped_name)) |
- .Eblock("}") |
- ) |
- 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 prop.description is not None: |
- 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. |
- """ |
- c = Code() |
- c.Concat(self._GenerateDocumentation(f)) |
- |
- if not self._NeedsProxiedCallback(f): |
- c.Append("%s => %s;" % (self._GenerateFunctionSignature(f), |
- self._GenerateProxyCall(f))) |
- return c |
- |
- (c.Sblock("%s {" % self._GenerateFunctionSignature(f)) |
- .Concat(self._GenerateProxiedFunction(f.callback, f.callback.name)) |
- .Append('%s;' % self._GenerateProxyCall(f)) |
- .Eblock('}') |
- ) |
- |
- return c |
- |
- def _GenerateProxiedFunction(self, f, callback_name): |
- """Given a function (assumed to be a callback), generates the proxied |
- version of this function, which calls |callback_name| if it is defined. |
- |
- Returns a Code object. |
- """ |
- c = Code() |
- proxied_params = [] |
- # A list of Properties, containing List<*> objects that need proxying for |
- # their members (by copying out each member and proxying it). |
- lists_to_proxy = [] |
- for p in f.params: |
- if self._IsBaseType(p.type_): |
- proxied_params.append(p.name) |
- elif self._IsSerializableObjectType(p.type_): |
- proxied_params.append('new %s._proxy(%s)' % ( |
- self._GetDartType(p.type_), p.name)) |
- elif self._IsListOfSerializableObjects(p.type_): |
- proxied_params.append('__proxy_%s' % p.name) |
- lists_to_proxy.append(p) |
- elif self._IsObjectType(p.type_): |
- # TODO(sashab): Find a way to build generic JS objects back in Dart. |
- proxied_params.append('%s' % p.name) |
- elif p.type_.property_type is PropertyType.ARRAY: |
- # TODO(sashab): This might be okay - what if this is a list of |
- # FileEntry elements? In this case, a basic list will proxy the objects |
- # fine. |
- proxied_params.append('%s' % p.name) |
- else: |
- raise Exception( |
- "Cannot automatically create proxy; can't wrap %s, type %s" % ( |
- self._GenerateFunctionSignature(f), self._GetDartType(p.type_))) |
- |
- (c.Sblock("void __proxy_callback(%s) {" % ', '.join(p.name for p in |
- f.params)) |
- .Sblock('if (%s != null) {' % callback_name) |
- ) |
- |
- # Add the proxied lists. |
- for list_to_proxy in lists_to_proxy: |
- (c.Append("%s __proxy_%s = new %s();" % ( |
- self._GetDartType(list_to_proxy.type_), |
- list_to_proxy.name, |
- self._GetDartType(list_to_proxy.type_))) |
- .Sblock("for (var o in %s) {" % list_to_proxy.name) |
- .Append('__proxy_%s.add(new %s._proxy(o));' % (list_to_proxy.name, |
- self._GetDartType(list_to_proxy.type_.item_type))) |
- .Eblock("}") |
- ) |
- |
- (c.Append("%s(%s);" % (callback_name, ', '.join(proxied_params))) |
- .Eblock('}') |
- .Eblock('}') |
- ) |
- return c |
- |
- def _NeedsProxiedCallback(self, f): |
- """Given a function, returns True if this function's callback needs to be |
- proxied, False if not. |
- |
- Function callbacks need to be proxied if they have at least one |
- non-base-type parameter. |
- """ |
- return f.callback and self._NeedsProxy(f.callback) |
- |
- def _NeedsProxy(self, f): |
- """Given a function, returns True if it needs to be proxied, False if not. |
- |
- A function needs to be proxied if any of its members are non-base types. |
- This means that, when the function object is passed to Javascript, it |
- needs to be wrapped in a "proxied" call that converts the JS inputs to Dart |
- objects explicitly, before calling the real function with these new objects. |
- """ |
- return any(not self._IsBaseType(p.type_) for p in f.params) |
- |
- def _GenerateProxyCall(self, function, call_target='this._jsObject'): |
- """Given a function, generates the code to call that function via JS(). |
- Returns a string. |
- |
- |call_target| 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)) |
- """ |
- n_params = len(function.params) |
- if function.callback: |
- n_params += 1 |
- |
- return_type_str = self._GetDartType(function.returns) |
- params = [] |
- |
- # If this object is serializable, don't convert the type from JS - pass the |
- # JS object straight into the proxy. |
- if self._IsSerializableObjectType(function.returns): |
- params.append("''") |
- else: |
- params.append("'%s'" % return_type_str) |
- |
- params.append("'#.%s(%s)'" % (function.name, ', '.join(['#'] * n_params))) |
- params.append(call_target) |
- |
- for param in function.params: |
- if not self._IsBaseType(param.type_): |
- params.append('convertArgument(%s)' % param.name) |
- else: |
- params.append(param.name) |
- if function.callback: |
- # If this isn't a base type, we need a proxied callback. |
- callback_name = function.callback.name |
- if self._NeedsProxiedCallback(function): |
- callback_name = "__proxy_callback" |
- params.append('convertDartClosureToJS(%s, %s)' % (callback_name, |
- len(function.callback.params))) |
- |
- # If the object is serializable, call the proxy constructor for this type. |
- proxy_call = 'JS(%s)' % ', '.join(params) |
- if self._IsSerializableObjectType(function.returns): |
- proxy_call = 'new %s._proxy(%s)' % (return_type_str, proxy_call) |
- |
- return proxy_call |
- |
- 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.Concat(self._GenerateDocumentation(event)) |
- .Sblock('class Event_%(event_name)s extends Event {') |
- ) |
- |
- # If this event needs a proxy, all calls need to be proxied. |
- needs_proxy = self._NeedsProxy(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, |
- convert_optional=True) |
- if needs_proxy: |
- (c.Sblock('%s %s(void callback(%s)) {' % (ret_type, event_func, |
- param_list)) |
- .Concat(self._GenerateProxiedFunction(event, 'callback')) |
- .Append('super.%s(__proxy_callback);' % event_func) |
- .Eblock('}') |
- ) |
- else: |
- c.Append('%s %s(void callback(%s)) => super.%s(callback);' % |
- (ret_type, event_func, param_list, event_func)) |
- c.Append() |
- |
- # Generate the constructor. |
- (c.Append('Event_%(event_name)s(jsObject) : ' |
- 'super._(jsObject, %(param_num)d);') |
- .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. |
- |
- Returns a code object. |
- """ |
- c = Code() |
- (c.Sblock('class API_%s {' % self._namespace.unix_name) |
- .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(): |
- # Check for custom dart for this whole property. |
- override = self._GetOverride([function.name], document_with=function) |
- c.Cblock(override if override is not None |
- else self._GenerateFunction(function)) |
- |
- # Add the constructor. |
- c.Sblock('API_%s(this._jsObject) {' % self._namespace.unix_name) |
- |
- # 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('}') |
- .Eblock('}') |
- ) |
- return c |
- |
- def _GeneratePropertySignature(self, prop): |
- """Given a property, returns a signature for that property. |
- Recursively generates the signature for callbacks. |
- Returns a String for the given property. |
- |
- e.g. |
- bool x |
- void onClosed() |
- void doSomething(bool x, void callback([String x])) |
- """ |
- if self._IsFunction(prop.type_): |
- return self._GenerateFunctionSignature(prop.type_.function) |
- return '%(type)s %(name)s' % { |
- 'type': self._GetDartType(prop.type_), |
- 'name': prop.simple_name |
- } |
- |
- def _GenerateFunctionSignature(self, function, convert_optional=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 convert_optional is True, changes optional parameters to be required. |
- |
- e.g. |
- void onClosed() |
- bool isOpen([String type]) |
- void doSomething(bool x, void callback([String x])) |
- """ |
- sig = '%(return_type)s %(name)s(%(params)s)' |
- |
- if function.returns: |
- return_type = self._GetDartType(function.returns) |
- else: |
- return_type = 'void' |
- |
- return sig % { |
- 'return_type': return_type, |
- 'name': function.simple_name, |
- 'params': self._GenerateParameterList(function.params, |
- function.callback, |
- convert_optional=convert_optional) |
- } |
- |
- def _GenerateParameterList(self, |
- params, |
- callback=None, |
- convert_optional=False): |
- """Given a list of function parameters, generates their signature (as a |
- string). |
- |
- e.g. |
- [String type] |
- bool x, void callback([String x]) |
- |
- If convert_optional is True, changes optional parameters to be required. |
- Useful for callbacks, where optional parameters are treated as required. |
- """ |
- # Params lists (required & optional), to be joined with commas. |
- # TODO(sashab): Don't assume optional params always come after required |
- # ones. |
- params_req = [] |
- params_opt = [] |
- for param in params: |
- p_sig = self._GeneratePropertySignature(param) |
- if param.optional and not convert_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, convert_optional=True) |
- if callback.optional: |
- params_opt.append(c_sig) |
- else: |
- params_req.append(c_sig) |
- |
- # Join the parameters with commas. |
- # Optional parameters have to be in square brackets, e.g.: |
- # |
- # required params | optional params | output |
- # [] | [] | '' |
- # [x, y] | [] | 'x, y' |
- # [] | [a, b] | '[a, b]' |
- # [x, y] | [a, b] | 'x, y, [a, b]' |
- if params_opt: |
- params_opt[0] = '[%s' % params_opt[0] |
- params_opt[-1] = '%s]' % params_opt[-1] |
- param_sets = [', '.join(params_req), ', '.join(params_opt)] |
- |
- # The 'if p' part here is needed to prevent commas where there are no |
- # parameters of a certain type. |
- # If there are no optional parameters, this prevents a _trailing_ comma, |
- # e.g. '(x, y,)'. Similarly, if there are no required parameters, this |
- # prevents a leading comma, e.g. '(, [a, b])'. |
- return ', '.join(p for p in param_sets if p) |
- |
- def _GetOverride(self, key_chain, document_with=None): |
- """Given a list of keys, joins them with periods and searches for them in |
- the custom dart overrides. |
- If there is an override for that key, finds the override code and returns |
- the Code object. If not, returns None. |
- |
- If document_with is not None, adds the documentation for this property |
- before the override code. |
- """ |
- c = Code() |
- contents = self._type_overrides.get('.'.join(key_chain)) |
- if contents is None: |
- return None |
- |
- if document_with is not None: |
- c.Concat(self._GenerateDocumentation(document_with)) |
- for line in contents.strip('\n').split('\n'): |
- c.Append(line) |
- return c |
- |
- def _AddPrefix(self, name): |
- """Given the name of a type, prefixes the namespace (as camelcase) and |
- returns the new name. |
- """ |
- # TODO(sashab): Split the dart library into multiple files, avoiding the |
- # need for this prefixing. |
- return ('%s%s' % ( |
- ''.join(s.capitalize() for s in self._namespace.name.split('.')), |
- name)) |
- |
- def _IsFunction(self, type_): |
- """Given a model.Type, returns whether this type is a function. |
- """ |
- return type_.property_type == PropertyType.FUNCTION |
- |
- def _IsSerializableObjectType(self, type_): |
- """Given a model.Type, returns whether this type is a serializable object. |
- Serializable objects are custom types defined in this namespace. |
- |
- If this object is a reference to something not in this namespace, assumes |
- its a serializable object. |
- """ |
- if type_ is None: |
- return False |
- if type_.property_type is PropertyType.CHOICES: |
- return all(self._IsSerializableObjectType(c) for c in type_.choices) |
- if type_.property_type is PropertyType.REF: |
- if type_.ref_type in self._types: |
- return self._IsObjectType(self._types[type_.ref_type]) |
- return True |
- if (type_.property_type == PropertyType.OBJECT |
- and type_.instance_of in self._types): |
- return self._IsObjectType(self._types[type_.instance_of]) |
- return False |
- |
- def _IsObjectType(self, type_): |
- """Given a model.Type, returns whether this type is an object. |
- """ |
- return (self._IsSerializableObjectType(type_) |
- or type_.property_type in [PropertyType.OBJECT, PropertyType.ANY]) |
- |
- def _IsListOfSerializableObjects(self, type_): |
- """Given a model.Type, returns whether this type is a list of serializable |
- objects (or regular objects, if this list is treated as a type - in this |
- case, the item type was defined inline). |
- |
- If this type is a reference to something not in this namespace, assumes |
- it is not a list of serializable objects. |
- """ |
- if type_.property_type is PropertyType.CHOICES: |
- return all(self._IsListOfSerializableObjects(c) for c in type_.choices) |
- if type_.property_type is PropertyType.REF: |
- if type_.ref_type in self._types: |
- return self._IsListOfSerializableObjects(self._types[type_.ref_type]) |
- return False |
- return (type_.property_type is PropertyType.ARRAY and |
- (self._IsSerializableObjectType(type_.item_type))) |
- |
- def _IsListOfBaseTypes(self, type_): |
- """Given a model.Type, returns whether this type is a list of base type |
- objects (PropertyType.REF types). |
- """ |
- if type_.property_type is PropertyType.CHOICES: |
- return all(self._IsListOfBaseTypes(c) for c in type_.choices) |
- return (type_.property_type is PropertyType.ARRAY and |
- self._IsBaseType(type_.item_type)) |
- |
- def _IsBaseType(self, type_): |
- """Given a model.type_, returns whether this type is a base type |
- (string, number, boolean, or a list of these). |
- |
- If type_ is a Choices object, returns True if all possible choices are base |
- types. |
- """ |
- # TODO(sashab): Remove 'Choices' as a base type once they are wrapped in |
- # native Dart classes. |
- if type_.property_type is PropertyType.CHOICES: |
- return all(self._IsBaseType(c) for c in type_.choices) |
- return ( |
- (self._GetDartType(type_) in ['bool', 'num', 'int', 'double', 'String']) |
- or (type_.property_type is PropertyType.ARRAY |
- and self._IsBaseType(type_.item_type)) |
- ) |
- |
- def _GetDartType(self, type_): |
- """Given a model.Type object, returns its type as a Dart string. |
- """ |
- if type_ is None: |
- return 'void' |
- |
- prop_type = type_.property_type |
- if prop_type is PropertyType.REF: |
- if type_.ref_type in self._types: |
- return self._GetDartType(self._types[type_.ref_type]) |
- # TODO(sashab): If the type is foreign, it might have to be imported. |
- return StripNamespace(type_.ref_type) |
- elif prop_type is PropertyType.BOOLEAN: |
- return 'bool' |
- elif prop_type is PropertyType.INTEGER: |
- return 'int' |
- elif prop_type is PropertyType.INT64: |
- return 'num' |
- elif prop_type is PropertyType.DOUBLE: |
- return 'double' |
- elif prop_type is PropertyType.STRING: |
- return 'String' |
- elif prop_type is PropertyType.ENUM: |
- return 'String' |
- elif prop_type is PropertyType.CHOICES: |
- # TODO(sashab): Think of a nice way to generate code for Choices objects |
- # in Dart. |
- return 'Object' |
- elif prop_type is PropertyType.ANY: |
- return 'Object' |
- elif prop_type is PropertyType.OBJECT: |
- # TODO(sashab): type_.name is the name of the function's parameter for |
- # inline types defined in functions. Think of a way to generate names |
- # for this, or remove all inline type definitions at the start. |
- if type_.instance_of is not None: |
- return type_.instance_of |
- if not isinstance(type_.parent, Function): |
- return self._AddPrefix(type_.name) |
- return 'Object' |
- elif prop_type is PropertyType.FUNCTION: |
- return 'Function' |
- elif prop_type is PropertyType.ARRAY: |
- return 'List<%s>' % self._GetDartType(type_.item_type) |
- elif prop_type is PropertyType.BINARY: |
- return 'String' |
- else: |
- raise NotImplementedError(prop_type) |
- |