/* valacallabletype.c generated by valac, the Vala compiler
 * generated from valacallabletype.vala, do not modify */

/* valacallabletype.vala
 *
 * Copyright (C) 2017  Rico Tzschichholz
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 *
 * Author:
 * 	Rico Tzschichholz <ricotz@ubuntu.com>
 */

#include "vala.h"
#include <glib.h>
#include <valagee.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>

#define _g_free0(var) (var = (g_free (var), NULL))
#define _vala_code_node_unref0(var) ((var == NULL) ? NULL : (var = (vala_code_node_unref (var), NULL)))
#define _vala_iterable_unref0(var) ((var == NULL) ? NULL : (var = (vala_iterable_unref (var), NULL)))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))

static gpointer vala_callable_type_parent_class = NULL;

static gboolean vala_callable_type_real_is_invokable (ValaDataType* base);
static ValaDataType* vala_callable_type_real_get_return_type (ValaDataType* base);
static ValaList* vala_callable_type_real_get_parameters (ValaDataType* base);
static gchar* vala_callable_type_real_to_prototype_string (ValaDataType* base,
                                                    const gchar* override_name);
static GType vala_callable_type_get_type_once (void);

ValaCallable*
vala_callable_type_get_callable_symbol (ValaCallableType* self)
{
	ValaCallable* result;
	ValaSymbol* _tmp0_;
	ValaSymbol* _tmp1_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = vala_data_type_get_symbol ((ValaDataType*) self);
	_tmp1_ = _tmp0_;
	result = G_TYPE_CHECK_INSTANCE_CAST (_tmp1_, VALA_TYPE_CALLABLE, ValaCallable);
	return result;
}

ValaCallableType*
vala_callable_type_construct (GType object_type,
                              ValaSymbol* symbol,
                              ValaSourceReference* source_reference)
{
	ValaCallableType* self = NULL;
	g_return_val_if_fail (symbol != NULL, NULL);
	self = (ValaCallableType*) vala_data_type_construct_with_symbol (object_type, symbol, source_reference);
	return self;
}

static gboolean
vala_callable_type_real_is_invokable (ValaDataType* base)
{
	ValaCallableType * self;
	gboolean result;
	self = (ValaCallableType*) base;
	result = TRUE;
	return result;
}

