示例#1
0
    def _generate_struct_class(self, namespace, data_type):
        if data_type.doc:
            doc = self.process_doc(data_type.doc, self._docf)
        else:
            doc = 'The {} struct'.format(fmt_class(data_type.name))
        self.emit_wrapped_text(doc, prefix='/// ', width=120)
        protocols = []
        if not data_type.parent_type:
            protocols.append('CustomStringConvertible')

        with self.class_block(data_type, protocols=protocols):
            for field in data_type.fields:
                fdoc = self.process_doc(field.doc,
                    self._docf) if field.doc else undocumented
                self.emit_wrapped_text(fdoc, prefix='/// ', width=120)
                self.emit('public let {}: {}'.format(
                    fmt_var(field.name),
                    fmt_type(field.data_type),
                ))
            self._generate_struct_init(namespace, data_type)

            decl = 'public var' if not data_type.parent_type else 'public override var'

            with self.block('{} description: String'.format(decl)):
                cls = fmt_class(data_type.name)+'Serializer'
                self.emit('return "\(SerializeUtil.prepareJSONForSerialization' +
                          '({}().serialize(self)))"'.format(cls))

        self._generate_struct_class_serializer(namespace, data_type)
示例#2
0
    def _generate_union_type(self, namespace, data_type):
        if data_type.doc:
            doc = self.process_doc(data_type.doc, self._docf)
        else:
            doc = 'The {} union'.format(fmt_class(data_type.name))
        self.emit_wrapped_text(doc, prefix='/// ', width=120)

        class_type = fmt_class(data_type.name)
        with self.block(
                'public enum {}: CustomStringConvertible'.format(class_type)):
            for field in data_type.all_fields:
                typ = self._format_tag_type(namespace, field.data_type)

                fdoc = self.process_doc(
                    field.doc,
                    self._docf) if field.doc else 'An unspecified error.'
                self.emit_wrapped_text(fdoc, prefix='/// ', width=120)
                self.emit('case {}{}'.format(fmt_var(field.name), typ))
            self.emit()
            with self.block('public var description: String'):
                cls = class_type + 'Serializer'
                self.emit(
                    'return "\\(SerializeUtil.prepareJSONForSerialization' +
                    '({}().serialize(self)))"'.format(cls))

        self._generate_union_serializer(data_type)
示例#3
0
    def _generate_struct_class(self, namespace, data_type):
        if data_type.doc:
            doc = self.process_doc(data_type.doc, self._docf)
        else:
            doc = 'The {} struct'.format(fmt_class(data_type.name))
        self.emit_wrapped_text(doc, prefix='/// ', width=120)
        protocols = []
        if not data_type.parent_type:
            protocols.append('CustomStringConvertible')

        with self.class_block(data_type, protocols=protocols):
            for field in data_type.fields:
                fdoc = self.process_doc(
                    field.doc, self._docf) if field.doc else undocumented
                self.emit_wrapped_text(fdoc, prefix='/// ', width=120)
                self.emit('open let {}: {}'.format(
                    fmt_var(field.name),
                    fmt_type(field.data_type),
                ))
            self._generate_struct_init(namespace, data_type)

            decl = 'open var' if not data_type.parent_type else 'open override var'

            with self.block('{} description: String'.format(decl)):
                cls = fmt_class(data_type.name) + 'Serializer'
                self.emit(
                    'return "\\(SerializeUtil.prepareJSONForSerialization' +
                    '({}().serialize(self)))"'.format(cls))

        self._generate_struct_class_serializer(namespace, data_type)
示例#4
0
    def _emit_route(self, namespace, route, req_obj_name, extra_args=None, extra_docs=None):
        arg_list, doc_list = self._get_route_args(namespace, route)
        extra_args = extra_args or []
        extra_docs = extra_docs or []

        arg_type = fmt_type(route.arg_data_type)
        func_name = fmt_func(route.name)

        if route.doc:
            route_doc = self.process_doc(route.doc, self._docf)
        else:
            route_doc = 'The {} route'.format(func_name)
        self.emit_wrapped_text(route_doc, prefix='/// ', width=120)
        self.emit('///')

        for name, doc in doc_list + extra_docs:
            param_doc = '- parameter {}: {}'.format(name, doc if doc is not None else undocumented)
            self.emit_wrapped_text(param_doc, prefix='/// ', width=120)
        self.emit('///')
        output = (' - returns: Through the response callback, the caller will ' +
                         'receive a `{}` object on success or a `{}` object on failure.')
        output = output.format(fmt_type(route.result_data_type),
                               fmt_type(route.error_data_type))
        self.emit_wrapped_text(output, prefix='/// ', width=120)

        func_args = [
            ('route', '{}.{}'.format(fmt_class(namespace.name), func_name)),
        ]
        client_args = []
        return_args = [('route', 'route')]

        for name, value, typ in extra_args:
            arg_list.append((name, typ))
            func_args.append((name, value))
            client_args.append((name, value))

        rtype = fmt_serial_type(route.result_data_type)
        etype = fmt_serial_type(route.error_data_type)

        self._maybe_generate_deprecation_warning(route)

        with self.function_block('public func {}'.format(func_name),
                args=self._func_args(arg_list, force_first=True),
                return_type='{}<{}, {}>'.format(req_obj_name, rtype, etype)):
            self.emit('let route = {}.{}'.format(fmt_class(namespace.name), func_name))
            if is_struct_type(route.arg_data_type):
                args = [(name, name) for name, _ in self._struct_init_args(route.arg_data_type)]
                func_args += [('serverArgs', '{}({})'.format(arg_type, self._func_args(args)))]
                self.emit('let serverArgs = {}({})'.format(arg_type, self._func_args(args)))
            elif is_union_type(route.arg_data_type):
                self.emit('let serverArgs = {}'.format(fmt_var(route.arg_data_type.name)))

            if not is_void_type(route.arg_data_type):
                return_args += [('serverArgs', 'serverArgs')]

            return_args += client_args

            self.emit('return client.request({})'.format(self._func_args(return_args, not_init=True)))
        self.emit()
示例#5
0
def fmt_serial_type(data_type):
    data_type, nullable = unwrap_nullable(data_type)

    if is_user_defined_type(data_type):
        result = '{}.{}Serializer'
        result = result.format(fmt_class(data_type.namespace.name),
            fmt_class(data_type.name))
    else:
        result = _serial_type_table.get(data_type.__class__, fmt_class(data_type.name))

        if is_list_type(data_type):
            result = result + '<{}>'.format(fmt_serial_type(data_type.data_type))

    return result if not nullable else 'NullableSerializer'
示例#6
0
def fmt_serial_type(data_type):
    data_type, nullable = unwrap_nullable(data_type)

    if is_user_defined_type(data_type):
        result = '{}.{}Serializer'
        result = result.format(fmt_class(data_type.namespace.name),
                                fmt_class(data_type.name))
    else:
        result = _serial_type_table.get(data_type.__class__, fmt_class(data_type.name))
        
        if is_list_type(data_type):
            result = result + '<{}>'.format(fmt_serial_type(data_type.data_type))        

    return result if not nullable else 'NullableSerializer'
示例#7
0
    def _generate_union_type(self, namespace, data_type):
        self.emit('/**')
        if data_type.doc:
            doc = self.process_doc(data_type.doc, self._docf)
        else:
            doc = 'The {} union'.format(self.class_data_type(data_type))
        self.emit_wrapped_text(doc, prefix='    ', width=120)
        self.emit('*/')

        class_type = self.class_data_type(data_type)
        with self.block('public enum {}: CustomStringConvertible'.format(class_type)):
            all_fields = self._populate_all_fields(data_type)
            for field in all_fields:
                typ = self._format_tag_type(namespace, field.data_type)
                if field.doc:
                    self.emit('/**')
                    self.emit_wrapped_text(self.process_doc(field.doc, self._docf),
                                           prefix='    ', width=120)
                    self.emit('*/')
                self.emit('case {}{}'.format(fmt_class(field.name),
                                                  typ))
            with self.block('public var description : String'):
                cls = class_type+'Serializer'
                self.emit(
                    'return "\(prepareJSONForSerialization({}().serialize(self)))"'.format(cls)
                )

        self._generate_union_serializer(data_type)
示例#8
0
    def _generate_client(self, api):
        self.emit_raw(base)
        self.emit('import Alamofire')
        self.emit()

        with self.block('open class {}'.format(self.args.class_name)):
            namespace_fields = []
            for namespace in api.namespaces.values():
                if namespace.routes:
                    namespace_fields.append(
                        (namespace.name, fmt_class(namespace.name)))
            for var, typ in namespace_fields:
                self.emit('/// Routes within the {} namespace. '
                          'See {}Routes for details.'.format(var, typ))
                self.emit('open var {}: {}Routes!'.format(var, typ))
            self.emit()

            with self.function_block('public init',
                                     args=self._func_args([
                                         ('client', '{}'.format(
                                             self.args.transport_client_name))
                                     ])):
                for var, typ in namespace_fields:
                    self.emit('self.{} = {}Routes(client: client)'.format(
                        var, typ))
示例#9
0
    def _generate_bound_client(self, api, raw_client):

        self.emit_raw(base)
        self.emit('import Alamofire')

        self.emit('/// The client for the API. Call routes using'
                   'the namespaces inside this object.')
        with self.block('public class DropboxClient : StoneClient'):
            self.emit_raw(raw_client.read())
            namespace_fields = []
            for namespace in api.namespaces.values():
                if len(namespace.routes) > 0:
                    namespace_fields.append((namespace.name,
                                              fmt_class(namespace.name)))

            my_props = [('accessToken', 'DropboxAccessToken')]
            super_props = [('manager', 'Manager'), ('backgroundManager', 'Manager'), ('baseHosts', '[String : String]')]

            for var, typ in namespace_fields:
                self.emit('/// Routes within the {} namespace.'
                          'See {}Routes for details.'.format(var, typ))
                self.emit('public var {} : {}Routes!'.format(var, typ))

            with self.function_block('public init', self._func_args(my_props + super_props)):
                for var, typ in my_props:
                    self.emit('self.{} = {}'.format(var, var))
                self.emit('super.init({})'.format(self._func_args((name,name)
                                                                  for name, _ in super_props)))

                for var, typ in namespace_fields:
                    self.emit('self.{} = {}Routes(client: self)'.format(var, typ))
示例#10
0
    def generate(self, api):
        rsrc_folder = os.path.join(os.path.dirname(__file__), 'swift_rsrc')
        self.logger.info('Copying StoneValidators.swift to output folder')
        shutil.copy(os.path.join(rsrc_folder, 'StoneValidators.swift'),
                    self.target_folder_path)
        self.logger.info('Copying StoneSerializers.swift to output folder')
        shutil.copy(os.path.join(rsrc_folder, 'StoneSerializers.swift'),
                    self.target_folder_path)
        self.logger.info('Copying StoneBase.swift to output folder')
        shutil.copy(os.path.join(rsrc_folder, 'StoneBase.swift'),
                    self.target_folder_path)

        jazzy_cfg_path = os.path.join(rsrc_folder, 'jazzy.json')
        with open(jazzy_cfg_path) as jazzy_file:
            jazzy_cfg = json.load(jazzy_file)

        for namespace in api.namespaces.values():
            ns_class = fmt_class(namespace.name)
            with self.output_to_relative_path('{}.swift'.format(ns_class)):
                self._generate_base_namespace_module(api, namespace)
            jazzy_cfg['custom_categories'][1]['children'].append(ns_class)

            if namespace.routes:
                jazzy_cfg['custom_categories'][0]['children'].append(ns_class + 'Routes')

        with self.output_to_relative_path('../.jazzy.json'):
            self.emit_raw(json.dumps(jazzy_cfg, indent=2)+'\n')
示例#11
0
 def serializer_func(self, data_type):
     with self.function_block('open func serialize',
                              args=self._func_args([
                                  ('_ value', fmt_class(data_type.name))
                              ]),
                              return_type='JSON'):
         yield
示例#12
0
    def generate(self, api):
        rsrc_folder = os.path.join(os.path.dirname(__file__), 'swift_rsrc')
        self.logger.info('Copying StoneValidators.swift to output folder')
        shutil.copy(os.path.join(rsrc_folder, 'StoneValidators.swift'),
                    self.target_folder_path)
        self.logger.info('Copying StoneSerializers.swift to output folder')
        shutil.copy(os.path.join(rsrc_folder, 'StoneSerializers.swift'),
                    self.target_folder_path)
        self.logger.info('Copying StoneBase.swift to output folder')
        shutil.copy(os.path.join(rsrc_folder, 'StoneBase.swift'),
                    self.target_folder_path)

        jazzy_cfg_path = os.path.join('../Format', 'jazzy.json')
        with open(jazzy_cfg_path) as jazzy_file:
            jazzy_cfg = json.load(jazzy_file)

        for namespace in api.namespaces.values():
            ns_class = fmt_class(namespace.name)
            with self.output_to_relative_path('{}.swift'.format(ns_class)):
                self._generate_base_namespace_module(api, namespace)
            jazzy_cfg['custom_categories'][1]['children'].append(ns_class)

            if namespace.routes:
                jazzy_cfg['custom_categories'][0]['children'].append(ns_class +
                                                                     'Routes')

        with self.output_to_relative_path('../../../../.jazzy.json'):
            self.emit_raw(json.dumps(jazzy_cfg, indent=2) + '\n')
示例#13
0
    def _generate_union_serializer(self, data_type):
        with self.serializer_block(data_type):
            with self.serializer_func(data_type), self.block('switch value'):
                for field in data_type.all_fields:
                    field_type = field.data_type
                    case = '.{}{}'.format(fmt_class(field.name),
                                         '' if is_void_type(field_type) else '(let arg)')
                    self.emit('case {}:'.format(case))

                    with self.indent():
                        if is_void_type(field_type):
                            self.emit('var d = [String: JSON]()')
                        elif (is_struct_type(field_type) and
                                not field_type.has_enumerated_subtypes()):
                            self.emit('var d = Serialization.getFields({}.serialize(arg))'.format(
                                fmt_serial_obj(field_type)))
                        else:
                            self.emit('var d = ["{}": {}.serialize(arg)]'.format(
                                field.name,
                                fmt_serial_obj(field_type)))
                        self.emit('d[".tag"] = .Str("{}")'.format(field.name))
                        self.emit('return .Dictionary(d)')
            with self.deserializer_func(data_type):
                with self.block("switch json"):
                    self.emit("case .Dictionary(let d):")
                    with self.indent():
                        self.emit('let tag = Serialization.getTag(d)')
                        with self.block('switch tag'):
                            for field in data_type.all_fields:
                                field_type = field.data_type
                                self.emit('case "{}":'.format(field.name))

                                tag_type = self._tag_type(data_type, field)
                                with self.indent():
                                    if is_void_type(field_type):
                                        self.emit('return {}'.format(tag_type))
                                    else:
                                        if (is_struct_type(field_type) and
                                                not field_type.has_enumerated_subtypes()):
                                            subdict = 'json'
                                        else:
                                            subdict = 'd["{}"] ?? .Null'.format(field.name)

                                        self.emit('let v = {}.deserialize({})'.format(
                                            fmt_serial_obj(field_type), subdict
                                        ))
                                        self.emit('return {}(v)'.format(tag_type))
                            self.emit('default:')
                            with self.indent():
                                if data_type.catch_all_field:
                                    self.emit('return {}'.format(
                                        self._tag_type(data_type, data_type.catch_all_field)
                                    ))
                                else:
                                    self.emit('fatalError("Unknown tag \(tag)")')
                    self.emit("default:")
                    with self.indent():

                        self.emit('fatalError("Failed to deserialize")')
示例#14
0
    def generate(self, api):
        for namespace in api.namespaces.values():
            ns_class = fmt_class(namespace.name)
            if namespace.routes:
                with self.output_to_relative_path('{}Routes.swift'.format(ns_class)):
                    self._generate_routes(namespace)

        with self.output_to_relative_path('{}.swift'.format(self.args.module_name)):
            self._generate_client(api)
