+
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public RenderableReturnType Create(GirModel.ReturnType returnType)
{
var nullableTypeName = ComplexType.GetFullyQualified((GirModel.Record) returnType.AnyType.AsT0);

if (returnType.Nullable)
nullableTypeName = $"{nullableTypeName}?";
return new RenderableReturnType(nullableTypeName);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ public string GetString(GirModel.ReturnType returnType, string fromVariableName)
throw new NotImplementedException($"Can't convert {returnType} to managed as it is a pointer");

if (cls.Fundamental)
return $"new {ComplexType.GetFullyQualified(cls)}({fromVariableName})";
{
string ctor = $"new {ComplexType.GetFullyQualified(cls)}({fromVariableName})";
if (returnType.Nullable)
return $"{fromVariableName}.Equals(IntPtr.Zero) ? null : {ctor}";
return ctor;
}

return returnType.Nullable
? $"GObject.Internal.ObjectWrapper.WrapNullableHandle<{ComplexType.GetFullyQualified(cls)}>({fromVariableName}, {Transfer.IsOwnedRef(returnType.Transfer).ToString().ToLower()})"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
using System;
using GirModel;
using Generator.Model;

namespace Generator.Renderer.Public.ReturnTypeToManagedExpressions;

internal class Record : ReturnTypeConverter
{
public bool Supports(AnyType type)
public bool Supports(GirModel.AnyType type)
=> type.Is<GirModel.Record>();

public string GetString(GirModel.ReturnType returnType, string fromVariableName)
{
if (returnType.IsPointer)
return $"new {ReturnTypeRenderer.Render(returnType)}({fromVariableName})";
{
var record = (GirModel.Record) returnType.AnyType.AsT0;
string ctor = $"new {ComplexType.GetFullyQualified(record)}({fromVariableName})";
if (returnType.Nullable)
return $"{fromVariableName}.Equals(IntPtr.Zero) ? null : {ctor}";
return ctor;
}

throw new NotImplementedException("Can't convert from internal records which are returnd by value to public available. This is not supported in current development branch, too.");
}
Expand Down
242 changes: 242 additions & 0 deletions src/Native/GirTestLib/data/girtest-instantiatable-fundamental.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
#include "girtest-instantiatable-fundamental.h"

#include <gobject/gvaluecollector.h>

typedef struct _GirTestInstantiatableFundamentalClass GirTestInstantiatableFundamentalClass;
typedef struct _GirTestInstantiatableFundamentalTypeInfo GirTestInstantiatableFundamentalTypeInfo;

/**
* GirTestInstantiatableFundamental:
*
* A fundamental type designed for unit tests.
*/

struct _GirTestInstantiatableFundamental
{
GTypeInstance parent_instance;
gatomicrefcount ref_count;
GType value_type;
};

struct _GirTestInstantiatableFundamentalClass
{
void (* finalize) (GirTestInstantiatableFundamental *inst);
gboolean (* is_static) (GirTestInstantiatableFundamental *inst);
};

struct _GirTestInstantiatableFundamentalTypeInfo
{
gsize instance_size;
void (* instance_init) (GirTestInstantiatableFundamental *inst);
void (* finalize) (GirTestInstantiatableFundamental *inst);
gboolean (* is_static) (GirTestInstantiatableFundamental *inst);
};

#define GIRTEST_INSTANTIATABLE_FUNDAMENTAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIRTEST_TYPE_INSTANTIATABLE_FUNDAMENTAL, GirTestInstantiatableFundamentalClass))

static void
girtest_instantiatable_fundamental_init (GirTestInstantiatableFundamental *self)
{
g_atomic_ref_count_init (&self->ref_count);
}

static void
value_instantiatable_fundamental_init(GValue *value)
{
value->data[0].v_pointer = NULL;
}

static void
girtest_instantiatable_fundamental_finalize (GirTestInstantiatableFundamental *self)
{
g_type_free_instance ((GTypeInstance *) self);
}

static void
girtest_instantiatable_fundamental_class_init(GirTestInstantiatableFundamentalClass *class)
{
class->finalize = girtest_instantiatable_fundamental_finalize;
}

/**
* girtest_instantiatable_fundamental_new:
*
* Creates a new `GirTestInstantiatableFundamental`.
*
* Returns: (transfer full): The newly created `GirTestInstantiatableFundamental`.
*/
GirTestInstantiatableFundamental*
girtest_instantiatable_fundamental_new()
{
GirTestInstantiatableFundamental *self;
self = (GirTestInstantiatableFundamental *)g_type_create_instance(GIRTEST_TYPE_INSTANTIATABLE_FUNDAMENTAL);
((GTypeInstance *)self)->g_class->g_type = GIRTEST_TYPE_INSTANTIATABLE_FUNDAMENTAL;
return self;
}

/**
* girtest_instantiatable_fundamental_unref:
* @self: (transfer full): a `GirTestInstantiatableFundamental`
*
* Releases a reference on the given `GirTestInstantiatableFundamental`.
*
* If the reference was the last, the resources associated to the `self` are
* freed.
*/
void
girtest_instantiatable_fundamental_unref (GirTestInstantiatableFundamental *self)
{
g_return_if_fail (GIRTEST_IS_INSTANTIATABLE_FUNDAMENTAL (self));

if (g_atomic_ref_count_dec (&self->ref_count)) {
girtest_instantiatable_fundamental_finalize(self);
}
}

/**
* girtest_instantiatable_fundamental_ref:
* @self: a `GirTestInstantiatableFundamental`
*
* Acquires a reference on the given `GirTestInstantiatableFundamental`.
*
* Returns: (transfer full): the `GirTestInstantiatableFundamental` with an additional reference
*/
GirTestInstantiatableFundamental *
girtest_instantiatable_fundamental_ref (GirTestInstantiatableFundamental *self)
{
g_return_val_if_fail (GIRTEST_IS_INSTANTIATABLE_FUNDAMENTAL (self), NULL);

g_atomic_ref_count_inc (&self->ref_count);

return self;
}

static void
value_instantiatable_fundamental_copy (const GValue *src,
GValue *dst)
{
if (src->data[0].v_pointer != NULL && GIRTEST_IS_INSTANTIATABLE_FUNDAMENTAL(src->data[0].v_pointer)) {
g_atomic_ref_count_inc (src->data[0].v_pointer);
dst->data[0].v_pointer = src->data[0].v_pointer;
}
else
dst->data[0].v_pointer = NULL;
}

static gpointer
value_instantiatable_fundamental_peek_pointer (const GValue *value)
{
return value->data[0].v_pointer;
}

static void
value_instantiatable_fundamental_free_value (GValue *value)
{
if (value->data[0].v_pointer != NULL)
g_clear_pointer (&value->data[0].v_pointer, girtest_instantiatable_fundamental_unref);
}

static char *
value_instantiatable_fundamental_collect_value (GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
GirTestInstantiatableFundamental *inst = collect_values[0].v_pointer;

if (inst == NULL)
{
value->data[0].v_pointer = NULL;
return NULL;
}

if (inst->parent_instance.g_class == NULL)
return g_strconcat ("invalid unclassed GirTestInstantiatableFundamental pointer for "
"value type '",
G_VALUE_TYPE_NAME (value),
"'",
NULL);

value->data[0].v_pointer = girtest_instantiatable_fundamental_ref (inst);

return NULL;
}

static char *
value_instantiatable_fundamental_lcopy_value (const GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
GirTestInstantiatableFundamental **inst = collect_values[0].v_pointer;

if (inst == NULL)
return g_strconcat ("value location for '",
G_VALUE_TYPE_NAME (value),
"' passed as NULL",
NULL);

if (value->data[0].v_pointer == NULL)
*inst = NULL;
else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
*inst = value->data[0].v_pointer;
else
*inst = girtest_instantiatable_fundamental_ref (value->data[0].v_pointer);

return NULL;
}

GType
girtest_instantiatable_fundamental_get_type (void)
{
static gsize type_id;

if (g_once_init_enter (&type_id))
{
static const GTypeFundamentalInfo finfo = {
(G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_INSTANTIATABLE |
G_TYPE_FLAG_DERIVABLE |
G_TYPE_FLAG_DEEP_DERIVABLE),
};

static const GTypeValueTable value_table = {
value_instantiatable_fundamental_init,
value_instantiatable_fundamental_free_value,
value_instantiatable_fundamental_copy,
value_instantiatable_fundamental_peek_pointer,
"p",
value_instantiatable_fundamental_collect_value,
"p",
value_instantiatable_fundamental_lcopy_value,
};

const GTypeInfo info = {
/* Class */
sizeof (GirTestInstantiatableFundamentalClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) girtest_instantiatable_fundamental_class_init,
(GClassFinalizeFunc) NULL,
NULL,

/* Instance */
sizeof (GirTestInstantiatableFundamental),
0,
(GInstanceInitFunc) girtest_instantiatable_fundamental_init,

/* GValue */
&value_table,
};

GType type =
g_type_register_fundamental (g_type_fundamental_next (),
g_intern_static_string ("GirTestInstantiatableFundamental"),
&info, &finfo,
// G_TYPE_FLAG_NONE only available in gobject>=2.74
0 /* G_TYPE_FLAG_NONE */);

g_once_init_leave (&type_id, type);
}
return type_id;
}
23 changes: 23 additions & 0 deletions src/Native/GirTestLib/data/girtest-instantiatable-fundamental.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include <glib-object.h>

G_BEGIN_DECLS

GType
girtest_instantiatable_fundamental_get_type (void);

#define GIRTEST_TYPE_INSTANTIATABLE_FUNDAMENTAL girtest_instantiatable_fundamental_get_type()
#define GIRTEST_IS_INSTANTIATABLE_FUNDAMENTAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIRTEST_TYPE_INSTANTIATABLE_FUNDAMENTAL))
#define GIRTEST_INSTANTIATABLE_FUNDAMENTAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIRTEST_TYPE_INSTANTIATABLE_FUNDAMENTAL, GirTestInstantiatableFundamental))

typedef struct _GirTestInstantiatableFundamental GirTestInstantiatableFundamental;

void
girtest_instantiatable_fundamental_unref (GirTestInstantiatableFundamental *self);

GirTestInstantiatableFundamental*
girtest_instantiatable_fundamental_new();

G_END_DECLS

44 changes: 44 additions & 0 deletions src/Native/GirTestLib/girtest-fundamental-tester.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "girtest-fundamental-tester.h"

#include <gobject/gvaluecollector.h>

/**
* GirTestFundamentalTester:
*
* Unit tests for fundamental types.
*/

struct _GirTestFundamentalTester
{
GObject parent_instance;
};

G_DEFINE_TYPE(GirTestFundamentalTester, girtest_fundamental_tester, G_TYPE_OBJECT)

static void
girtest_fundamental_tester_init(GirTestFundamentalTester *value)
{
}

static void
girtest_fundamental_tester_class_init(GirTestFundamentalTesterClass *class)
{
}

/**
* girtest_fundamental_tester_create_fundamental:
* @return_null: Iff true, NULL will be returned.
*
* Creates a new `GirTestInstantiatableFundamental`.
*
* Returns: (transfer full) (nullable): The newly created `GirTestInstantiatableFundamental`.
*/
GirTestInstantiatableFundamental*
girtest_fundamental_tester_create_fundamental (gboolean return_null)
{
if (return_null) {
return NULL;
}
GirTestInstantiatableFundamental *tester = girtest_instantiatable_fundamental_new();
return tester;
}
20 changes: 20 additions & 0 deletions src/Native/GirTestLib/girtest-fundamental-tester.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include <glib-object.h>

#include "data/girtest-instantiatable-fundamental.h"

G_BEGIN_DECLS

#define GIRTEST_TYPE_FUNDAMENTAL_TESTER girtest_fundamental_tester_get_type()

typedef struct _GirTestFundamentalTester GirTestFundamentalTester;

G_DECLARE_FINAL_TYPE(GirTestFundamentalTester, girtest_fundamental_tester,
GIRTEST, FUNDAMENTAL_TESTER, GObject)

GirTestInstantiatableFundamental*
girtest_fundamental_tester_create_fundamental (gboolean return_null);

G_END_DECLS

Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载