[vala] Add support for properties in structs
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] Add support for properties in structs
- Date: Sat, 5 Sep 2009 17:29:32 +0000 (UTC)
commit 472db6e7c82ddc95fa0135652dc2481f9c53c6c4
Author: Jürg Billeter <j bitron ch>
Date: Sat Sep 5 18:16:07 2009 +0200
Add support for properties in structs
codegen/valaccodebasemodule.vala | 40 ++++++++++++++++++++++++++---
codegen/valaccodememberaccessmodule.vala | 22 ++++++++++++++++
vala/valacodewriter.vala | 1 +
vala/valaparser.vala | 2 +
vala/valastruct.vala | 35 ++++++++++++++++++++++++++
5 files changed, 95 insertions(+), 5 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index a5f628b..f701903 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1250,10 +1250,13 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
if (prop.binding == MemberBinding.INSTANCE) {
- var t = (ObjectTypeSymbol) prop.parent_symbol;
- var this_type = new ObjectType (t);
+ var t = (TypeSymbol) prop.parent_symbol;
+ var this_type = get_data_type_for_symbol (t);
generate_type_declaration (this_type, decl_space);
var cselfparam = new CCodeFormalParameter ("self", this_type.get_cname ());
+ if (t is Struct) {
+ cselfparam.type_name += "*";
+ }
function.add_parameter (cselfparam);
}
@@ -1295,7 +1298,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
acc.accept_children (codegen);
- var t = (ObjectTypeSymbol) prop.parent_symbol;
+ var t = (TypeSymbol) prop.parent_symbol;
if (acc.construction && !t.is_subtype_of (gobject_type)) {
Report.error (acc.source_reference, "construct properties require GLib.Object");
@@ -1319,8 +1322,11 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
}
- var this_type = new ObjectType (t);
+ var this_type = get_data_type_for_symbol (t);
var cselfparam = new CCodeFormalParameter ("self", this_type.get_cname ());
+ if (t is Struct) {
+ cselfparam.type_name += "*";
+ }
CCodeFormalParameter cvalueparam;
if (returns_real_struct) {
cvalueparam = new CCodeFormalParameter ("value", acc.value_type.get_cname () + "*");
@@ -3966,7 +3972,31 @@ internal class Vala.CCodeBaseModule : CCodeModule {
if (prop.binding == MemberBinding.INSTANCE) {
/* target instance is first argument */
- ccall.add_argument ((CCodeExpression) get_ccodenode (ma.inner));
+ var instance = (CCodeExpression) get_ccodenode (ma.inner);
+
+ if (prop.parent_symbol is Struct) {
+ // we need to pass struct instance by reference
+ var unary = instance as CCodeUnaryExpression;
+ if (unary != null && unary.operator == CCodeUnaryOperator.POINTER_INDIRECTION) {
+ // *expr => expr
+ instance = unary.inner;
+ } else if (instance is CCodeIdentifier || instance is CCodeMemberAccess) {
+ instance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance);
+ } else {
+ // if instance is e.g. a function call, we can't take the address of the expression
+ // (tmp = expr, &tmp)
+ var ccomma = new CCodeCommaExpression ();
+
+ var temp_var = get_temp_variable (ma.inner.target_type);
+ temp_vars.insert (0, temp_var);
+ ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), instance));
+ ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
+
+ instance = ccomma;
+ }
+ }
+
+ ccall.add_argument (instance);
}
if (prop.no_accessor_method) {
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index b002309..d698a03 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -244,6 +244,28 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
var ccall = new CCodeFunctionCall (new CCodeIdentifier (getter_cname));
if (prop.binding == MemberBinding.INSTANCE) {
+ if (prop.parent_symbol is Struct) {
+ // we need to pass struct instance by reference
+ var unary = pub_inst as CCodeUnaryExpression;
+ if (unary != null && unary.operator == CCodeUnaryOperator.POINTER_INDIRECTION) {
+ // *expr => expr
+ pub_inst = unary.inner;
+ } else if (pub_inst is CCodeIdentifier || pub_inst is CCodeMemberAccess) {
+ pub_inst = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, pub_inst);
+ } else {
+ // if instance is e.g. a function call, we can't take the address of the expression
+ // (tmp = expr, &tmp)
+ var ccomma = new CCodeCommaExpression ();
+
+ var temp_var = get_temp_variable (expr.inner.target_type);
+ temp_vars.insert (0, temp_var);
+ ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), pub_inst));
+ ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
+
+ pub_inst = ccomma;
+ }
+ }
+
ccall.add_argument (pub_inst);
}
diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala
index dbc1cb8..164a25a 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -362,6 +362,7 @@ public class Vala.CodeWriter : CodeVisitor {
}
visit_sorted (st.get_constants ());
visit_sorted (st.get_methods ());
+ visit_sorted (st.get_properties ());
current_scope = current_scope.parent_scope;
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 569bff4..fa5bc3d 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -2517,6 +2517,8 @@ public class Vala.Parser : CodeVisitor {
st.add_field ((Field) sym);
} else if (sym is Constant) {
st.add_constant ((Constant) sym);
+ } else if (sym is Property) {
+ st.add_property ((Property) sym);
} else {
Report.error (sym.source_reference, "unexpected declaration in struct");
}
diff --git a/vala/valastruct.vala b/vala/valastruct.vala
index e060d8c..17ed9ec 100644
--- a/vala/valastruct.vala
+++ b/vala/valastruct.vala
@@ -31,6 +31,7 @@ public class Vala.Struct : TypeSymbol {
private Gee.List<Constant> constants = new ArrayList<Constant> ();
private Gee.List<Field> fields = new ArrayList<Field> ();
private Gee.List<Method> methods = new ArrayList<Method> ();
+ private Gee.List<Property> properties = new ArrayList<Property> ();
private DataType _base_type = null;
private string cname;
@@ -210,6 +211,32 @@ public class Vala.Struct : TypeSymbol {
return new ReadOnlyList<Method> (methods);
}
+ /**
+ * Adds the specified property as a member to this struct.
+ *
+ * @param prop a property
+ */
+ public void add_property (Property prop) {
+ properties.add (prop);
+ scope.add (prop.name, prop);
+
+ prop.this_parameter = new FormalParameter ("this", SemanticAnalyzer.get_data_type_for_symbol (this));
+ prop.scope.add (prop.this_parameter.name, prop.this_parameter);
+
+ if (prop.field != null) {
+ add_field (prop.field);
+ }
+ }
+
+ /**
+ * Returns a copy of the list of properties.
+ *
+ * @return list of properties
+ */
+ public Gee.List<Property> get_properties () {
+ return new ReadOnlyList<Property> (properties);
+ }
+
public override void accept (CodeVisitor visitor) {
visitor.visit_struct (this);
}
@@ -234,6 +261,10 @@ public class Vala.Struct : TypeSymbol {
foreach (Method m in methods) {
m.accept (visitor);
}
+
+ foreach (Property prop in properties) {
+ prop.accept (visitor);
+ }
}
public override string get_cname (bool const_type = false) {
@@ -758,6 +789,10 @@ public class Vala.Struct : TypeSymbol {
m.check (analyzer);
}
+ foreach (Property prop in properties) {
+ prop.check (analyzer);
+ }
+
if (!external && !external_package && base_type == null && get_fields ().size == 0
&& !is_boolean_type () && !is_integer_type () && !is_floating_type ()) {
error = true;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]