示例#15
0
    def _get_route_args(self, namespace, route):
        data_type = route.arg_data_type
        arg_type = fmt_type(data_type)
        if is_struct_type(data_type):
            arg_list = self._struct_init_args(data_type, namespace=namespace)

            doc_list = [(fmt_var(f.name), self.process_doc(f.doc, self._docf)
                if f.doc else undocumented) for f in data_type.fields if f.doc]
        elif is_union_type(data_type):
            arg_list = [(fmt_var(data_type.name), '{}.{}'.format(
                fmt_class(namespace.name), fmt_class(data_type.name)))]
            doc_list = [(fmt_var(data_type.name),
                self.process_doc(data_type.doc, self._docf)
                if data_type.doc else 'The {} union'.format(fmt_class(data_type.name)))]
        else:
            arg_list = [] if is_void_type(data_type) else [('request', arg_type)]
            doc_list = []
        return arg_list, doc_list
示例#16
0
def fmt_serial_obj(data_type):
    data_type, nullable = unwrap_nullable(data_type)

    if is_user_defined_type(data_type):
        result = '{}.{}Serializer()'
        result = result.format(fmt_class(data_type.namespace.name),
                                fmt_class(data_type.name))
    else:
        result = _serial_type_table.get(data_type.__class__, fmt_class(data_type.name))

        if is_list_type(data_type):
            result = result + '({})'.format(fmt_serial_obj(data_type.data_type))
        elif is_timestamp_type(data_type):
            result = result + '("{}")'.format(data_type.format)
        else:
            result = 'Serialization._{}'.format(result)

    return result if not nullable else 'NullableSerializer({})'.format(result)
示例#17
0
def fmt_serial_obj(data_type):
    data_type, nullable = unwrap_nullable(data_type)

    if is_user_defined_type(data_type):
        result = '{}.{}Serializer()'
        result = result.format(fmt_class(data_type.namespace.name),
            fmt_class(data_type.name))
    else:
        result = _serial_type_table.get(data_type.__class__, fmt_class(data_type.name))

        if is_list_type(data_type):
            result = result + '({})'.format(fmt_serial_obj(data_type.data_type))
        elif is_timestamp_type(data_type):
            result = result + '("{}")'.format(data_type.format)
        else:
            result = 'Serialization._{}'.format(result)

    return result if not nullable else 'NullableSerializer({})'.format(result)
示例#18
0
    def generate(self, api):
        rsrc_folder = os.path.join(os.path.dirname(__file__), 'swift_rsrc')
        for namespace in api.namespaces.values():
            ns_class = fmt_class(namespace.name)
            if namespace.routes:
                with self.output_to_relative_path('{}Routes.swift'.format(ns_class)):
                    self._generate_routes(namespace)

        with self.output_to_relative_path('{}.swift'.format(self.args.module_name)):
            self._generate_client(api)
示例#19
0
    def generate(self, api):
        for namespace in api.namespaces.values():
            ns_class = fmt_class(namespace.name)
            if namespace.routes:
                with self.output_to_relative_path(
                        '{}Routes.swift'.format(ns_class)):
                    self._generate_routes(namespace)

        with self.output_to_relative_path('{}.swift'.format(
                self.args.module_name)):
            self._generate_client(api)
示例#20
0
    def _generate_routes(self, namespace):
        ns_class = fmt_class(namespace.name)
        self.emit('/// Routes for the {} namespace'.format(namespace.name))
        with self.block('public class {}Routes'.format(ns_class)):
            self.emit('public let client : StoneClient')
            args = [('client', 'StoneClient')]
            with self.function_block('init', self._func_args(args)):
                self.emit('self.client = client')

            for route in namespace.routes:
                self._generate_route(namespace, route)
示例#21
0
    def _generate_base_namespace_module(self, namespace):
        self.emit_raw(base)

        self.emit('/**')
        self.emit('    Datatypes and serializers for the {} namespace'.format(namespace.name))
        self.emit('*/')
        with self.block('public class {}'.format(fmt_class(namespace.name))):
            for data_type in namespace.linearize_data_types():
                if is_struct_type(data_type):
                    self._generate_struct_class(namespace, data_type)
                elif is_union_type(data_type):
                    self._generate_union_type(namespace, data_type)
示例#22
0
    def generate(self, api):
        rsrc_folder = os.path.join(os.path.dirname(__file__), 'swift_rsrc')
        for namespace in api.namespaces.values():
            ns_class = fmt_class(namespace.name)
            if namespace.routes:
                with self.output_to_relative_path(
                        '{}Routes.swift'.format(ns_class)):
                    self._generate_routes(namespace)

        with self.output_to_relative_path('{}.swift'.format(
                self.args.module_name)):
            self._generate_client(api)
示例#23
0
    def _generate_struct_base_class_deserializer(self, namespace, data_type):
        args = []
        for field in data_type.all_fields:
            var = fmt_var(field.name)
            value = 'dict["{}"]'.format(field.name)
            self.emit('let {} = {}.deserialize({} ?? {})'.format(
                var, fmt_serial_obj(field.data_type), value,
                fmt_default_value(namespace, field)
                if field.has_default else '.null'))

            args.append((var, var))
        self.emit('return {}({})'.format(fmt_class(data_type.name),
                                         self._func_args(args)))
示例#24
0
    def _generate_struct_base_class_deserializer(self, namespace, data_type):
        args = []
        for field in data_type.all_fields:
            var = fmt_var(field.name)
            self.emit('let {} = {}.deserialize(dict["{}"] ?? .Null)'.format(
                var,
                fmt_serial_obj(field.data_type),
                field.name,
            ))

            args.append((var, var))
        self.emit('return {}({})'.format(fmt_class(data_type.name),
                                         self._func_args(args)))
