Commit e5f72479 authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

add is_null property fix type analysis in conditional and parenthesized

2007-04-12  Jürg Billeter  <j@bitron.ch>

	* vala/valatypereference.vala: add is_null property
	* vala/valasemanticanalyzer.vala: fix type analysis in conditional and
	  parenthesized expressions, fixes bug 428368
	* vapi/glib-2.0.vala: don't mark GLib.Object and GLib.InitiallyUnowned
	  as abstract

svn path=/trunk/; revision=284
parent e4e2e3ad
2007-04-12 Jürg Billeter <j@bitron.ch>
* vala/valatypereference.vala: add is_null property
* vala/valasemanticanalyzer.vala: fix type analysis in conditional and
parenthesized expressions, fixes bug 428368
* vapi/glib-2.0.vala: don't mark GLib.Object and GLib.InitiallyUnowned
as abstract
2007-04-12 Jürg Billeter <j@bitron.ch>
* vala/valacodegenerator.vala: fix warning when using interface
......
......@@ -1000,7 +1000,9 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
public override void visit_parenthesized_expression (ParenthesizedExpression! expr) {
expr.static_type = expr.inner.static_type;
expr.static_type = expr.inner.static_type.copy ();
// don't call g_object_ref_sink on inner and outer expression
expr.static_type.floating_reference = false;
}
private DataType find_parent_type (Symbol sym) {
......@@ -1871,16 +1873,130 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
expr.static_type = bool_type;
}
private TypeReference compute_common_base_type (List<TypeReference> types) {
bool null_found = false;
bool class_or_iface_found = false;
bool type_param_found = false;
bool ref_struct_found = false;
bool val_struct_found = false;
bool enum_found = false;
bool callback_found = false;
TypeReference base_type = null;
TypeReference last_type = null;
foreach (TypeReference type in types) {
last_type = type;
if (type.error) {
base_type = new TypeReference ();
base_type.error = true;
return base_type;
}
if (type.data_type == null && type.type_parameter == null) {
if (!null_found) {
null_found = true;
if (val_struct_found || enum_found) {
base_type.error = true;
break;
}
}
} else if (type.data_type is Class || type.data_type is Interface) {
if (!class_or_iface_found) {
class_or_iface_found = true;
if (type_param_found || ref_struct_found || val_struct_found || enum_found || callback_found) {
base_type.error = true;
break;
}
}
} else if (type.type_parameter != null) {
if (!type_param_found) {
type_param_found = true;
if (class_or_iface_found || ref_struct_found || val_struct_found || enum_found || callback_found) {
base_type.error = true;
break;
}
}
} else if (type.data_type is Struct) {
var st = (Struct) type.data_type;
if (st.is_reference_type ()) {
if (!ref_struct_found) {
ref_struct_found = true;
if (class_or_iface_found || type_param_found || val_struct_found || enum_found || callback_found) {
base_type.error = true;
break;
}
}
} else {
if (!val_struct_found) {
val_struct_found = true;
if (class_or_iface_found || type_param_found || ref_struct_found || enum_found || callback_found) {
base_type.error = true;
break;
}
}
}
} else if (type.data_type is Enum) {
if (!enum_found) {
enum_found = true;
if (class_or_iface_found || type_param_found || ref_struct_found || val_struct_found) {
base_type.error = true;
break;
}
}
} else if (type.data_type is Callback) {
if (!callback_found) {
callback_found = true;
if (class_or_iface_found || type_param_found || ref_struct_found || val_struct_found || enum_found) {
base_type.error = true;
break;
}
}
} else {
base_type = new TypeReference ();
base_type.error = true;
Report.error (type.source_reference, "internal error: unsupported type `%s'".printf (type.to_string ()));
return base_type;
}
if (base_type == null) {
base_type = new TypeReference ();
base_type.data_type = type.data_type;
base_type.type_parameter = type.type_parameter;
base_type.non_null = type.non_null;
base_type.is_null = type.is_null;
base_type.transfers_ownership = type.transfers_ownership;
} else {
if (base_type.data_type != type.data_type) {
if (is_type_compatible (type, base_type)) {
} else if (is_type_compatible (base_type, type)) {
base_type.data_type = type.data_type;
} else {
base_type.error = true;
break;
}
}
base_type.non_null = base_type.non_null && type.non_null;
base_type.is_null = base_type.is_null && type.is_null;
// if one subexpression transfers ownership, all subexpressions must transfer ownership
// FIXME add ref calls to subexpressions that don't transfer ownership
base_type.transfers_ownership = base_type.transfers_ownership || type.transfers_ownership;
}
}
if (base_type != null && base_type.error) {
Report.error (last_type.source_reference, "`%s' is incompatible with `%s'".printf (last_type.to_string (), base_type.to_string ()));
}
return base_type;
}
public override void visit_conditional_expression (ConditionalExpression! expr) {
if (expr.condition.static_type.data_type != bool_type.data_type) {
expr.error = true;
Report.error (expr.condition.source_reference, "Condition must be boolean");
return;
}
/* FIXME: use greatest lower bound in the type hierarchy */
/* FIXME: support memory management */
expr.static_type = expr.true_expression.static_type;
List<TypeReference> types;
types.append (expr.true_expression.static_type);
types.append (expr.false_expression.static_type);
expr.static_type = compute_common_base_type (types);
}
private ref string get_lambda_name () {
......
......@@ -56,6 +56,11 @@ public class Vala.TypeReference : CodeNode {
*/
public bool non_null { get; set; }
/**
* Specifies that the expression is known to be null.
*/
public bool is_null { get; set; }
/**
* The referred data type.
*/
......
......@@ -561,7 +561,7 @@ namespace GLib {
}
[CCode (cheader_filename = "glib-object.h")]
public abstract class Object {
public class Object {
[CCode (cname = "G_TYPE_FROM_INSTANCE")]
public Type get_type ();
public Object @ref ();
......@@ -569,7 +569,7 @@ namespace GLib {
public Object ref_sink ();
}
public abstract class InitiallyUnowned : Object {
public class InitiallyUnowned : Object {
}
public /* static */ interface Boxed<G> {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment