From: Jürg Billeter Date: Fri, 7 Nov 2008 09:07:08 +0000 (+0000) Subject: Move element access checking to ElementAccess.check X-Git-Tag: VALA_0_5_2~117 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db5f3f9062a7dd32a41a37031835e4cecff30656;p=thirdparty%2Fvala.git Move element access checking to ElementAccess.check 2008-11-07 Jürg Billeter * vala/valaelementaccess.vala: * vala/valasemanticanalyzer.vala: Move element access checking to ElementAccess.check svn path=/trunk/; revision=1994 --- diff --git a/ChangeLog b/ChangeLog index f7103c010..ef673339b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-11-07 Jürg Billeter + + * vala/valaelementaccess.vala: + * vala/valasemanticanalyzer.vala: + + Move element access checking to ElementAccess.check + 2008-11-07 Jürg Billeter * vapigen/valagirparser.vala: diff --git a/vala/valaelementaccess.vala b/vala/valaelementaccess.vala index 640bd3e31..0734944d4 100644 --- a/vala/valaelementaccess.vala +++ b/vala/valaelementaccess.vala @@ -85,4 +85,127 @@ public class Vala.ElementAccess : Expression { } return container.is_pure (); } + + public override bool check (SemanticAnalyzer analyzer) { + if (checked) { + return !error; + } + + checked = true; + + container.accept (analyzer); + + if (container.value_type == null) { + /* don't proceed if a child expression failed */ + error = true; + return false; + } + + var container_type = container.value_type.data_type; + + if (container is MemberAccess && container.symbol_reference is Signal) { + // signal detail access + if (get_indices ().size != 1) { + error = true; + Report.error (source_reference, "Element access with more than one dimension is not supported for signals"); + return false; + } + get_indices ().get (0).target_type = analyzer.string_type.copy (); + } + + foreach (Expression index in get_indices ()) { + index.accept (analyzer); + } + + bool index_int_type_check = true; + + var pointer_type = container.value_type as PointerType; + + /* assign a value_type when possible */ + if (container.value_type is ArrayType) { + var array_type = (ArrayType) container.value_type; + value_type = array_type.element_type.copy (); + if (!lvalue) { + value_type.value_owned = false; + } + } else if (pointer_type != null && !pointer_type.base_type.is_reference_type_or_type_parameter ()) { + value_type = pointer_type.base_type.copy (); + } else if (container_type == analyzer.string_type.data_type) { + if (get_indices ().size != 1) { + error = true; + Report.error (source_reference, "Element access with more than one dimension is not supported for strings"); + return false; + } + + value_type = analyzer.unichar_type; + } else if (container_type != null && analyzer.list_type != null && analyzer.map_type != null && + (container_type.is_subtype_of (analyzer.list_type) || container_type.is_subtype_of (analyzer.map_type))) { + Gee.List indices = get_indices (); + if (indices.size != 1) { + error = true; + Report.error (source_reference, "Element access with more than one dimension is not supported for the specified type"); + return false; + } + Iterator indices_it = indices.iterator (); + indices_it.next (); + var index = indices_it.get (); + index_int_type_check = false; + + // lookup symbol in interface instead of class as implemented interface methods are not in VAPI files + Symbol get_sym = null; + if (container_type.is_subtype_of (analyzer.list_type)) { + get_sym = analyzer.list_type.scope.lookup ("get"); + } else if (container_type.is_subtype_of (analyzer.map_type)) { + get_sym = analyzer.map_type.scope.lookup ("get"); + } + var get_method = (Method) get_sym; + Gee.List get_params = get_method.get_parameters (); + Iterator get_params_it = get_params.iterator (); + get_params_it.next (); + var get_param = get_params_it.get (); + + var index_type = get_param.parameter_type; + if (index_type.type_parameter != null) { + index_type = analyzer.get_actual_type (container.value_type, get_method, get_param.parameter_type, this); + } + + if (!index.value_type.compatible (index_type)) { + error = true; + Report.error (source_reference, "index expression: Cannot convert from `%s' to `%s'".printf (index.value_type.to_string (), index_type.to_string ())); + return false; + } + + value_type = analyzer.get_actual_type (container.value_type, get_method, get_method.return_type, this).copy (); + if (lvalue) { + // get () returns owned value, set () accepts unowned value + value_type.value_owned = false; + } + } else if (container is MemberAccess && container.symbol_reference is Signal) { + index_int_type_check = false; + + symbol_reference = container.symbol_reference; + value_type = container.value_type; + } else { + error = true; + Report.error (source_reference, "The expression `%s' does not denote an Array".printf (container.value_type.to_string ())); + } + + if (index_int_type_check) { + /* check if the index is of type integer */ + foreach (Expression e in get_indices ()) { + /* don't proceed if a child expression failed */ + if (e.value_type == null) { + return false; + } + + /* check if the index is of type integer */ + if (!(e.value_type.data_type is Struct) || !((Struct) e.value_type.data_type).is_integer_type ()) { + error = true; + Report.error (e.source_reference, "Expression of integer type expected"); + } + } + } + + return !error; + } } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 4b37620a6..ecbd73683 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -56,12 +56,12 @@ public class Vala.SemanticAnalyzer : CodeVisitor { public DataType type_type; public Class object_type; public TypeSymbol initially_unowned_type; - DataType glist_type; - DataType gslist_type; - Class gerror_type; - DataType iterable_type; - Interface iterator_type; - Interface list_type; + public DataType glist_type; + public DataType gslist_type; + public Class gerror_type; + public DataType iterable_type; + public Interface iterator_type; + public Interface list_type; public Interface collection_type; public Interface map_type; @@ -1543,118 +1543,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } public override void visit_element_access (ElementAccess expr) { - expr.container.accept (this); - - if (expr.container.value_type == null) { - /* don't proceed if a child expression failed */ - expr.error = true; - return; - } - - var container_type = expr.container.value_type.data_type; - - if (expr.container is MemberAccess && expr.container.symbol_reference is Signal) { - // signal detail access - if (expr.get_indices ().size != 1) { - expr.error = true; - Report.error (expr.source_reference, "Element access with more than one dimension is not supported for signals"); - return; - } - expr.get_indices ().get (0).target_type = string_type.copy (); - } - - foreach (Expression index in expr.get_indices ()) { - index.accept (this); - } - - bool index_int_type_check = true; - - var pointer_type = expr.container.value_type as PointerType; - - /* assign a value_type when possible */ - if (expr.container.value_type is ArrayType) { - var array_type = (ArrayType) expr.container.value_type; - expr.value_type = array_type.element_type.copy (); - if (!expr.lvalue) { - expr.value_type.value_owned = false; - } - } else if (pointer_type != null && !pointer_type.base_type.is_reference_type_or_type_parameter ()) { - expr.value_type = pointer_type.base_type.copy (); - } else if (container_type == string_type.data_type) { - if (expr.get_indices ().size != 1) { - expr.error = true; - Report.error (expr.source_reference, "Element access with more than one dimension is not supported for strings"); - return; - } - - expr.value_type = unichar_type; - } else if (container_type != null && list_type != null && map_type != null && - (container_type.is_subtype_of (list_type) || container_type.is_subtype_of (map_type))) { - Gee.List indices = expr.get_indices (); - if (indices.size != 1) { - expr.error = true; - Report.error (expr.source_reference, "Element access with more than one dimension is not supported for the specified type"); - return; - } - Iterator indices_it = indices.iterator (); - indices_it.next (); - var index = indices_it.get (); - index_int_type_check = false; - - // lookup symbol in interface instead of class as implemented interface methods are not in VAPI files - Symbol get_sym = null; - if (container_type.is_subtype_of (list_type)) { - get_sym = list_type.scope.lookup ("get"); - } else if (container_type.is_subtype_of (map_type)) { - get_sym = map_type.scope.lookup ("get"); - } - var get_method = (Method) get_sym; - Gee.List get_params = get_method.get_parameters (); - Iterator get_params_it = get_params.iterator (); - get_params_it.next (); - var get_param = get_params_it.get (); - - var index_type = get_param.parameter_type; - if (index_type.type_parameter != null) { - index_type = get_actual_type (expr.container.value_type, get_method, get_param.parameter_type, expr); - } - - if (!index.value_type.compatible (index_type)) { - expr.error = true; - Report.error (expr.source_reference, "index expression: Cannot convert from `%s' to `%s'".printf (index.value_type.to_string (), index_type.to_string ())); - return; - } - - expr.value_type = get_actual_type (expr.container.value_type, get_method, get_method.return_type, expr).copy (); - if (expr.lvalue) { - // get () returns owned value, set () accepts unowned value - expr.value_type.value_owned = false; - } - } else if (expr.container is MemberAccess && expr.container.symbol_reference is Signal) { - index_int_type_check = false; - - expr.symbol_reference = expr.container.symbol_reference; - expr.value_type = expr.container.value_type; - } else { - expr.error = true; - Report.error (expr.source_reference, "The expression `%s' does not denote an Array".printf (expr.container.value_type.to_string ())); - } - - if (index_int_type_check) { - /* check if the index is of type integer */ - foreach (Expression e in expr.get_indices ()) { - /* don't proceed if a child expression failed */ - if (e.value_type == null) { - return; - } - - /* check if the index is of type integer */ - if (!(e.value_type.data_type is Struct) || !((Struct) e.value_type.data_type).is_integer_type ()) { - expr.error = true; - Report.error (e.source_reference, "Expression of integer type expected"); - } - } - } + expr.check (this); } public bool is_in_instance_method () {