示例#25
0
    def _get_route_args(self, namespace, route):
        data_type = route.arg_data_type
        arg_type = fmt_type(data_type)
        if is_struct_type(data_type):
            arg_list = self._struct_init_args(data_type, namespace=namespace)

            doc_list = [(fmt_var(f.name), self.process_doc(f.doc, self._docf)
                         if f.doc else undocumented) for f in data_type.fields
                        if f.doc]
        elif is_union_type(data_type):
            arg_list = [(fmt_var(data_type.name),
                         '{}.{}'.format(fmt_class(namespace.name),
                                        fmt_class(data_type.name)))]
            doc_list = [
                (fmt_var(data_type.name),
                 self.process_doc(data_type.doc, self._docf) if data_type.doc
                 else 'The {} union'.format(fmt_class(data_type.name)))
            ]
        else:
            arg_list = [] if is_void_type(data_type) else [('request',
                                                            arg_type)]
            doc_list = []
        return arg_list, doc_list
示例#26
0
    def _generate_union_type(self, namespace, data_type):
        if data_type.doc:
            doc = self.process_doc(data_type.doc, self._docf)
        else:
            doc = 'The {} union'.format(fmt_class(data_type.name))
        self.emit_wrapped_text(doc, prefix='/// ', width=120)

        class_type = fmt_class(data_type.name)
        with self.block('public enum {}: CustomStringConvertible'.format(class_type)):
            for field in data_type.all_fields:
                typ = self._format_tag_type(namespace, field.data_type)

                fdoc = self.process_doc(field.doc,
                    self._docf) if field.doc else 'An unspecified error.'
                self.emit_wrapped_text(fdoc, prefix='/// ', width=120)
                self.emit('case {}{}'.format(fmt_var(field.name), typ))
            self.emit()
            with self.block('public var description: String'):
                cls = class_type + 'Serializer'
                self.emit('return "\\(SerializeUtil.prepareJSONForSerialization' +
                          '({}().serialize(self)))"'.format(cls))

        self._generate_union_serializer(data_type)
示例#27
0
    def _generate_struct_base_class_deserializer(self, namespace, data_type):
            args = []
            for field in data_type.all_fields:
                var = fmt_var(field.name)
                self.emit('let {} = {}.deserialize(dict["{}"] ?? .Null)'.format(
                    var,
                    fmt_serial_obj(field.data_type),
                    field.name,
                ))

                args.append((var, var))
            self.emit('return {}({})'.format(
                fmt_class(data_type.name),
                self._func_args(args)
            ))
示例#28
0
 def _docf(self, tag, val):
     if tag == 'route':
         return fmt_func(val)
     elif tag == 'field':
         if '.' in val:
             cls, field = val.split('.')
             return ('{} in {}'.format(fmt_var(field), fmt_class(cls)))
         else:
             return fmt_var(val)
     elif tag in ('type', 'val', 'link'):
         return val
     else:
         import pdb
         pdb.set_trace()
         return val
示例#29
0
    def class_block(self, thing, protocols=None):
        protocols = protocols or []
        extensions = []

        if isinstance(thing, DataType):
            name = fmt_class(thing.name)
            if thing.parent_type:
                extensions.append(fmt_type(thing.parent_type))
        else:
            name = thing
        extensions.extend(protocols)

        extend_suffix = ': {}'.format(', '.join(extensions)) if extensions else ''

        with self.block('open class {}{}'.format(name, extend_suffix)):
            yield
示例#30
0
    def _generate_routes(self, namespace):
        ns_class = fmt_class(namespace.name)
        self.emit_raw(stone_warning)
        self.emit('/// Routes for the {} namespace'.format(namespace.name))

        with self.block('open class {}Routes'.format(ns_class)):
            self.emit('open let client: {}'.format(self.args.transport_client_name))
            args = [('client', '{}'.format(self.args.transport_client_name))]

            with self.function_block('init', self._func_args(args)):
                self.emit('self.client = client')

            self.emit()

            for route in namespace.routes:
                self._generate_route(namespace, route)
示例#31
0
    def _generate_base_namespace_module(self, api, namespace):
        self.emit_raw(base)

        routes_base = 'Datatypes and serializers for the {} namespace'.format(namespace.name)
        self.emit_wrapped_text(routes_base, prefix='/// ', width=120)

        with self.block('public class {}'.format(fmt_class(namespace.name))):
            for data_type in namespace.linearize_data_types():
                if is_struct_type(data_type):
                    self._generate_struct_class(namespace, data_type)
                    self.emit()
                elif is_union_type(data_type):
                    self._generate_union_type(namespace, data_type)
                    self.emit()
            if namespace.routes:
                self._generate_route_objects(api.route_schema, namespace)
示例#32
0
    def class_block(self, thing, protocols=None):
        protocols = protocols or []
        extensions = []

        if isinstance(thing, DataType):
            name = fmt_class(thing.name)
            if thing.parent_type:
                extensions.append(fmt_type(thing.parent_type))
        else:
            name = thing
        extensions.extend(protocols)

        extend_suffix = ': {}'.format(', '.join(extensions)) if extensions else ''

        with self.block('public class {}{}'.format(name, extend_suffix)):
            yield