static ValaDataType*
vala_callable_type_real_get_return_type (ValaDataType* base)
{
	ValaCallableType * self;
	ValaCallable* _tmp0_;
	ValaCallable* _tmp1_;
	ValaDataType* _tmp2_;
	ValaDataType* _tmp3_;
	ValaDataType* result;
	self = (ValaCallableType*) base;
	_tmp0_ = vala_callable_type_get_callable_symbol (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = vala_callable_get_return_type (_tmp1_);
	_tmp3_ = _tmp2_;
	result = _tmp3_;
	return result;
}

static ValaList*
vala_callable_type_real_get_parameters (ValaDataType* base)
{
	ValaCallableType * self;
	ValaCallable* _tmp0_;
	ValaCallable* _tmp1_;
	ValaList* _tmp2_;
	ValaList* result;
	self = (ValaCallableType*) base;
	_tmp0_ = vala_callable_type_get_callable_symbol (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = vala_callable_get_parameters (_tmp1_);
	result = _tmp2_;
	return result;
}

static gchar*
vala_callable_type_real_to_prototype_string (ValaDataType* base,
                                             const gchar* override_name)
{
	ValaCallableType * self;
	GString* builder = NULL;
	GString* _tmp0_;
	ValaDelegateType* delegate_type = NULL;
	ValaMethodType* method_type = NULL;
	ValaSignalType* signal_type = NULL;
	gboolean _tmp1_ = FALSE;
	ValaMethodType* _tmp2_;
	gboolean _tmp13_ = FALSE;
	ValaMethodType* _tmp14_;
	GString* _tmp22_;
	gchar* _tmp23_ = NULL;
	gchar* _tmp24_;
	GString* _tmp26_;
	GString* _tmp27_;
	GString* _tmp28_;
	gint i = 0;
	ValaDelegateType* _tmp29_;
	GString* _tmp108_;
	ValaArrayList* error_types = NULL;
	GEqualFunc _tmp109_;
	ValaArrayList* _tmp110_;
	ValaCallable* _tmp111_;
	ValaCallable* _tmp112_;
	ValaArrayList* _tmp113_;
	ValaArrayList* _tmp114_;
	gint _tmp115_;
	gint _tmp116_;
	GString* _tmp131_;
	const gchar* _tmp132_;
	gchar* _tmp133_;
	gchar* result;
	self = (ValaCallableType*) base;
	_tmp0_ = g_string_new ("");
	builder = _tmp0_;
	delegate_type = VALA_IS_DELEGATE_TYPE (self) ? ((ValaDelegateType*) self) : NULL;
	method_type = VALA_IS_METHOD_TYPE (self) ? ((ValaMethodType*) self) : NULL;
	signal_type = VALA_IS_SIGNAL_TYPE (self) ? ((ValaSignalType*) self) : NULL;
	_tmp2_ = method_type;
	if (_tmp2_ != NULL) {
		ValaMethodType* _tmp3_;
		ValaMethod* _tmp4_;
		ValaMethod* _tmp5_;
		gboolean _tmp6_;
		gboolean _tmp7_;
		_tmp3_ = method_type;
		_tmp4_ = vala_method_type_get_method_symbol (_tmp3_);
		_tmp5_ = _tmp4_;
		_tmp6_ = vala_method_get_coroutine (_tmp5_);
		_tmp7_ = _tmp6_;
		_tmp1_ = _tmp7_;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GString* _tmp8_;
		_tmp8_ = builder;
		g_string_append (_tmp8_, "async ");
	} else {
		ValaDelegateType* _tmp9_;
		_tmp9_ = delegate_type;
		if (_tmp9_ != NULL) {
			GString* _tmp10_;
			_tmp10_ = builder;
			g_string_append (_tmp10_, "delegate ");
		} else {
			ValaSignalType* _tmp11_;
			_tmp11_ = signal_type;
			if (_tmp11_ != NULL) {
				GString* _tmp12_;
				_tmp12_ = builder;
				g_string_append (_tmp12_, "signal ");
			}
		}
	}
	_tmp14_ = method_type;
	if (_tmp14_ == NULL) {
		_tmp13_ = TRUE;
	} else {
		ValaMethodType* _tmp15_;
		ValaMethod* _tmp16_;
		ValaMethod* _tmp17_;
		_tmp15_ = method_type;
		_tmp16_ = vala_method_type_get_method_symbol (_tmp15_);
		_tmp17_ = _tmp16_;
		_tmp13_ = !VALA_IS_CREATION_METHOD (_tmp17_);
	}
	if (_tmp13_) {
		GString* _tmp18_;
		ValaDataType* _tmp19_;
		gchar* _tmp20_;
		gchar* _tmp21_;
		_tmp18_ = builder;
		_tmp19_ = vala_data_type_get_return_type ((ValaDataType*) self);
		_tmp20_ = vala_data_type_to_prototype_string (_tmp19_, NULL);
		_tmp21_ = _tmp20_;
		g_string_append (_tmp18_, _tmp21_);
		_g_free0 (_tmp21_);
	}
	_tmp22_ = builder;
	g_string_append_c (_tmp22_, ' ');
	_tmp24_ = g_strdup (override_name);
	_tmp23_ = _tmp24_;
	if (_tmp23_ == NULL) {
		gchar* _tmp25_;
		_tmp25_ = vala_code_node_to_string ((ValaCodeNode*) self);
		_g_free0 (_tmp23_);
		_tmp23_ = _tmp25_;
	}
	_tmp26_ = builder;
	g_string_append (_tmp26_, _tmp23_);
	_tmp27_ = builder;
	g_string_append_c (_tmp27_, ' ');
	_tmp28_ = builder;
	g_string_append_c (_tmp28_, '(');
	i = 1;
	_tmp29_ = delegate_type;
	if (_tmp29_ != NULL) {
		ValaDelegate* delegate_symbol = NULL;
		ValaDelegateType* _tmp30_;
		ValaDelegate* _tmp31_;
		ValaDelegate* _tmp32_;
		gboolean _tmp33_ = FALSE;
		ValaDelegate* _tmp34_;
		ValaSymbol* _tmp35_;
		ValaSymbol* _tmp36_;
		_tmp30_ = delegate_type;
		_tmp31_ = vala_delegate_type_get_delegate_symbol (_tmp30_);
		_tmp32_ = _tmp31_;
		delegate_symbol = _tmp32_;
		_tmp34_ = delegate_symbol;
		_tmp35_ = vala_symbol_get_parent_symbol ((ValaSymbol*) _tmp34_);
		_tmp36_ = _tmp35_;
		if (VALA_IS_SIGNAL (_tmp36_)) {
			ValaDelegate* _tmp37_;
			ValaDataType* _tmp38_;
			ValaDataType* _tmp39_;
			_tmp37_ = delegate_symbol;
			_tmp38_ = vala_delegate_get_sender_type (_tmp37_);
			_tmp39_ = _tmp38_;
			_tmp33_ = _tmp39_ != NULL;
		} else {
			_tmp33_ = FALSE;
		}
		if (_tmp33_) {
			GString* _tmp40_;
			ValaDelegate* _tmp41_;
			ValaDataType* _tmp42_;
			ValaDataType* _tmp43_;
			gchar* _tmp44_;
			gchar* _tmp45_;
			gint _tmp46_;
			_tmp40_ = builder;
			_tmp41_ = delegate_symbol;
			_tmp42_ = vala_delegate_get_sender_type (_tmp41_);
			_tmp43_ = _tmp42_;
			_tmp44_ = vala_data_type_to_qualified_string (_tmp43_, NULL);
			_tmp45_ = _tmp44_;
			g_string_append (_tmp40_, _tmp45_);
			_g_free0 (_tmp45_);
			_tmp46_ = i;
			i = _tmp46_ + 1;
		}
	}
	{
		ValaList* _param_list = NULL;
		ValaList* _tmp47_;
		gint _param_size = 0;
		ValaList* _tmp48_;
		gint _tmp49_;
		gint _tmp50_;
		gint _param_index = 0;
		_tmp47_ = vala_data_type_get_parameters ((ValaDataType*) self);
		_param_list = _tmp47_;
		_tmp48_ = _param_list;
		_tmp49_ = vala_collection_get_size ((ValaCollection*) _tmp48_);
		_tmp50_ = _tmp49_;
		_param_size = _tmp50_;
		_param_index = -1;
		while (TRUE) {
			gint _tmp51_;
			gint _tmp52_;
			ValaParameter* param = NULL;
			ValaList* _tmp53_;
			gpointer _tmp54_;
			ValaParameter* _tmp56_;
			gboolean _tmp57_;
			gboolean _tmp58_;
			ValaParameter* _tmp60_;
			gboolean _tmp61_;
			gboolean _tmp62_;
			ValaParameter* _tmp64_;
			ValaParameterDirection _tmp65_;
			ValaParameterDirection _tmp66_;
			GString* _tmp91_;
			ValaParameter* _tmp92_;
			ValaDataType* _tmp93_;
			ValaDataType* _tmp94_;
			gchar* _tmp95_;
			gchar* _tmp96_;
			ValaParameter* _tmp97_;
			ValaExpression* _tmp98_;
			ValaExpression* _tmp99_;
			gint _tmp107_;
			_param_index = _param_index + 1;
			_tmp51_ = _param_index;
			_tmp52_ = _param_size;
			if (!(_tmp51_ < _tmp52_)) {
				break;
			}
			_tmp53_ = _param_list;
			_tmp54_ = vala_list_get (_tmp53_, _param_index);
			param = (ValaParameter*) _tmp54_;
			if (i > 1) {
				GString* _tmp55_;
				_tmp55_ = builder;
				g_string_append (_tmp55_, ", ");
			}
			_tmp56_ = param;
			_tmp57_ = vala_parameter_get_ellipsis (_tmp56_);
			_tmp58_ = _tmp57_;
			if (_tmp58_) {
				GString* _tmp59_;
				_tmp59_ = builder;
				g_string_append (_tmp59_, "...");
				_vala_code_node_unref0 (param);
				continue;
			}
			_tmp60_ = param;
			_tmp61_ = vala_parameter_get_params_array (_tmp60_);
			_tmp62_ = _tmp61_;
			if (_tmp62_) {
				GString* _tmp63_;
				_tmp63_ = builder;
				g_string_append (_tmp63_, "params ");
			}
			_tmp64_ = param;
			_tmp65_ = vala_parameter_get_direction (_tmp64_);
			_tmp66_ = _tmp65_;
			if (_tmp66_ == VALA_PARAMETER_DIRECTION_IN) {
				ValaParameter* _tmp67_;
				ValaDataType* _tmp68_;
				ValaDataType* _tmp69_;
				gboolean _tmp70_;
				gboolean _tmp71_;
				_tmp67_ = param;
				_tmp68_ = vala_variable_get_variable_type ((ValaVariable*) _tmp67_);
				_tmp69_ = _tmp68_;
				_tmp70_ = vala_data_type_get_value_owned (_tmp69_);
				_tmp71_ = _tmp70_;
				if (_tmp71_) {
					GString* _tmp72_;
					_tmp72_ = builder;
					g_string_append (_tmp72_, "owned ");
				}
			} else {
				ValaParameter* _tmp73_;
				ValaParameterDirection _tmp74_;
				ValaParameterDirection _tmp75_;
				gboolean _tmp81_ = FALSE;
				ValaParameter* _tmp82_;
				ValaDataType* _tmp83_;
				ValaDataType* _tmp84_;
				gboolean _tmp85_;
				gboolean _tmp86_;
				_tmp73_ = param;
				_tmp74_ = vala_parameter_get_direction (_tmp73_);
				_tmp75_ = _tmp74_;
				if (_tmp75_ == VALA_PARAMETER_DIRECTION_REF) {
					GString* _tmp76_;
					_tmp76_ = builder;
					g_string_append (_tmp76_, "ref ");
				} else {
					ValaParameter* _tmp77_;
					ValaParameterDirection _tmp78_;
					ValaParameterDirection _tmp79_;
					_tmp77_ = param;
					_tmp78_ = vala_parameter_get_direction (_tmp77_);
					_tmp79_ = _tmp78_;
					if (_tmp79_ == VALA_PARAMETER_DIRECTION_OUT) {
						GString* _tmp80_;
						_tmp80_ = builder;
						g_string_append (_tmp80_, "out ");
					}
				}
				_tmp82_ = param;
				_tmp83_ = vala_variable_get_variable_type ((ValaVariable*) _tmp82_);
				_tmp84_ = _tmp83_;
				_tmp85_ = vala_data_type_get_value_owned (_tmp84_);
				_tmp86_ = _tmp85_;
				if (!_tmp86_) {
					ValaParameter* _tmp87_;
					ValaDataType* _tmp88_;
					ValaDataType* _tmp89_;
					_tmp87_ = param;
					_tmp88_ = vala_variable_get_variable_type ((ValaVariable*) _tmp87_);
					_tmp89_ = _tmp88_;
					_tmp81_ = VALA_IS_REFERENCE_TYPE (_tmp89_);
				} else {
					_tmp81_ = FALSE;
				}
				if (_tmp81_) {
					GString* _tmp90_;
					_tmp90_ = builder;
					g_string_append (_tmp90_, "weak ");
				}
			}
			_tmp91_ = builder;
			_tmp92_ = param;
			_tmp93_ = vala_variable_get_variable_type ((ValaVariable*) _tmp92_);
			_tmp94_ = _tmp93_;
			_tmp95_ = vala_data_type_to_qualified_string (_tmp94_, NULL);
			_tmp96_ = _tmp95_;
			g_string_append (_tmp91_, _tmp96_);
			_g_free0 (_tmp96_);
			_tmp97_ = param;
			_tmp98_ = vala_variable_get_initializer ((ValaVariable*) _tmp97_);
			_tmp99_ = _tmp98_;
			if (_tmp99_ != NULL) {
				GString* _tmp100_;
				GString* _tmp101_;
				ValaParameter* _tmp102_;
				ValaExpression* _tmp103_;
				ValaExpression* _tmp104_;
				gchar* _tmp105_;
				gchar* _tmp106_;
				_tmp100_ = builder;
				g_string_append (_tmp100_, " = ");
				_tmp101_ = builder;
				_tmp102_ = param;
				_tmp103_ = vala_variable_get_initializer ((ValaVariable*) _tmp102_);
				_tmp104_ = _tmp103_;
				_tmp105_ = vala_code_node_to_string ((ValaCodeNode*) _tmp104_);
				_tmp106_ = _tmp105_;
				g_string_append (_tmp101_, _tmp106_);
				_g_free0 (_tmp106_);
			}
			_tmp107_ = i;
			i = _tmp107_ + 1;
			_vala_code_node_unref0 (param);
		}
	}
	_tmp108_ = builder;
	g_string_append_c (_tmp108_, ')');
	_tmp109_ = g_direct_equal;
	_tmp110_ = vala_array_list_new (VALA_TYPE_DATA_TYPE, (GBoxedCopyFunc) vala_code_node_ref, (GDestroyNotify) vala_code_node_unref, _tmp109_);
	error_types = _tmp110_;
	_tmp111_ = vala_callable_type_get_callable_symbol (self);
	_tmp112_ = _tmp111_;
	_tmp113_ = error_types;
	vala_code_node_get_error_types ((ValaCodeNode*) _tmp112_, (ValaCollection*) _tmp113_, NULL);
	_tmp114_ = error_types;
	_tmp115_ = vala_collection_get_size ((ValaCollection*) _tmp114_);
	_tmp116_ = _tmp115_;
	if (_tmp116_ > 0) {
		GString* _tmp117_;
		gboolean first = FALSE;
		_tmp117_ = builder;
		g_string_append (_tmp117_, " throws ");
		first = TRUE;
		{
			ValaArrayList* _type_list = NULL;
			ValaArrayList* _tmp118_;
			gint _type_size = 0;
			ValaArrayList* _tmp119_;
			gint _tmp120_;
			gint _tmp121_;
			gint _type_index = 0;
			_tmp118_ = error_types;
			_type_list = _tmp118_;
			_tmp119_ = _type_list;
			_tmp120_ = vala_collection_get_size ((ValaCollection*) _tmp119_);
			_tmp121_ = _tmp120_;
			_type_size = _tmp121_;
			_type_index = -1;
			while (TRUE) {
				gint _tmp122_;
				gint _tmp123_;
				ValaDataType* type = NULL;
				ValaArrayList* _tmp124_;
				gpointer _tmp125_;
				GString* _tmp127_;
				ValaDataType* _tmp128_;
				gchar* _tmp129_;
				gchar* _tmp130_;
				_type_index = _type_index + 1;
				_tmp122_ = _type_index;
				_tmp123_ = _type_size;
				if (!(_tmp122_ < _tmp123_)) {
					break;
				}
				_tmp124_ = _type_list;
				_tmp125_ = vala_list_get ((ValaList*) _tmp124_, _type_index);
				type = (ValaDataType*) _tmp125_;
				if (!first) {
					GString* _tmp126_;
					_tmp126_ = builder;
					g_string_append (_tmp126_, ", ");
				} else {
					first = FALSE;
				}
				_tmp127_ = builder;
				_tmp128_ = type;
				_tmp129_ = vala_code_node_to_string ((ValaCodeNode*) _tmp128_);
				_tmp130_ = _tmp129_;
				g_string_append (_tmp127_, _tmp130_);
				_g_free0 (_tmp130_);
				_vala_code_node_unref0 (type);
			}
		}
	}
	_tmp131_ = builder;
	_tmp132_ = _tmp131_->str;
	_tmp133_ = g_strdup (_tmp132_);
	result = _tmp133_;
	_vala_iterable_unref0 (error_types);
	_g_free0 (_tmp23_);
	_g_string_free0 (builder);
	return result;
}

static void
vala_callable_type_class_init (ValaCallableTypeClass * klass,
                               gpointer klass_data)
{
	vala_callable_type_parent_class = g_type_class_peek_parent (klass);
	((ValaDataTypeClass *) klass)->is_invokable = (gboolean (*) (ValaDataType*)) vala_callable_type_real_is_invokable;
	((ValaDataTypeClass *) klass)->get_return_type = (ValaDataType* (*) (ValaDataType*)) vala_callable_type_real_get_return_type;
	((ValaDataTypeClass *) klass)->get_parameters = (ValaList* (*) (ValaDataType*)) vala_callable_type_real_get_parameters;
	((ValaDataTypeClass *) klass)->to_prototype_string = (gchar* (*) (ValaDataType*, const gchar*)) vala_callable_type_real_to_prototype_string;
}

static void
vala_callable_type_instance_init (ValaCallableType * self,
                                  gpointer klass)
{
}

/**
 * A callable type, i.e. a delegate, method, or signal type.
 */
static GType
vala_callable_type_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ValaCallableTypeClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) vala_callable_type_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ValaCallableType), 0, (GInstanceInitFunc) vala_callable_type_instance_init, NULL };
	GType vala_callable_type_type_id;
	vala_callable_type_type_id = g_type_register_static (VALA_TYPE_DATA_TYPE, "ValaCallableType", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
	return vala_callable_type_type_id;
}

GType
vala_callable_type_get_type (void)
{
	static volatile gsize vala_callable_type_type_id__once = 0;
	if (g_once_init_enter (&vala_callable_type_type_id__once)) {
		GType vala_callable_type_type_id;
		vala_callable_type_type_id = vala_callable_type_get_type_once ();
		g_once_init_leave (&vala_callable_type_type_id__once, vala_callable_type_type_id);
	}
	return vala_callable_type_type_id__once;
}

