vala r874 - in trunk: . gobject vala vapigen
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r874 - in trunk: . gobject vala vapigen
- Date: Mon, 21 Jan 2008 17:09:25 +0000 (GMT)
Author: juergbi
Date: Mon Jan 21 17:09:24 2008
New Revision: 874
URL: http://svn.gnome.org/viewvc/vala?rev=874&view=rev
Log:
2008-01-21 Juerg Billeter <j bitron ch>
* vala/valasemanticanalyzer.vala: improve generic type resolution, add
type checking for element type in foreach statement,
based on patch by Hans Vercammen, fixes bug 510852
* gobject/valaccodegenerator.vala,
gobject/valaccodegeneratormethod.vala, vapigen/valagidlparser.vala:
fix foreach statements
Modified:
trunk/ChangeLog
trunk/gobject/valaccodegenerator.vala
trunk/gobject/valaccodegeneratormethod.vala
trunk/vala/valasemanticanalyzer.vala
trunk/vapigen/valagidlparser.vala
Modified: trunk/gobject/valaccodegenerator.vala
==============================================================================
--- trunk/gobject/valaccodegenerator.vala (original)
+++ trunk/gobject/valaccodegenerator.vala Mon Jan 21 17:09:24 2008
@@ -787,11 +787,11 @@
}
if (stmt.ccodenode is CCodeFragment) {
- foreach (CCodeStatement cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
+ foreach (CCodeNode cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
cblock.add_statement (cstmt);
}
} else {
- cblock.add_statement ((CCodeStatement) stmt.ccodenode);
+ cblock.add_statement (stmt.ccodenode);
}
}
@@ -1431,11 +1431,11 @@
var cblock = new CCodeBlock ();
foreach (CodeNode body_stmt in section.get_statements ()) {
if (body_stmt.ccodenode is CCodeFragment) {
- foreach (CCodeStatement cstmt in ((CCodeFragment) body_stmt.ccodenode).get_children ()) {
+ foreach (CCodeNode cstmt in ((CCodeFragment) body_stmt.ccodenode).get_children ()) {
cblock.add_statement (cstmt);
}
} else {
- cblock.add_statement ((CCodeStatement) body_stmt.ccodenode);
+ cblock.add_statement (body_stmt.ccodenode);
}
}
@@ -1555,6 +1555,10 @@
CCodeExpression element_expr = new CCodeIdentifier ("*%s".printf (it_name));
+ var element_data_type = new DataType ();
+ element_data_type.data_type = arr.element_type;
+ element_expr = get_implicit_cast_expression (element_expr, element_data_type, stmt.type_reference);
+
if (stmt.type_reference.takes_ownership) {
var ma = new MemberAccess.simple (stmt.variable_name);
ma.static_type = stmt.type_reference;
@@ -1597,6 +1601,10 @@
CCodeExpression element_expr = new CCodeElementAccess (new CCodeIdentifier (collection_backup.name), new CCodeIdentifier (it_name));
+ var element_data_type = new DataType ();
+ element_data_type.data_type = arr.element_type;
+ element_expr = get_implicit_cast_expression (element_expr, element_data_type, stmt.type_reference);
+
if (stmt.type_reference.takes_ownership) {
var ma = new MemberAccess.simple (stmt.variable_name);
ma.static_type = stmt.type_reference;
@@ -1655,6 +1663,15 @@
CCodeExpression element_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "data");
+ if (collection_type.get_type_arguments ().size != 1) {
+ Report.error (stmt.source_reference, "internal error: missing generic type argument");
+ stmt.error = true;
+ return;
+ }
+
+ var element_data_type = collection_type.get_type_arguments ().get (0);
+ element_expr = get_implicit_cast_expression (element_expr, element_data_type, stmt.type_reference);
+
element_expr = convert_from_generic_pointer (element_expr, stmt.type_reference);
if (stmt.type_reference.takes_ownership) {
@@ -1710,6 +1727,8 @@
type_arg_it.next ();
var it_type = SemanticAnalyzer.get_actual_type (stmt.collection.static_type, it_method, type_arg_it.get (), stmt);
+ element_expr = get_implicit_cast_expression (element_expr, it_type, stmt.type_reference);
+
if (stmt.type_reference.takes_ownership && !it_type.takes_ownership) {
var ma = new MemberAccess.simple (stmt.variable_name);
ma.static_type = stmt.type_reference;
@@ -1767,7 +1786,7 @@
var local_vars = b.get_local_variables ();
foreach (VariableDeclarator decl in local_vars) {
- if (decl.active && decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
+ if (decl.active && decl.type_reference.data_type != null && decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
var ma = new MemberAccess.simple (decl.name);
ma.symbol_reference = decl;
cfrag.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (get_variable_cname (decl.name)), decl.type_reference, ma)));
Modified: trunk/gobject/valaccodegeneratormethod.vala
==============================================================================
--- trunk/gobject/valaccodegeneratormethod.vala (original)
+++ trunk/gobject/valaccodegeneratormethod.vala Mon Jan 21 17:09:24 2008
@@ -68,11 +68,11 @@
foreach (CodeNode stmt in m.body.get_statements ()) {
if (((ExpressionStatement) stmt).assigned_property ().set_accessor.construction) {
if (stmt.ccodenode is CCodeFragment) {
- foreach (CCodeStatement cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
+ foreach (CCodeNode cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
cblock.add_statement (cstmt);
}
} else {
- cblock.add_statement ((CCodeStatement) stmt.ccodenode);
+ cblock.add_statement (stmt.ccodenode);
}
}
}
@@ -82,11 +82,11 @@
foreach (CodeNode stmt in m.body.get_statements ()) {
if (!((ExpressionStatement) stmt).assigned_property ().set_accessor.construction) {
if (stmt.ccodenode is CCodeFragment) {
- foreach (CCodeStatement cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
+ foreach (CCodeNode cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
cblock.add_statement (cstmt);
}
} else {
- cblock.add_statement ((CCodeStatement) stmt.ccodenode);
+ cblock.add_statement (stmt.ccodenode);
}
}
}
Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala (original)
+++ trunk/vala/valasemanticanalyzer.vala Mon Jan 21 17:09:24 2008
@@ -937,9 +937,21 @@
stmt.add_local_variable (stmt.collection_variable_declarator);
stmt.collection_variable_declarator.active = true;
-
+
var collection_type = stmt.collection.static_type;
- if (iterable_type != null && collection_type.compatible (iterable_type)) {
+ var element_data_type = new DataType ();
+ bool need_type_check = false;
+
+ if (collection_type.is_array ()) {
+ var arr = (Array) collection_type.data_type;
+ element_data_type.data_type = arr.element_type;
+ need_type_check = true;
+ } else if (collection_type.compatible (glist_type) || collection_type.compatible (gslist_type)) {
+ if (collection_type.get_type_arguments ().size > 0) {
+ element_data_type = (DataType) collection_type.get_type_arguments ().get (0);
+ need_type_check = true;
+ }
+ } else if (iterable_type != null && collection_type.compatible (iterable_type)) {
stmt.iterator_variable_declarator = new VariableDeclarator ("%s_it".printf (stmt.variable_name));
stmt.iterator_variable_declarator.type_reference = new InterfaceType (iterator_type);
stmt.iterator_variable_declarator.type_reference.takes_ownership = true;
@@ -947,12 +959,32 @@
stmt.add_local_variable (stmt.iterator_variable_declarator);
stmt.iterator_variable_declarator.active = true;
- } else if (!(collection_type.is_array () || collection_type.compatible (glist_type) || collection_type.compatible (gslist_type))) {
+
+ var it_method = (Method) iterable_type.data_type.scope.lookup ("iterator");
+ if (it_method.return_type.get_type_arguments ().size > 0) {
+ var type_arg = it_method.return_type.get_type_arguments ().get (0);
+ if (type_arg.type_parameter != null) {
+ element_data_type = SemanticAnalyzer.get_actual_type (collection_type, it_method, type_arg, stmt);
+ } else {
+ element_data_type = type_arg;
+ }
+ need_type_check = true;
+ }
+ } else {
stmt.error = true;
Report.error (stmt.source_reference, "Collection not iterable");
return;
}
+ if (need_type_check && element_data_type != null) {
+ /* allow implicit upcasts ? */
+ if (!element_data_type.compatible (stmt.type_reference)) {
+ stmt.error = true;
+ Report.error (stmt.source_reference, "Foreach: Cannot convert from `%s' to `%s'".printf (element_data_type.to_string (), stmt.type_reference.to_string ()));
+ return;
+ }
+ }
+
stmt.tree_can_fail = stmt.collection.tree_can_fail || stmt.body.tree_can_fail;
}
@@ -1514,25 +1546,28 @@
}
// resolve generic return values
+ var ma = expr.call as MemberAccess;
if (ret_type.type_parameter != null) {
- if (!(expr.call is MemberAccess)) {
- Report.error (expr.source_reference, "internal error: unsupported generic return value");
- expr.error = true;
- return;
- }
- var ma = (MemberAccess) expr.call;
- if (ma.inner == null) {
- // TODO resolve generic return values within the type hierarchy if possible
- Report.error (expr.source_reference, "internal error: resolving generic return values within type hierarchy not supported yet");
- expr.error = true;
- return;
- } else {
+ if (ma != null && ma.inner != null) {
ret_type = get_actual_type (ma.inner.static_type, ma.symbol_reference, ret_type, expr);
if (ret_type == null) {
return;
}
}
}
+ Gee.List<DataType> resolved_type_args = new ArrayList<DataType> ();
+ foreach (DataType type_arg in ret_type.get_type_arguments ()) {
+ if (type_arg.type_parameter != null && ma != null && ma.inner != null) {
+ resolved_type_args.add (get_actual_type (ma.inner.static_type, ma.symbol_reference, type_arg, expr));
+ } else {
+ resolved_type_args.add (type_arg);
+ }
+ }
+ ret_type = ret_type.copy ();
+ ret_type.remove_all_type_arguments ();
+ foreach (DataType resolved_type_arg in resolved_type_args) {
+ ret_type.add_type_argument (resolved_type_arg);
+ }
if (mtype is MethodType) {
var m = ((MethodType) mtype).method_symbol;
Modified: trunk/vapigen/valagidlparser.vala
==============================================================================
--- trunk/vapigen/valagidlparser.vala (original)
+++ trunk/vapigen/valagidlparser.vala Mon Jan 21 17:09:24 2008
@@ -37,7 +37,7 @@
private Namespace current_namespace;
private Typesymbol current_data_type;
private Map<string,string> codenode_attributes_map;
- private Map<pointer,string> codenode_attributes_patterns;
+ private Map<PatternSpec*,string> codenode_attributes_patterns;
private Gee.Set<string> current_type_symbol_set;
private Map<string,Typesymbol> cname_type_map;
@@ -1421,7 +1421,7 @@
var colon_required = (null != codenode.chr (-1, ':'));
var pattern_specs = codenode_attributes_patterns.get_keys ();
- foreach (weak PatternSpec pattern in pattern_specs) {
+ foreach (PatternSpec* pattern in pattern_specs) {
var pspec = codenode_attributes_patterns[pattern];
if ((dot_required && null == pspec.chr (-1, '.')) ||
@@ -1429,7 +1429,7 @@
continue;
}
- if (pattern.match_string (codenode)) {
+ if (pattern->match_string (codenode)) {
return get_attributes (pspec);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]