示例#33
0
    def _generate_base_namespace_module(self, api, namespace):
        self.emit_raw(base)

        routes_base = 'Datatypes and serializers for the {} namespace'.format(namespace.name)
        self.emit_wrapped_text(routes_base, prefix='/// ', width=120)

        with self.block('open class {}'.format(fmt_class(namespace.name))):
            for data_type in namespace.linearize_data_types():
                if is_struct_type(data_type):
                    self._generate_struct_class(namespace, data_type)
                    self.emit()
                elif is_union_type(data_type):
                    self._generate_union_type(namespace, data_type)
                    self.emit()
            if namespace.routes:
                self._generate_route_objects(api.route_schema, namespace)
示例#34
0
 def _docf(self, tag, val):
     if tag == 'route':
         return fmt_func(val)
     elif tag == 'field':
         if '.' in val:
             cls, field = val.split('.')
             return ('{} in {}'.format(fmt_var(field),
                     fmt_class(cls)))
         else:
             return fmt_var(val)
     elif tag in ('type', 'val', 'link'):
         return val
     else:
         import pdb
         pdb.set_trace()
         return val
示例#35
0
    def _generate_routes(self, namespace):
        ns_class = fmt_class(namespace.name)
        self.emit_raw(stone_warning)
        self.emit('/// Routes for the {} namespace'.format(namespace.name))

        with self.block('open class {}Routes'.format(ns_class)):
            self.emit('open let client: {}'.format(
                self.args.transport_client_name))
            args = [('client', '{}'.format(self.args.transport_client_name))]

            with self.function_block('init', self._func_args(args)):
                self.emit('self.client = client')

            self.emit()

            for route in namespace.routes:
                self._generate_route(namespace, route)
示例#36
0
    def _swift_type_mapping(self, data_type, serializer=False):
        suffix = 'Serializer' if serializer else ''
        if is_nullable_type(data_type):
            data_type = data_type.data_type
            nullable = True
        else:
            nullable = False
        if is_list_type(data_type):
            ret = 'Array{}<{}>'.format(
                suffix,
                self._swift_type_mapping(data_type.data_type, serializer)
            )
            suffix = ''
        elif is_string_type(data_type):
            ret = 'String'
        elif is_timestamp_type(data_type):
            ret = 'NSDate'
        elif is_boolean_type(data_type):
            ret = 'Bool'
        elif is_bytes_type(data_type):
            ret = 'NSData'
        elif is_void_type(data_type):
            ret = 'Void'
        elif isinstance(data_type, Int32):
            ret = 'Int32'
        elif isinstance(data_type, Int64):
            ret = 'Int64'
        elif isinstance(data_type, UInt32):
            ret = 'UInt32'
        elif isinstance(data_type, UInt64):
            ret = 'UInt64'
        elif isinstance(data_type, Float32):
            ret = 'Float'
        elif isinstance(data_type, Float64):
            ret = 'Double'
        elif is_user_defined_type(data_type):
            ret = '{}.{}'.format(fmt_class(data_type.namespace.name),
                                 self.class_data_type(data_type))
        ret += suffix
        if nullable:
            if serializer:
                ret = 'NullableSerializer<{}>'.format(ret)
            else:
                ret += '?'

        return ret
示例#37
0
    def _generate_struct_base_class_deserializer(self, namespace, data_type):
        args = []
        for field in data_type.all_fields:
            var = fmt_var(field.name)
            value = 'dict["{}"]'.format(field.name)
            self.emit('let {} = {}.deserialize({} ?? {})'.format(
                var,
                fmt_serial_obj(field.data_type),
                value,
                fmt_default_value(namespace, field) if field.has_default else '.null'
            ))

            args.append((var, var))
        self.emit('return {}({})'.format(
            fmt_class(data_type.name),
            self._func_args(args)
        ))
示例#38
0
文件: swift.py 项目: strogo/stone
    def _struct_init_args(self, data_type, namespace=None):
        args = []
        for field in data_type.all_fields:
            name = fmt_var(field.name)
            value = fmt_type(field.data_type)
            data_type, nullable = unwrap_nullable(field.data_type)

            if field.has_default:
                if is_union_type(data_type):
                    default = '.{}'.format(fmt_class(field.default.tag_name))
                else:
                    default = fmt_obj(field.default)
                value += ' = {}'.format(default)
            elif nullable:
                value += ' = nil'
            arg = (name, value)
            args.append(arg)
        return args
示例#39
0
    def _struct_init_args(self, data_type, namespace=None):
        args = []
        for field in data_type.all_fields:
            name = fmt_var(field.name)
            value = fmt_type(field.data_type)
            data_type, nullable = unwrap_nullable(field.data_type)

            if field.has_default:
                if is_union_type(data_type):
                    default = '.{}'.format(fmt_class(field.default.tag_name))
                else:
                    default = fmt_obj(field.default)
                value += ' = {}'.format(default)
            elif nullable:
                value += ' = nil'
            arg = (name, value)
            args.append(arg)
        return args
示例#40
0
    def _generate_client(self, api):
        self.emit_raw(base)
        self.emit('import Alamofire')
        self.emit()

        with self.block('open class {}'.format(self.args.class_name)):
            namespace_fields = []
            for namespace in api.namespaces.values():
                if namespace.routes:
                    namespace_fields.append((namespace.name,
                                            fmt_class(namespace.name)))
            for var, typ in namespace_fields:
                self.emit('/// Routes within the {} namespace. '
                          'See {}Routes for details.'.format(var, typ))
                self.emit('open var {}: {}Routes!'.format(var, typ))
            self.emit()

            with self.function_block('public init', args=self._func_args(
                    [('client', '{}'.format(self.args.transport_client_name))])):
                for var, typ in namespace_fields:
                    self.emit('self.{} = {}Routes(client: client)'.format(var, typ))
