[vala/wip/issue/767] WIP Extend silent-cast support to type with known type signatures
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/issue/767] WIP Extend silent-cast support to type with known type signatures
- Date: Thu, 21 Mar 2019 22:20:10 +0000 (UTC)
commit 0f44bd9134703f92e12e8c7b07e12f18f27c299c
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Thu Mar 21 22:19:26 2019 +0100
WIP Extend silent-cast support to type with known type signatures
codegen/valagvariantmodule.vala | 75 ++++++++++++++++++++-------
tests/semantic/cast-gvariant-unsupported.test | 2 +-
vala/valacastexpression.vala | 4 +-
3 files changed, 58 insertions(+), 23 deletions(-)
---
diff --git a/codegen/valagvariantmodule.vala b/codegen/valagvariantmodule.vala
index 223302aa0..55bd9c59f 100644
--- a/codegen/valagvariantmodule.vala
+++ b/codegen/valagvariantmodule.vala
@@ -160,32 +160,67 @@ public class Vala.GVariantModule : GAsyncModule {
push_function (cfunc);
+ CCodeExpression type_expr = null;
+ BasicTypeInfo basic_type = {};
+ bool is_basic_type = false;
+ if (expr.is_silent_cast) {
+ var signature = target_type.get_type_signature ();
+ is_basic_type = get_basic_type_info (signature, out basic_type);
+ var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_is_of_type"));
+ ccheck.add_argument (new CCodeIdentifier ("value"));
+ if (is_basic_type) {
+ type_expr = new CCodeIdentifier ("G_VARIANT_TYPE_" +
basic_type.type_name.ascii_up ());
+ } else {
+ var gvariant_type_type = new ObjectType ((Class) root_symbol.scope.lookup
("GLib").scope.lookup ("VariantType"));
+ var type_temp = get_temp_variable (gvariant_type_type, true, expr, true);
+ emit_temp_var (type_temp);
+ type_expr = new CCodeFunctionCall (new CCodeIdentifier
("g_variant_type_new"));
+ ((CCodeFunctionCall) type_expr).add_argument (new CCodeIdentifier
("\"%s\"".printf (signature)));
+ store_value (get_local_cvalue (type_temp), new GLibValue (gvariant_type_type,
type_expr), expr.source_reference);
+ type_expr = get_variable_cexpression (type_temp.name);
+ }
+ ccheck.add_argument (type_expr);
+ ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.AND, new
CCodeIdentifier ("value"), ccheck));
+ }
+
CCodeExpression func_result = deserialize_expression (target_type, new CCodeIdentifier
("value"), new CCodeIdentifier ("*result"));
- if (target_type.is_real_non_null_struct_type ()) {
- ccode.add_assignment (new CCodeIdentifier ("*result"), func_result);
- } else {
- if (expr.is_silent_cast && SemanticAnalyzer.is_gvariant_basic_type (target_type)) {
- var ccheck = new CCodeFunctionCall (new CCodeIdentifier
("g_variant_is_of_type"));
- ccheck.add_argument (new CCodeIdentifier ("value"));
- BasicTypeInfo basic_type;
- get_basic_type_info (target_type.get_type_signature (), out basic_type);
- ccheck.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_" +
basic_type.type_name.ascii_up ()));
- ccode.open_if (ccheck);
- if (basic_type.is_string) {
- ccode.add_return (func_result);
+
+ if (expr.is_silent_cast) {
+ if (is_basic_type && basic_type.is_string) {
+ ccode.add_return (func_result);
+ } else {
+ if (!is_basic_type) {
+ var type_free = new CCodeFunctionCall (new CCodeIdentifier
("g_variant_type_free"));
+ type_free.add_argument (type_expr);
+ ccode.add_expression (type_free);
+ }
+ var temp_type = expr.target_type.copy ();
+ temp_type.nullable = false;
+ var temp_value = create_temp_value (temp_type, false, expr);
+ store_value (temp_value, new GLibValue (temp_type, func_result),
expr.source_reference);
+ if (target_type.is_real_non_null_struct_type ()) {
+ ccode.add_assignment (new CCodeIdentifier ("*result"), get_cvalue_
(transform_value (temp_value, expr.target_type, expr)));
} else {
- var temp_type = expr.target_type.copy ();
- temp_type.nullable = false;
- var temp_value = create_temp_value (temp_type, false, expr);
- store_value (temp_value, new GLibValue (temp_type, func_result),
expr.source_reference);
ccode.add_return (get_cvalue_ (transform_value (temp_value,
expr.target_type, expr)));
}
- ccode.add_else ();
- ccode.add_return (new CCodeConstant ("NULL"));
- ccode.close ();
+ }
+
+ ccode.add_else ();
+ if (!is_basic_type) {
+ var type_free = new CCodeFunctionCall (new CCodeIdentifier
("g_variant_type_free"));
+ type_free.add_argument (type_expr);
+ ccode.add_expression (type_free);
+ }
+ if (target_type.is_real_non_null_struct_type ()) {
+ ccode.add_assignment (new CCodeIdentifier ("*result"), new CCodeConstant
("NULL"));
} else {
- ccode.add_return (func_result);
+ ccode.add_return (new CCodeConstant ("NULL"));
}
+ ccode.close ();
+ } else if (target_type.is_real_non_null_struct_type ()) {
+ ccode.add_assignment (new CCodeIdentifier ("*result"), func_result);
+ } else {
+ ccode.add_return (func_result);
}
pop_function ();
diff --git a/tests/semantic/cast-gvariant-unsupported.test b/tests/semantic/cast-gvariant-unsupported.test
index 80abaac67..2e4ed2d3e 100644
--- a/tests/semantic/cast-gvariant-unsupported.test
+++ b/tests/semantic/cast-gvariant-unsupported.test
@@ -2,5 +2,5 @@ Invalid Code
void main () {
Variant? v = null;
- string[]? array = v as string[];
+ Object? array = v as Object;
}
diff --git a/vala/valacastexpression.vala b/vala/valacastexpression.vala
index e1a4dc7ab..63e356155 100644
--- a/vala/valacastexpression.vala
+++ b/vala/valacastexpression.vala
@@ -184,8 +184,8 @@ public class Vala.CastExpression : Expression {
&& is_gvariant (context, inner.value_type) && !is_gvariant (context, value_type)) {
// GVariant unboxing returns owned value
value_type.value_owned = true;
- if (is_silent_cast && !SemanticAnalyzer.is_gvariant_basic_type (value_type)) {
- Report.error (source_reference, "Silent casts of `GLib.Variant' is only
supported for basic types");
+ if (value_type.get_type_signature () == null) {
+ Report.error (source_reference, "Casting of `GLib.Variant' to `%s' is not
supported".printf (value_type.to_qualified_string ()));
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]