[vala/wip/issue/370] parser: Improve partial classes support
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/issue/370] parser: Improve partial classes support
- Date: Tue, 21 Dec 2021 15:34:13 +0000 (UTC)
commit 73cd47c7c474d4601766a10e413e4e7512b810f2
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Sat Dec 18 22:25:54 2021 +0100
parser: Improve partial classes support
Fixes https://gitlab.gnome.org/GNOME/vala/issues/370
tests/Makefile.am | 1 +
tests/objects/class-partial-nested.c-expected | 440 ++++++++++++++++++++++++++
tests/objects/class-partial-nested.vala | 34 ++
tests/objects/class-partial.c-expected | 120 +++----
vala/valaparser.vala | 69 +++-
5 files changed, 601 insertions(+), 63 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b3e51dc7b..788d9e474 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -471,6 +471,7 @@ TESTS = \
objects/class-partial-conflict-access.test \
objects/class-partial-conflict-partial.test \
objects/class-partial-conflict-sealed.test \
+ objects/class-partial-nested.vala \
objects/class-vfunc-base-access.vala \
objects/classes.vala \
objects/classes-interfaces.vala \
diff --git a/tests/objects/class-partial-nested.c-expected b/tests/objects/class-partial-nested.c-expected
new file mode 100644
index 000000000..32b00c14e
--- /dev/null
+++ b/tests/objects/class-partial-nested.c-expected
@@ -0,0 +1,440 @@
+/* objects_class_partial_nested.c generated by valac, the Vala compiler
+ * generated from objects_class_partial_nested.vala, do not modify */
+
+#include <glib-object.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <gobject/gvaluecollector.h>
+
+#if !defined(VALA_EXTERN)
+#if defined(_MSC_VER)
+#define VALA_EXTERN __declspec(dllexport) extern
+#elif __GNUC__ >= 4
+#define VALA_EXTERN __attribute__((visibility("default"))) extern
+#else
+#define VALA_EXTERN extern
+#endif
+#endif
+
+#define MANAM_FOO_BAR_TYPE_BAZ (manam_foo_bar_baz_get_type ())
+#define MANAM_FOO_BAR_BAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MANAM_FOO_BAR_TYPE_BAZ, ManamFooBarBaz))
+#define MANAM_FOO_BAR_BAZ_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MANAM_FOO_BAR_TYPE_BAZ,
ManamFooBarBazClass))
+#define MANAM_FOO_BAR_IS_BAZ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MANAM_FOO_BAR_TYPE_BAZ))
+#define MANAM_FOO_BAR_IS_BAZ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MANAM_FOO_BAR_TYPE_BAZ))
+#define MANAM_FOO_BAR_BAZ_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MANAM_FOO_BAR_TYPE_BAZ,
ManamFooBarBazClass))
+
+typedef struct _ManamFooBarBaz ManamFooBarBaz;
+typedef struct _ManamFooBarBazClass ManamFooBarBazClass;
+typedef struct _ManamFooBarBazPrivate ManamFooBarBazPrivate;
+#define _g_free0(var) (var = (g_free (var), NULL))
+#define _manam_foo_bar_baz_unref0(var) ((var == NULL) ? NULL : (var = (manam_foo_bar_baz_unref (var), NULL)))
+typedef struct _ManamFooBarParamSpecBaz ManamFooBarParamSpecBaz;
+
+struct _ManamFooBarBaz {
+ GTypeInstance parent_instance;
+ volatile int ref_count;
+ ManamFooBarBazPrivate * priv;
+ gchar* f0;
+ gchar* f1;
+};
+
+struct _ManamFooBarBazClass {
+ GTypeClass parent_class;
+ void (*finalize) (ManamFooBarBaz *self);
+ void (*v0) (ManamFooBarBaz* self);
+ void (*v1) (ManamFooBarBaz* self);
+};
+
+struct _ManamFooBarBazPrivate {
+ gchar* _p0;
+ gchar* _p1;
+};
+
+struct _ManamFooBarParamSpecBaz {
+ GParamSpec parent_instance;
+};
+
+static gint ManamFooBarBaz_private_offset;
+static gpointer manam_foo_bar_baz_parent_class = NULL;
+
+static void _vala_main (void);
+VALA_EXTERN gpointer manam_foo_bar_baz_ref (gpointer instance);
+VALA_EXTERN void manam_foo_bar_baz_unref (gpointer instance);
+VALA_EXTERN GParamSpec* manam_foo_bar_param_spec_baz (const gchar* name,
+ const gchar* nick,
+ const gchar* blurb,
+ GType object_type,
+ GParamFlags flags);
+VALA_EXTERN void manam_foo_bar_value_set_baz (GValue* value,
+ gpointer v_object);
+VALA_EXTERN void manam_foo_bar_value_take_baz (GValue* value,
+ gpointer v_object);
+VALA_EXTERN gpointer manam_foo_bar_value_get_baz (const GValue* value);
+VALA_EXTERN GType manam_foo_bar_baz_get_type (void) G_GNUC_CONST ;
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (ManamFooBarBaz, manam_foo_bar_baz_unref)
+VALA_EXTERN ManamFooBarBaz* manam_foo_bar_baz_new (void);
+VALA_EXTERN ManamFooBarBaz* manam_foo_bar_baz_construct (GType object_type);
+VALA_EXTERN void manam_foo_bar_baz_set_p0 (ManamFooBarBaz* self,
+ const gchar* value);
+VALA_EXTERN void manam_foo_bar_baz_m0 (ManamFooBarBaz* self);
+VALA_EXTERN void manam_foo_bar_baz_v0 (ManamFooBarBaz* self);
+VALA_EXTERN void manam_foo_bar_baz_set_p1 (ManamFooBarBaz* self,
+ const gchar* value);
+VALA_EXTERN void manam_foo_bar_baz_m1 (ManamFooBarBaz* self);
+VALA_EXTERN void manam_foo_bar_baz_v1 (ManamFooBarBaz* self);
+static void manam_foo_bar_baz_real_v0 (ManamFooBarBaz* self);
+static void manam_foo_bar_baz_real_v1 (ManamFooBarBaz* self);
+VALA_EXTERN const gchar* manam_foo_bar_baz_get_p0 (ManamFooBarBaz* self);
+VALA_EXTERN const gchar* manam_foo_bar_baz_get_p1 (ManamFooBarBaz* self);
+static void manam_foo_bar_baz_finalize (ManamFooBarBaz * obj);
+static GType manam_foo_bar_baz_get_type_once (void);
+
+static void
+_vala_main (void)
+{
+ ManamFooBarBaz* baz = NULL;
+ ManamFooBarBaz* _tmp0_;
+ gchar* _tmp1_;
+ gchar* _tmp2_;
+ _tmp0_ = manam_foo_bar_baz_new ();
+ baz = _tmp0_;
+ manam_foo_bar_baz_set_p0 (baz, "p0");
+ _tmp1_ = g_strdup ("f0");
+ _g_free0 (baz->f0);
+ baz->f0 = _tmp1_;
+ manam_foo_bar_baz_m0 (baz);
+ manam_foo_bar_baz_v0 (baz);
+ manam_foo_bar_baz_set_p1 (baz, "p1");
+ _tmp2_ = g_strdup ("f1");
+ _g_free0 (baz->f1);
+ baz->f1 = _tmp2_;
+ manam_foo_bar_baz_m1 (baz);
+ manam_foo_bar_baz_v1 (baz);
+ _manam_foo_bar_baz_unref0 (baz);
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
+static inline gpointer
+manam_foo_bar_baz_get_instance_private (ManamFooBarBaz* self)
+{
+ return G_STRUCT_MEMBER_P (self, ManamFooBarBaz_private_offset);
+}
+
+void
+manam_foo_bar_baz_m0 (ManamFooBarBaz* self)
+{
+ g_return_if_fail (MANAM_FOO_BAR_IS_BAZ (self));
+}
+
+static void
+manam_foo_bar_baz_real_v0 (ManamFooBarBaz* self)
+{
+}
+
+void
+manam_foo_bar_baz_v0 (ManamFooBarBaz* self)
+{
+ ManamFooBarBazClass* _klass_;
+ g_return_if_fail (MANAM_FOO_BAR_IS_BAZ (self));
+ _klass_ = MANAM_FOO_BAR_BAZ_GET_CLASS (self);
+ if (_klass_->v0) {
+ _klass_->v0 (self);
+ }
+}
+
+ManamFooBarBaz*
+manam_foo_bar_baz_construct (GType object_type)
+{
+ ManamFooBarBaz* self = NULL;
+ self = (ManamFooBarBaz*) g_type_create_instance (object_type);
+ return self;
+}
+
+ManamFooBarBaz*
+manam_foo_bar_baz_new (void)
+{
+ return manam_foo_bar_baz_construct (MANAM_FOO_BAR_TYPE_BAZ);
+}
+
+void
+manam_foo_bar_baz_m1 (ManamFooBarBaz* self)
+{
+ g_return_if_fail (MANAM_FOO_BAR_IS_BAZ (self));
+}
+
+static void
+manam_foo_bar_baz_real_v1 (ManamFooBarBaz* self)
+{
+}
+
+void
+manam_foo_bar_baz_v1 (ManamFooBarBaz* self)
+{
+ ManamFooBarBazClass* _klass_;
+ g_return_if_fail (MANAM_FOO_BAR_IS_BAZ (self));
+ _klass_ = MANAM_FOO_BAR_BAZ_GET_CLASS (self);
+ if (_klass_->v1) {
+ _klass_->v1 (self);
+ }
+}
+
+const gchar*
+manam_foo_bar_baz_get_p0 (ManamFooBarBaz* self)
+{
+ const gchar* result;
+ const gchar* _tmp0_;
+ g_return_val_if_fail (MANAM_FOO_BAR_IS_BAZ (self), NULL);
+ _tmp0_ = self->priv->_p0;
+ result = _tmp0_;
+ return result;
+}
+
+void
+manam_foo_bar_baz_set_p0 (ManamFooBarBaz* self,
+ const gchar* value)
+{
+ gchar* _tmp0_;
+ g_return_if_fail (MANAM_FOO_BAR_IS_BAZ (self));
+ _tmp0_ = g_strdup (value);
+ _g_free0 (self->priv->_p0);
+ self->priv->_p0 = _tmp0_;
+}
+
+const gchar*
+manam_foo_bar_baz_get_p1 (ManamFooBarBaz* self)
+{
+ const gchar* result;
+ const gchar* _tmp0_;
+ g_return_val_if_fail (MANAM_FOO_BAR_IS_BAZ (self), NULL);
+ _tmp0_ = self->priv->_p1;
+ result = _tmp0_;
+ return result;
+}
+
+void
+manam_foo_bar_baz_set_p1 (ManamFooBarBaz* self,
+ const gchar* value)
+{
+ gchar* _tmp0_;
+ g_return_if_fail (MANAM_FOO_BAR_IS_BAZ (self));
+ _tmp0_ = g_strdup (value);
+ _g_free0 (self->priv->_p1);
+ self->priv->_p1 = _tmp0_;
+}
+
+static void
+manam_foo_bar_value_baz_init (GValue* value)
+{
+ value->data[0].v_pointer = NULL;
+}
+
+static void
+manam_foo_bar_value_baz_free_value (GValue* value)
+{
+ if (value->data[0].v_pointer) {
+ manam_foo_bar_baz_unref (value->data[0].v_pointer);
+ }
+}
+
+static void
+manam_foo_bar_value_baz_copy_value (const GValue* src_value,
+ GValue* dest_value)
+{
+ if (src_value->data[0].v_pointer) {
+ dest_value->data[0].v_pointer = manam_foo_bar_baz_ref (src_value->data[0].v_pointer);
+ } else {
+ dest_value->data[0].v_pointer = NULL;
+ }
+}
+
+static gpointer
+manam_foo_bar_value_baz_peek_pointer (const GValue* value)
+{
+ return value->data[0].v_pointer;
+}
+
+static gchar*
+manam_foo_bar_value_baz_collect_value (GValue* value,
+ guint n_collect_values,
+ GTypeCValue* collect_values,
+ guint collect_flags)
+{
+ if (collect_values[0].v_pointer) {
+ ManamFooBarBaz * object;
+ object = collect_values[0].v_pointer;
+ if (object->parent_instance.g_class == NULL) {
+ return g_strconcat ("invalid unclassed object pointer for value type `",
G_VALUE_TYPE_NAME (value), "'", NULL);
+ } else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
+ return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE
(object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
+ }
+ value->data[0].v_pointer = manam_foo_bar_baz_ref (object);
+ } else {
+ value->data[0].v_pointer = NULL;
+ }
+ return NULL;
+}
+
+static gchar*
+manam_foo_bar_value_baz_lcopy_value (const GValue* value,
+ guint n_collect_values,
+ GTypeCValue* collect_values,
+ guint collect_flags)
+{
+ ManamFooBarBaz ** object_p;
+ object_p = collect_values[0].v_pointer;
+ if (!object_p) {
+ return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
+ }
+ if (!value->data[0].v_pointer) {
+ *object_p = NULL;
+ } else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
+ *object_p = value->data[0].v_pointer;
+ } else {
+ *object_p = manam_foo_bar_baz_ref (value->data[0].v_pointer);
+ }
+ return NULL;
+}
+
+GParamSpec*
+manam_foo_bar_param_spec_baz (const gchar* name,
+ const gchar* nick,
+ const gchar* blurb,
+ GType object_type,
+ GParamFlags flags)
+{
+ ManamFooBarParamSpecBaz* spec;
+ g_return_val_if_fail (g_type_is_a (object_type, MANAM_FOO_BAR_TYPE_BAZ), NULL);
+ spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
+ G_PARAM_SPEC (spec)->value_type = object_type;
+ return G_PARAM_SPEC (spec);
+}
+
+gpointer
+manam_foo_bar_value_get_baz (const GValue* value)
+{
+ g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, MANAM_FOO_BAR_TYPE_BAZ), NULL);
+ return value->data[0].v_pointer;
+}
+
+void
+manam_foo_bar_value_set_baz (GValue* value,
+ gpointer v_object)
+{
+ ManamFooBarBaz * old;
+ g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, MANAM_FOO_BAR_TYPE_BAZ));
+ old = value->data[0].v_pointer;
+ if (v_object) {
+ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, MANAM_FOO_BAR_TYPE_BAZ));
+ g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE
(value)));
+ value->data[0].v_pointer = v_object;
+ manam_foo_bar_baz_ref (value->data[0].v_pointer);
+ } else {
+ value->data[0].v_pointer = NULL;
+ }
+ if (old) {
+ manam_foo_bar_baz_unref (old);
+ }
+}
+
+void
+manam_foo_bar_value_take_baz (GValue* value,
+ gpointer v_object)
+{
+ ManamFooBarBaz * old;
+ g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, MANAM_FOO_BAR_TYPE_BAZ));
+ old = value->data[0].v_pointer;
+ if (v_object) {
+ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, MANAM_FOO_BAR_TYPE_BAZ));
+ g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE
(value)));
+ value->data[0].v_pointer = v_object;
+ } else {
+ value->data[0].v_pointer = NULL;
+ }
+ if (old) {
+ manam_foo_bar_baz_unref (old);
+ }
+}
+
+static void
+manam_foo_bar_baz_class_init (ManamFooBarBazClass * klass,
+ gpointer klass_data)
+{
+ manam_foo_bar_baz_parent_class = g_type_class_peek_parent (klass);
+ ((ManamFooBarBazClass *) klass)->finalize = manam_foo_bar_baz_finalize;
+ g_type_class_adjust_private_offset (klass, &ManamFooBarBaz_private_offset);
+ ((ManamFooBarBazClass *) klass)->v0 = (void (*) (ManamFooBarBaz*)) manam_foo_bar_baz_real_v0;
+ ((ManamFooBarBazClass *) klass)->v1 = (void (*) (ManamFooBarBaz*)) manam_foo_bar_baz_real_v1;
+}
+
+static void
+manam_foo_bar_baz_instance_init (ManamFooBarBaz * self,
+ gpointer klass)
+{
+ self->priv = manam_foo_bar_baz_get_instance_private (self);
+ self->ref_count = 1;
+}
+
+static void
+manam_foo_bar_baz_finalize (ManamFooBarBaz * obj)
+{
+ ManamFooBarBaz * self;
+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, MANAM_FOO_BAR_TYPE_BAZ, ManamFooBarBaz);
+ g_signal_handlers_destroy (self);
+ _g_free0 (self->priv->_p0);
+ _g_free0 (self->f0);
+ _g_free0 (self->priv->_p1);
+ _g_free0 (self->f1);
+}
+
+static GType
+manam_foo_bar_baz_get_type_once (void)
+{
+ static const GTypeValueTable g_define_type_value_table = { manam_foo_bar_value_baz_init,
manam_foo_bar_value_baz_free_value, manam_foo_bar_value_baz_copy_value, manam_foo_bar_value_baz_peek_pointer,
"p", manam_foo_bar_value_baz_collect_value, "p", manam_foo_bar_value_baz_lcopy_value };
+ static const GTypeInfo g_define_type_info = { sizeof (ManamFooBarBazClass), (GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL, (GClassInitFunc) manam_foo_bar_baz_class_init, (GClassFinalizeFunc) NULL, NULL,
sizeof (ManamFooBarBaz), 0, (GInstanceInitFunc) manam_foo_bar_baz_instance_init, &g_define_type_value_table };
+ static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
+ GType manam_foo_bar_baz_type_id;
+ manam_foo_bar_baz_type_id = g_type_register_fundamental (g_type_fundamental_next (),
"ManamFooBarBaz", &g_define_type_info, &g_define_type_fundamental_info, 0);
+ ManamFooBarBaz_private_offset = g_type_add_instance_private (manam_foo_bar_baz_type_id, sizeof
(ManamFooBarBazPrivate));
+ return manam_foo_bar_baz_type_id;
+}
+
+GType
+manam_foo_bar_baz_get_type (void)
+{
+ static volatile gsize manam_foo_bar_baz_type_id__volatile = 0;
+ if (g_once_init_enter (&manam_foo_bar_baz_type_id__volatile)) {
+ GType manam_foo_bar_baz_type_id;
+ manam_foo_bar_baz_type_id = manam_foo_bar_baz_get_type_once ();
+ g_once_init_leave (&manam_foo_bar_baz_type_id__volatile, manam_foo_bar_baz_type_id);
+ }
+ return manam_foo_bar_baz_type_id__volatile;
+}
+
+gpointer
+manam_foo_bar_baz_ref (gpointer instance)
+{
+ ManamFooBarBaz * self;
+ self = instance;
+ g_atomic_int_inc (&self->ref_count);
+ return instance;
+}
+
+void
+manam_foo_bar_baz_unref (gpointer instance)
+{
+ ManamFooBarBaz * self;
+ self = instance;
+ if (g_atomic_int_dec_and_test (&self->ref_count)) {
+ MANAM_FOO_BAR_BAZ_GET_CLASS (self)->finalize (self);
+ g_type_free_instance ((GTypeInstance *) self);
+ }
+}
+
diff --git a/tests/objects/class-partial-nested.vala b/tests/objects/class-partial-nested.vala
new file mode 100644
index 000000000..03298ea4f
--- /dev/null
+++ b/tests/objects/class-partial-nested.vala
@@ -0,0 +1,34 @@
+namespace Manam.Foo {
+ public partial class Bar.Baz {
+ public string p0 { get; set; }
+ public string f0;
+ public void m0 () {
+ }
+ public virtual void v0 () {
+ }
+ }
+}
+
+namespace Manam.Foo {
+ public partial class Bar.Baz {
+ public string p1 { get; set; }
+ public string f1;
+ public void m1 () {
+ }
+ public virtual void v1 () {
+ }
+ }
+}
+
+void main () {
+ var baz = new Manam.Foo.Bar.Baz ();
+ baz.p0 = "p0";
+ baz.f0 = "f0";
+ baz.m0 ();
+ baz.v0 ();
+
+ baz.p1 = "p1";
+ baz.f1 = "f1";
+ baz.m1 ();
+ baz.v1 ();
+}
diff --git a/tests/objects/class-partial.c-expected b/tests/objects/class-partial.c-expected
index 0cf36ee73..ccc2533d7 100644
--- a/tests/objects/class-partial.c-expected
+++ b/tests/objects/class-partial.c-expected
@@ -42,6 +42,8 @@ typedef struct _IBarIface IBarIface;
typedef struct _Foo Foo;
typedef struct _FooClass FooClass;
typedef struct _FooPrivate FooPrivate;
+#define _g_free0(var) (var = (g_free (var), NULL))
+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
enum {
FOO_0_PROPERTY,
FOO_P0_PROPERTY,
@@ -50,7 +52,6 @@ enum {
FOO_NUM_PROPERTIES
};
static GParamSpec* foo_properties[FOO_NUM_PROPERTIES];
-#define _g_free0(var) (var = (g_free (var), NULL))
enum {
FOO_S0_SIGNAL,
FOO_S1_SIGNAL,
@@ -58,7 +59,6 @@ enum {
FOO_NUM_SIGNALS
};
static guint foo_signals[FOO_NUM_SIGNALS] = {0};
-#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__,
__LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN,
G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning
(G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
@@ -109,30 +109,31 @@ static GType ifoo_get_type_once (void);
VALA_EXTERN GType ibar_get_type (void) G_GNUC_CONST ;
VALA_EXTERN void ibar_i2 (IBar* self);
static GType ibar_get_type_once (void);
+static void _vala_main (void);
VALA_EXTERN GType foo_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (Foo, g_object_unref)
+VALA_EXTERN Foo* foo_new (void);
+VALA_EXTERN Foo* foo_construct (GType object_type);
+VALA_EXTERN void foo_set_p0 (Foo* self,
+ const gchar* value);
+VALA_EXTERN void foo_m0 (Foo* self);
VALA_EXTERN void foo_v0 (Foo* self);
+VALA_EXTERN void foo_set_p1 (Foo* self,
+ const gchar* value);
+VALA_EXTERN void foo_m1 (Foo* self);
VALA_EXTERN void foo_v1 (Foo* self);
+VALA_EXTERN void foo_set_p2 (Foo* self,
+ const gchar* value);
+VALA_EXTERN void foo_m2 (Foo* self);
VALA_EXTERN void foo_v2 (Foo* self);
-VALA_EXTERN void foo_m0 (Foo* self);
static void foo_real_v0 (Foo* self);
-VALA_EXTERN Foo* foo_new (void);
-VALA_EXTERN Foo* foo_construct (GType object_type);
-VALA_EXTERN void foo_m1 (Foo* self);
static void foo_real_v1 (Foo* self);
static void foo_real_i1 (IFoo* base);
-VALA_EXTERN void foo_m2 (Foo* self);
static void foo_real_v2 (Foo* self);
static void foo_real_i2 (IBar* base);
VALA_EXTERN const gchar* foo_get_p0 (Foo* self);
-VALA_EXTERN void foo_set_p0 (Foo* self,
- const gchar* value);
VALA_EXTERN const gchar* foo_get_p1 (Foo* self);
-VALA_EXTERN void foo_set_p1 (Foo* self,
- const gchar* value);
VALA_EXTERN const gchar* foo_get_p2 (Foo* self);
-VALA_EXTERN void foo_set_p2 (Foo* self,
- const gchar* value);
static void foo_real_s0 (Foo* self);
static void foo_real_s1 (Foo* self);
static void foo_real_s2 (Foo* self);
@@ -146,7 +147,6 @@ static void _vala_foo_set_property (GObject * object,
guint property_id,
const GValue * value,
GParamSpec * pspec);
-static void _vala_main (void);
void
ifoo_i1 (IFoo* self)
@@ -224,6 +224,52 @@ ibar_get_type (void)
return ibar_type_id__volatile;
}
+static void
+_vala_main (void)
+{
+ Foo* foo = NULL;
+ Foo* _tmp0_;
+ gchar* _tmp1_;
+ gchar* _tmp2_;
+ gchar* _tmp3_;
+ _tmp0_ = foo_new ();
+ foo = _tmp0_;
+ foo_set_p0 (foo, "p0");
+ _tmp1_ = g_strdup ("f0");
+ _g_free0 (foo->f0);
+ foo->f0 = _tmp1_;
+ foo_m0 (foo);
+ foo_v0 (foo);
+ g_signal_emit (foo, foo_signals[FOO_S0_SIGNAL], 0);
+ foo_set_p1 (foo, "p1");
+ _tmp2_ = g_strdup ("f1");
+ _g_free0 (foo->f1);
+ foo->f1 = _tmp2_;
+ foo_m1 (foo);
+ foo_v1 (foo);
+ g_signal_emit (foo, foo_signals[FOO_S1_SIGNAL], 0);
+ foo_set_p2 (foo, "p2");
+ _tmp3_ = g_strdup ("f2");
+ _g_free0 (foo->f2);
+ foo->f2 = _tmp3_;
+ foo_m2 (foo);
+ foo_v2 (foo);
+ g_signal_emit (foo, foo_signals[FOO_S2_SIGNAL], 0);
+ _vala_assert (IS_IFOO (foo), "foo is IFoo");
+ ifoo_i1 (G_TYPE_CHECK_INSTANCE_CAST (foo, TYPE_IFOO, IFoo));
+ _vala_assert (IS_IBAR (foo), "foo is IBar");
+ ibar_i2 (G_TYPE_CHECK_INSTANCE_CAST (foo, TYPE_IBAR, IBar));
+ _g_object_unref0 (foo);
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
static inline gpointer
foo_get_instance_private (Foo* self)
{
@@ -554,49 +600,3 @@ _vala_foo_set_property (GObject * object,
}
}
-static void
-_vala_main (void)
-{
- Foo* foo = NULL;
- Foo* _tmp0_;
- gchar* _tmp1_;
- gchar* _tmp2_;
- gchar* _tmp3_;
- _tmp0_ = foo_new ();
- foo = _tmp0_;
- foo_set_p0 (foo, "p0");
- _tmp1_ = g_strdup ("f0");
- _g_free0 (foo->f0);
- foo->f0 = _tmp1_;
- foo_m0 (foo);
- foo_v0 (foo);
- g_signal_emit (foo, foo_signals[FOO_S0_SIGNAL], 0);
- foo_set_p1 (foo, "p1");
- _tmp2_ = g_strdup ("f1");
- _g_free0 (foo->f1);
- foo->f1 = _tmp2_;
- foo_m1 (foo);
- foo_v1 (foo);
- g_signal_emit (foo, foo_signals[FOO_S1_SIGNAL], 0);
- foo_set_p2 (foo, "p2");
- _tmp3_ = g_strdup ("f2");
- _g_free0 (foo->f2);
- foo->f2 = _tmp3_;
- foo_m2 (foo);
- foo_v2 (foo);
- g_signal_emit (foo, foo_signals[FOO_S2_SIGNAL], 0);
- _vala_assert (IS_IFOO (foo), "foo is IFoo");
- ifoo_i1 (G_TYPE_CHECK_INSTANCE_CAST (foo, TYPE_IFOO, IFoo));
- _vala_assert (IS_IBAR (foo), "foo is IBar");
- ibar_i2 (G_TYPE_CHECK_INSTANCE_CAST (foo, TYPE_IBAR, IBar));
- _g_object_unref0 (foo);
-}
-
-int
-main (int argc,
- char ** argv)
-{
- _vala_main ();
- return 0;
-}
-
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index d61a581e0..112a0d04d 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -44,12 +44,20 @@ public class Vala.Parser : CodeVisitor {
static List<TypeParameter> _empty_type_parameter_list;
static int next_local_func_id = 0;
+ PartialInfo[] partials;
+
struct TokenInfo {
public TokenType type;
public SourceLocation begin;
public SourceLocation end;
}
+ struct PartialInfo {
+ public Symbol parent;
+ public SourceLocation begin;
+ public List<Attribute>? attributes;
+ }
+
[Flags]
enum ModifierFlags {
NONE = 0,
@@ -211,6 +219,20 @@ public class Vala.Parser : CodeVisitor {
}
}
+ void jump (SourceLocation location) {
+ while (tokens[index].begin.pos != location.pos) {
+ index = (index + 1) % BUFFER_SIZE;
+ size--;
+ if (size <= 0) {
+ scanner.seek (location);
+ size = 0;
+ index = 0;
+
+ next ();
+ }
+ }
+ }
+
void skip_identifier () throws ParseError {
// also accept keywords as identifiers where there is no conflict
switch (current ()) {
@@ -386,6 +408,8 @@ public class Vala.Parser : CodeVisitor {
try {
+ partials = new PartialInfo[] {};
+ var begin = get_location ();
parse_using_directives (context.root);
parse_declarations (context.root, true);
if (accept (TokenType.CLOSE_BRACE)) {
@@ -394,6 +418,14 @@ public class Vala.Parser : CodeVisitor {
Report.error (get_last_src (), "unexpected `}'");
}
}
+ if (partials.length > 0) {
+ rollback (begin);
+ foreach (var info in partials) {
+ jump (info.begin);
+ parse_class_declaration (info.parent, info.attributes, true);
+ }
+ }
+ partials = null;
} catch (ParseError e) {
report_parse_error (e);
}
@@ -2903,7 +2935,7 @@ public class Vala.Parser : CodeVisitor {
}
}
- void parse_class_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
+ void parse_class_declaration (Symbol parent, List<Attribute>? attrs, bool partial_reparse = false)
throws ParseError {
var begin = get_location ();
var access = parse_access_modifier ();
var flags = parse_type_declaration_modifiers ();
@@ -2935,7 +2967,30 @@ public class Vala.Parser : CodeVisitor {
cl.is_extern = true;
}
- var old_cl = parent.scope.lookup (cl.name) as Class;
+ Class? old_cl = null;
+ if (partial_reparse) {
+ var names = new ArrayList<string> ();
+ while (sym.inner != null) {
+ sym = sym.inner;
+ names.insert (0, sym.name);
+ }
+ Symbol p = parent;
+ while (p != null && p != context.root) {
+ names.insert (0, p.name);
+ p = p.parent_symbol;
+ }
+ p = context.root;
+ foreach (var name in names) {
+ p = p.scope.lookup (name);
+ if (p == null) {
+ break;
+ }
+ }
+ if (p != null) {
+ old_cl = p.scope.lookup (cl.name) as Class;
+ parent = p;
+ }
+ }
if (old_cl != null && old_cl.is_partial) {
if (cl.is_partial != old_cl.is_partial) {
Report.error (cl.source_reference, "conflicting partial and not partial
declarations of `%s'".printf (cl.name));
@@ -2984,6 +3039,11 @@ public class Vala.Parser : CodeVisitor {
cl.add_method (m);
}
+ if (partial_reparse) {
+ parent.add_class (cl);
+ return;
+ }
+
Symbol result = cl;
while (sym != null) {
sym = sym.inner;
@@ -2991,7 +3051,10 @@ public class Vala.Parser : CodeVisitor {
Symbol next = (sym != null ? new Namespace (sym.name, cl.source_reference) : parent);
if (result is Namespace) {
next.add_namespace ((Namespace) result);
- } else {
+ } else if (!partial_reparse && cl.is_partial) {
+ PartialInfo info = { parent, begin, attrs };
+ partials += info;
+ } else if (!cl.is_partial) {
next.add_class ((Class) result);
}
result = next;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]