示例#41
0
    def generate(self, api):
        rsrc_folder = os.path.join(os.path.dirname(__file__), 'swift_rsrc')
        self.logger.info('Copying StoneSerializers.swift to output folder')
        shutil.copy(os.path.join(rsrc_folder, 'StoneSerializers.swift'),
                    os.path.join(self.target_folder_path, 'Source'))

        self.logger.info('Copying StoneValidators.swift to output folder')
        shutil.copy(os.path.join(rsrc_folder, 'StoneValidators.swift'),
                    os.path.join(self.target_folder_path, 'Source'))

        self.logger.info('Copying Client.swift to output folder')
        shutil.copy(os.path.join(rsrc_folder, 'Client.swift'),
                    os.path.join(self.target_folder_path, 'Source'))

        jazzy_cfg_path = os.path.join(rsrc_folder, 'jazzy.json')
        with open(jazzy_cfg_path) as jazzy_file:
            jazzy_cfg = json.load(jazzy_file)

        for namespace in api.namespaces.values():

            ns_class = fmt_class(namespace.name)
            path = os.path.join('Source', '{}.swift'.format(ns_class))
            with self.output_to_relative_path(path):
                self._generate_base_namespace_module(namespace)
            jazzy_cfg['custom_categories'][1]['children'].append(ns_class)

            if len(namespace.routes) > 0:
                path = os.path.join('Source', '{}Routes.swift'.format(ns_class))
                with self.output_to_relative_path(path):
                    self._generate_routes(namespace)
                jazzy_cfg['custom_categories'][0]['children'].append(ns_class + 'Routes')

        with self.output_to_relative_path('.jazzy.json'):
            self.emit_raw(json.dumps(jazzy_cfg, indent=2)+'\n')

        client_path = os.path.join('Source', 'DropboxClient.swift')
        dropbox_raw_path = os.path.join(rsrc_folder, 'DropboxClient-raw.swift')

        with open(dropbox_raw_path) as raw_client, self.output_to_relative_path(client_path):
            self._generate_bound_client(api, raw_client)
示例#42
0
    def _serializer_obj(self, data_type):
        if is_nullable_type(data_type):
            data_type = data_type.data_type
            nullable = True
        else:
            nullable = False
        if is_list_type(data_type):
            ret = 'ArraySerializer({})'.format(
                self._serializer_obj(data_type.data_type))
        elif is_string_type(data_type):
            ret = 'Serialization._StringSerializer'
        elif is_timestamp_type(data_type):
            ret = 'NSDateSerializer("{}")'.format(data_type.format)
        elif is_boolean_type(data_type):
            ret = 'Serialization._BoolSerializer'
        elif is_bytes_type(data_type):
            ret = 'Serialization._NSDataSerializer'
        elif is_void_type(data_type):
            ret = 'Serialization._VoidSerializer'
        elif isinstance(data_type, Int32):
            ret = 'Serialization._Int32Serializer'
        elif isinstance(data_type, Int64):
            ret = 'Serialization._Int64Serializer'
        elif isinstance(data_type, UInt32):
            ret = 'Serialization._UInt32Serializer'
        elif isinstance(data_type, UInt64):
            ret = 'Serialization._UInt64Serializer'
        elif isinstance(data_type, Float32):
            ret = 'Serialization._FloatSerializer'
        elif isinstance(data_type, Float64):
            ret = 'Serialization._DoubleSerializer'
        elif is_user_defined_type(data_type):
            ret = "{}.{}Serializer()".format(fmt_class(data_type.namespace.name),
                                             self.class_data_type(data_type))

        if nullable:
            ret = 'NullableSerializer({})'.format(ret)

        return ret
示例#43
0
    def _struct_init_args(self, data_type, namespace=None):
        args = []
        for field in data_type.all_fields:
            name = fmt_var(field.name)
            value = self._swift_type_mapping(field.data_type)
            field_type = field.data_type
            if is_nullable_type(field_type):
                field_type = field_type.data_type
                nullable = True
            else:
                nullable = False

            if field.has_default:
                if is_union_type(field_type):
                    default = '.{}'.format(fmt_class(field.default.tag_name))
                else:
                    default = fmt_obj(field.default)
                value += ' = {}'.format(default)
            elif nullable:
                value += ' = nil'
            arg = (name, value)
            args.append(arg)
        return args
示例#44
0
 def deserializer_func(self, data_type):
     with self.function_block('public func deserialize',
                              args=self._func_args([('json', 'JSON')]),
                              return_type=fmt_class(data_type.name)):
         yield
示例#45
0
 def serializer_func(self, data_type):
     with self.function_block('public func serialize',
                              args=self._func_args([('value', fmt_class(data_type.name))]),
                              return_type='JSON'):
         yield
示例#46
0
 def serializer_block(self, data_type):
     with self.class_block(fmt_class(data_type.name)+'Serializer',
                           protocols=['JSONSerializer']):
         self.emit("public init() { }")
         yield
示例#47
0
 def _tag_type(self, data_type, field):
     return "{}.{}".format(
         fmt_class(data_type.name),
         fmt_class(field.name)
     )
示例#48
0
 def _tag_type(self, data_type, field):
     return "{}.{}".format(fmt_class(data_type.name), fmt_var(field.name))
