From e1016f87892f2f3aa4d681620cc0ece9bbc151e2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=BCrg=20Billeter?= Date: Tue, 27 Feb 2007 22:42:50 +0000 Subject: [PATCH] mark source_reference as construction property to allow access in Array MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 2007-02-27 Jürg Billeter * vala/valacodenode.vala: mark source_reference as construction property to allow access in Array constructor * vala/valaarraylengthfield.vala: the Array.length field * vala/valaarrayresizemethod.vala: the Array.resize method * vala/valaarray.vala: support arrays of generic type parameters, add length field, add resize method * vala/valatypereference.vala: make source reference optional * vala/valatypeparameter.vala, vala/valasymbolresolver.vala, vala/valasemanticanalyzer.vala: support arrays of generic type parameters * vala/valadatatype.vala, vala/valacodegenerator.vala: support Array.length field and Array.resize method * vala/Makefile.am: update svn path=/trunk/; revision=203 --- vala/ChangeLog | 16 +++++++++ vala/vala/Makefile.am | 6 ++++ vala/vala/valaarray.vala | 65 +++++++++++++++++++++++++++++++----- vala/vala/valaarraylengthfield.vala | 46 +++++++++++++++++++++++++ vala/vala/valaarrayresizemethod.vala | 53 +++++++++++++++++++++++++++++ vala/vala/valacodegenerator.vala | 7 ++++ vala/vala/valacodenode.vala | 4 +-- vala/vala/valadatatype.vala | 13 ++++++-- vala/vala/valasemanticanalyzer.vala | 6 +++- vala/vala/valasymbolresolver.vala | 16 ++++++--- vala/vala/valatypeparameter.vala | 37 +++++++++++++++++++- vala/vala/valatypereference.vala | 4 +-- 12 files changed, 250 insertions(+), 23 deletions(-) create mode 100644 vala/vala/valaarraylengthfield.vala create mode 100644 vala/vala/valaarrayresizemethod.vala diff --git a/vala/ChangeLog b/vala/ChangeLog index 5459746..bbca43a 100644 --- a/vala/ChangeLog +++ b/vala/ChangeLog @@ -1,5 +1,21 @@ 2007-02-27 Jürg Billeter + * vala/valacodenode.vala: mark source_reference as construction property + to allow access in Array constructor + * vala/valaarraylengthfield.vala: the Array.length field + * vala/valaarrayresizemethod.vala: the Array.resize method + * vala/valaarray.vala: support arrays of generic type parameters, add + length field, add resize method + * vala/valatypereference.vala: make source reference optional + * vala/valatypeparameter.vala, vala/valasymbolresolver.vala, + vala/valasemanticanalyzer.vala: support arrays of generic type + parameters + * vala/valadatatype.vala, vala/valacodegenerator.vala: support + Array.length field and Array.resize method + * vala/Makefile.am: update + +2007-02-27 Jürg Billeter + * vala/parser.y: accept interfaces with base types 2007-02-26 Jürg Billeter diff --git a/vala/vala/Makefile.am b/vala/vala/Makefile.am index 4e6fe63..d54295e 100644 --- a/vala/vala/Makefile.am +++ b/vala/vala/Makefile.am @@ -22,6 +22,12 @@ libvala_la_SOURCES = \ valaarraycreationexpression.c \ valaarraycreationexpression.h \ valaarraycreationexpression.vala \ + valaarraylengthfield.c \ + valaarraylengthfield.h \ + valaarraylengthfield.vala \ + valaarrayresizemethod.c \ + valaarrayresizemethod.h \ + valaarrayresizemethod.vala \ valaassignment.c \ valaassignment.h \ valaassignment.vala \ diff --git a/vala/vala/valaarray.vala b/vala/vala/valaarray.vala index 7becec2..b46c8c3 100644 --- a/vala/vala/valaarray.vala +++ b/vala/vala/valaarray.vala @@ -1,6 +1,6 @@ /* valatype.vala * - * Copyright (C) 2006 Raffaele Sandrini + * Copyright (C) 2006-2007 Raffaele Sandrini, Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,6 +18,7 @@ * * Author: * Raffaele Sandrini + * Jürg Billeter */ using GLib; @@ -30,7 +31,12 @@ public class Vala.Array : DataType { /** * DataType of which this is an array of. */ - public DataType! element_type { get; set construct; } + public DataType element_type { get; set construct; } + + /** + * TypeParameter of which this is an array of. + */ + public TypeParameter element_type_parameter { get; set construct; } /** * The rank of this array. @@ -39,9 +45,24 @@ public class Vala.Array : DataType { private string cname; - public construct (DataType _element_type, int _rank) { + private ArrayLengthField length_field; + + private ArrayResizeMethod resize_method; + + public construct (DataType! _element_type, int _rank, SourceReference! _source_reference) { rank = _rank; element_type = _element_type; + source_reference = _source_reference; + + if (_rank < 1) { + Report.error (null, "internal: attempt to create an array with rank smaller than 1"); + } + } + + public construct with_type_parameter (TypeParameter! _element_type_parameter, int _rank, SourceReference! _source_reference) { + rank = _rank; + element_type_parameter = _element_type_parameter; + source_reference = _source_reference; if (_rank < 1) { Report.error (null, "internal: attempt to create an array with rank smaller than 1"); @@ -49,7 +70,7 @@ public class Vala.Array : DataType { } Array () { - /* FIXME: this implementation raises compiler bugs + /* FIXME: this implementation reveals compiler bugs string commas = ""; int i = rank - 1; @@ -61,12 +82,22 @@ public class Vala.Array : DataType { name = "%s[%s]".printf (element_type.name, commas); */ int i = rank - 1; - name = "%s[".printf (element_type.name); + if (element_type != null) { + name = "%s[".printf (element_type.name); + } else { + name = "%s[".printf (element_type_parameter.name); + } while (i > 0) { name = "%s,".printf (name); i--; } name = "%s]".printf (name); + + length_field = new ArrayLengthField (source_reference); + length_field.symbol = new Symbol (length_field); + + resize_method = new ArrayResizeMethod (source_reference); + resize_method.symbol = new Symbol (resize_method); } /** @@ -76,10 +107,14 @@ public class Vala.Array : DataType { */ public override string get_cname (bool const_type = false) { if (cname == null) { - if (element_type.is_reference_type ()) { - cname = "%s*".printf (element_type.get_cname ()); + if (element_type != null) { + if (element_type.is_reference_type ()) { + cname = "%s*".printf (element_type.get_cname ()); + } else { + cname = element_type.get_cname (); + } } else { - cname = element_type.get_cname (); + cname = "gpointer"; } } @@ -141,7 +176,11 @@ public class Vala.Array : DataType { * @return list of C header filenames for this data type */ public override ref List get_cheader_filenames () { - return element_type.get_cheader_filenames (); + if (element_type != null) { + return element_type.get_cheader_filenames (); + } else { + return null; + } } public override string get_marshaller_type_name () { @@ -155,4 +194,12 @@ public class Vala.Array : DataType { public override string get_set_value_function () { return "g_value_set_pointer"; } + + public ArrayLengthField get_length_field () { + return length_field; + } + + public ArrayResizeMethod get_resize_method () { + return resize_method; + } } diff --git a/vala/vala/valaarraylengthfield.vala b/vala/vala/valaarraylengthfield.vala new file mode 100644 index 0000000..37e3161 --- /dev/null +++ b/vala/vala/valaarraylengthfield.vala @@ -0,0 +1,46 @@ +/* valaarraylengthfield.vala + * + * Copyright (C) 2007 Jürg Billeter + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: + * Jürg Billeter + */ + +using GLib; + +/** + * Represents the Array.length field. + */ +public class Vala.ArrayLengthField : Field { + ArrayLengthField () { + access = MemberAccessibility.PUBLIC; + + var root_symbol = source_reference.file.context.get_root (); + type_reference.data_type = (DataType) root_symbol.lookup ("int").node; + } + + /** + * Creates a new array length field. + * + * @return newly created field + */ + public construct (SourceReference! source) { + name = "length"; + type_reference = new TypeReference (); + source_reference = source; + } +} diff --git a/vala/vala/valaarrayresizemethod.vala b/vala/vala/valaarrayresizemethod.vala new file mode 100644 index 0000000..fe0915c --- /dev/null +++ b/vala/vala/valaarrayresizemethod.vala @@ -0,0 +1,53 @@ +/* valaarrayresizemethod.vala + * + * Copyright (C) 2007 Jürg Billeter + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: + * Jürg Billeter + */ + +using GLib; + +/** + * Represents the Array.resize method. + */ +public class Vala.ArrayResizeMethod : Method { + ArrayResizeMethod () { + access = MemberAccessibility.PUBLIC; + + set_cname ("g_renew"); + + var root_symbol = source_reference.file.context.get_root (); + var int_type = new TypeReference (); + int_type.data_type = (DataType) root_symbol.lookup ("int").node; + + add_parameter (new FormalParameter ("length", int_type)); + + returns_modified_pointer = true; + } + + /** + * Creates a new array resize method. + * + * @return newly created method + */ + public construct (SourceReference! _source_reference) { + name = "resize"; + return_type = new TypeReference (); + source_reference = _source_reference; + } +} diff --git a/vala/vala/valacodegenerator.vala b/vala/vala/valacodegenerator.vala index 198d4e5..46c1bb4 100644 --- a/vala/vala/valacodegenerator.vala +++ b/vala/vala/valacodegenerator.vala @@ -2565,6 +2565,8 @@ public class Vala.CodeGenerator : CodeVisitor { } else { expr.ccodenode = new CCodeIdentifier (m.base_method.get_cname ()); } + } else if (expr.symbol_reference.node is ArrayLengthField) { + expr.ccodenode = get_array_length_cexpression (expr.inner, 1); } else if (expr.symbol_reference.node is Field) { var f = (Field) expr.symbol_reference.node; if (f.instance) { @@ -2865,6 +2867,11 @@ public class Vala.CodeGenerator : CodeVisitor { } } + if (m is ArrayResizeMethod) { + var array = (Array) m.symbol.parent_symbol.node; + ccall.add_argument (new CCodeIdentifier (array.get_cname ())); + } + /* explicitly use strong reference as ccall gets unrefed * at end of inner block */ diff --git a/vala/vala/valacodenode.vala b/vala/vala/valacodenode.vala index 56514a8..22a0309 100644 --- a/vala/vala/valacodenode.vala +++ b/vala/vala/valacodenode.vala @@ -1,6 +1,6 @@ /* valacodenode.vala * - * Copyright (C) 2006 Jürg Billeter + * Copyright (C) 2006-2007 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -43,7 +43,7 @@ public abstract class Vala.CodeNode { * References the location in the source file where this code node has * been written. */ - public SourceReference source_reference { get; set; } + public SourceReference source_reference { get; set construct; } /** * Contains all attributes that have been specified for this code node. diff --git a/vala/vala/valadatatype.vala b/vala/vala/valadatatype.vala index 56575c9..15ce343 100644 --- a/vala/vala/valadatatype.vala +++ b/vala/vala/valadatatype.vala @@ -1,6 +1,6 @@ /* valatype.vala * - * Copyright (C) 2006 Jürg Billeter, Raffaele Sandrini + * Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -47,7 +47,8 @@ public abstract class Vala.DataType : CodeNode { public weak Namespace @namespace; private List cheader_filenames; - /* holds the array types of this type; each rank is a speperate one */ + + /* holds the array types of this type; each rank is a separate one */ /* FIXME: uses string because int does not work as key yet */ private HashTable array_types = new HashTable.full (str_hash, str_equal, g_free, g_object_unref); @@ -229,10 +230,16 @@ public abstract class Vala.DataType : CodeNode { Array array_type = (Array) array_types.lookup (rank.to_string ()); if (array_type == null) { - var new_array_type = new Array (this, rank); + var new_array_type = new Array (this, rank, source_reference); /* create a new Symbol */ new_array_type.symbol = new Symbol (new_array_type); this.symbol.parent_symbol.add (new_array_type.name, new_array_type.symbol); + + /* add internal length field */ + new_array_type.symbol.add (new_array_type.get_length_field ().name, new_array_type.get_length_field ().symbol); + /* add internal resize method */ + new_array_type.symbol.add (new_array_type.get_resize_method ().name, new_array_type.get_resize_method ().symbol); + /* link the array type to the same source as the container type */ new_array_type.source_reference = this.source_reference; /* link the namespace */ diff --git a/vala/vala/valasemanticanalyzer.vala b/vala/vala/valasemanticanalyzer.vala index 5d32d39..707e0f6 100644 --- a/vala/vala/valasemanticanalyzer.vala +++ b/vala/vala/valasemanticanalyzer.vala @@ -640,7 +640,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } expr.static_type = expr.element_type.copy (); - expr.static_type.data_type = expr.element_type.data_type.get_array (expr.rank); + if (expr.element_type.data_type != null) { + expr.static_type.data_type = expr.element_type.data_type.get_array (expr.rank); + } else { + expr.static_type.data_type = expr.element_type.type_parameter.get_array (expr.rank); + } expr.static_type.transfers_ownership = true; expr.static_type.takes_ownership = true; diff --git a/vala/vala/valasymbolresolver.vala b/vala/vala/valasymbolresolver.vala index ec70182..6ffe73c 100644 --- a/vala/vala/valasymbolresolver.vala +++ b/vala/vala/valasymbolresolver.vala @@ -1,6 +1,6 @@ /* valasymbolresolver.vala * - * Copyright (C) 2006 Jürg Billeter + * Copyright (C) 2006-2007 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -195,11 +195,17 @@ public class Vala.SymbolResolver : CodeVisitor { if (type.array_rank > 0) { var element_type = new TypeReference (); element_type.data_type = type.data_type; - if (type.data_type != null && type.data_type.is_reference_type ()) { - element_type.takes_ownership = true; - } + element_type.type_parameter = type.type_parameter; - type.data_type = type.data_type.get_array (type.array_rank); + if (type.data_type != null) { + if (type.data_type.is_reference_type ()) { + element_type.takes_ownership = true; + } + type.data_type = element_type.data_type.get_array (type.array_rank); + } else { + type.data_type = element_type.type_parameter.get_array (type.array_rank); + type.type_parameter = null; + } type.add_type_argument (element_type); } diff --git a/vala/vala/valatypeparameter.vala b/vala/vala/valatypeparameter.vala index e92d0ad..1bad1cf 100644 --- a/vala/vala/valatypeparameter.vala +++ b/vala/vala/valatypeparameter.vala @@ -1,6 +1,6 @@ /* valatypeparameter.vala * - * Copyright (C) 2006 Jürg Billeter + * Copyright (C) 2006-2007 Jürg Billeter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -36,6 +36,10 @@ public class Vala.TypeParameter : CodeNode { */ public weak DataType type; + /* holds the array types of this type; each rank is a separate one */ + /* FIXME: uses string because int does not work as key yet */ + private HashTable array_types = new HashTable.full (str_hash, str_equal, g_free, g_object_unref); + /** * Creates a new generic type parameter. * @@ -51,4 +55,35 @@ public class Vala.TypeParameter : CodeNode { public override void accept (CodeVisitor! visitor) { visitor.visit_type_parameter (this); } + + /** + * Returns the array type for elements of this type parameter. + * + * @param rank the rank the array should be of + * @return array type for this type parameter + */ + public Array! get_array (int rank) { + Array array_type = (Array) array_types.lookup (rank.to_string ()); + + if (array_type == null) { + var new_array_type = new Array.with_type_parameter (this, rank, source_reference); + /* create a new Symbol */ + new_array_type.symbol = new Symbol (new_array_type); + this.symbol.parent_symbol.add (new_array_type.name, new_array_type.symbol); + + /* add internal length field */ + new_array_type.symbol.add (new_array_type.get_length_field ().name, new_array_type.get_length_field ().symbol); + /* add internal resize method */ + new_array_type.symbol.add (new_array_type.get_resize_method ().name, new_array_type.get_resize_method ().symbol); + + /* link the array type to the same source as the container type */ + new_array_type.source_reference = this.source_reference; + + array_types.insert (rank.to_string (), new_array_type); + + array_type = new_array_type; + } + + return array_type; + } } diff --git a/vala/vala/valatypereference.vala b/vala/vala/valatypereference.vala index f2dca2f..6d2ff04 100644 --- a/vala/vala/valatypereference.vala +++ b/vala/vala/valatypereference.vala @@ -1,6 +1,6 @@ /* valatypereference.vala * - * Copyright (C) 2006 Jürg Billeter, Raffaele Sandrini + * Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -114,7 +114,7 @@ public class Vala.TypeReference : CodeNode { * @param source reference to source code * @return newly created type reference */ - public construct from_name (string ns, string! type, SourceReference source) { + public construct from_name (string ns, string! type, SourceReference source = null) { namespace_name = ns; type_name = type; source_reference = source; -- 2.7.4