示例#49
0
 def serializer_block(self, data_type):
     with self.class_block(fmt_class(data_type.name) + 'Serializer',
                           protocols=['JSONSerializer']):
         self.emit("public init() { }")
         yield
示例#50
0
    def _generate_union_serializer(self, data_type):
        with self.serializer_block(data_type):
            with self.serializer_func(data_type), self.block('switch value'):
                for field in data_type.all_fields:
                    field_type = field.data_type
                    case = '.{}{}'.format(
                        fmt_class(field.name),
                        '' if is_void_type(field_type) else '(let arg)')
                    self.emit('case {}:'.format(case))

                    with self.indent():
                        if is_void_type(field_type):
                            self.emit('var d = [String: JSON]()')
                        elif (is_struct_type(field_type)
                              and not field_type.has_enumerated_subtypes()):
                            self.emit(
                                'var d = Serialization.getFields({}.serialize(arg))'
                                .format(fmt_serial_obj(field_type)))
                        else:
                            self.emit(
                                'var d = ["{}": {}.serialize(arg)]'.format(
                                    field.name, fmt_serial_obj(field_type)))
                        self.emit('d[".tag"] = .Str("{}")'.format(field.name))
                        self.emit('return .Dictionary(d)')
            with self.deserializer_func(data_type):
                with self.block("switch json"):
                    self.emit("case .Dictionary(let d):")
                    with self.indent():
                        self.emit('let tag = Serialization.getTag(d)')
                        with self.block('switch tag'):
                            for field in data_type.all_fields:
                                field_type = field.data_type
                                self.emit('case "{}":'.format(field.name))

                                tag_type = self._tag_type(data_type, field)
                                with self.indent():
                                    if is_void_type(field_type):
                                        self.emit('return {}'.format(tag_type))
                                    else:
                                        if (is_struct_type(field_type)
                                                and not field_type.
                                                has_enumerated_subtypes()):
                                            subdict = 'json'
                                        else:
                                            subdict = 'd["{}"] ?? .Null'.format(
                                                field.name)

                                        self.emit(
                                            'let v = {}.deserialize({})'.
                                            format(fmt_serial_obj(field_type),
                                                   subdict))
                                        self.emit(
                                            'return {}(v)'.format(tag_type))
                            self.emit('default:')
                            with self.indent():
                                if data_type.catch_all_field:
                                    self.emit('return {}'.format(
                                        self._tag_type(
                                            data_type,
                                            data_type.catch_all_field)))
                                else:
                                    self.emit(
                                        'fatalError("Unknown tag \(tag)")')
                    self.emit("default:")
                    with self.indent():

                        self.emit('fatalError("Failed to deserialize")')
示例#51
0
 def deserializer_func(self, data_type):
     with self.function_block('open func deserialize',
                              args=self._func_args([('_ json', 'JSON')]),
                              return_type=fmt_class(data_type.name)):
         yield
示例#52
0
    def _emit_route(self,
                    namespace,
                    route,
                    req_obj_name,
                    extra_args=None,
                    extra_docs=None):
        arg_list, doc_list = self._get_route_args(namespace, route)
        extra_args = extra_args or []
        extra_docs = extra_docs or []

        arg_type = fmt_type(route.arg_data_type)
        func_name = fmt_func(route.name)

        if route.doc:
            route_doc = self.process_doc(route.doc, self._docf)
        else:
            route_doc = 'The {} route'.format(func_name)
        self.emit_wrapped_text(route_doc, prefix='/// ', width=120)
        self.emit('///')

        for name, doc in doc_list + extra_docs:
            param_doc = '- parameter {}: {}'.format(
                name, doc if doc is not None else undocumented)
            self.emit_wrapped_text(param_doc, prefix='/// ', width=120)
        self.emit('///')
        output = (
            ' - returns: Through the response callback, the caller will ' +
            'receive a `{}` object on success or a `{}` object on failure.')
        output = output.format(fmt_type(route.result_data_type),
                               fmt_type(route.error_data_type))
        self.emit_wrapped_text(output, prefix='/// ', width=120)

        func_args = [
            ('route', '{}.{}'.format(fmt_class(namespace.name), func_name)),
        ]
        client_args = []
        return_args = [('route', 'route')]

        for name, value, typ in extra_args:
            arg_list.append((name, typ))
            func_args.append((name, value))
            client_args.append((name, value))

        rtype = fmt_serial_type(route.result_data_type)
        etype = fmt_serial_type(route.error_data_type)

        self._maybe_generate_deprecation_warning(route)

        with self.function_block(
                '@discardableResult open func {}'.format(func_name),
                args=self._func_args(arg_list, force_first=False),
                return_type='{}<{}, {}>'.format(req_obj_name, rtype, etype)):
            self.emit('let route = {}.{}'.format(fmt_class(namespace.name),
                                                 func_name))
            if is_struct_type(route.arg_data_type):
                args = [
                    (name, name)
                    for name, _ in self._struct_init_args(route.arg_data_type)
                ]
                func_args += [
                    ('serverArgs', '{}({})'.format(arg_type,
                                                   self._func_args(args)))
                ]
                self.emit('let serverArgs = {}({})'.format(
                    arg_type, self._func_args(args)))
            elif is_union_type(route.arg_data_type):
                self.emit('let serverArgs = {}'.format(
                    fmt_var(route.arg_data_type.name)))

            if not is_void_type(route.arg_data_type):
                return_args += [('serverArgs', 'serverArgs')]

            return_args += client_args

            self.emit('return client.request({})'.format(
                self._func_args(return_args, not_init=True)))
        self.emit()