Commit 846d6165 authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

remove Array class, arrays are not type symbols

2008-03-14  Juerg Billeter  <j@bitron.ch>

	* vala/Makefile.am, vala/valaarraytype.vala, vala/valadatatype.vala,
	  vala/valamember.vala, vala/valasemanticanalyzer.vala,
	  vala/valasymbolresolver.vala, vala/valatypeparameter.vala,
	  vala/valatypesymbol.vala, gobject/valaccodegenerator.vala,
	  gobject/valaccodegeneratorinvocationexpression.vala,
	  gobject/valaccodegeneratormethod.vala: remove Array class, arrays
	  are not type symbols

svn path=/trunk/; revision=1124
parent 543cf141
2008-03-14 Jürg Billeter <j@bitron.ch>
* vala/Makefile.am, vala/valaarraytype.vala, vala/valadatatype.vala,
vala/valamember.vala, vala/valasemanticanalyzer.vala,
vala/valasymbolresolver.vala, vala/valatypeparameter.vala,
vala/valatypesymbol.vala, gobject/valaccodegenerator.vala,
gobject/valaccodegeneratorinvocationexpression.vala,
gobject/valaccodegeneratormethod.vala: remove Array class, arrays
are not type symbols
2008-03-12 Jürg Billeter <j@bitron.ch>
* vapi/packages/gtk+-2.0/: fix gtk_get_option_group binding
......
......@@ -1125,6 +1125,9 @@ public class Vala.CCodeGenerator : CodeGenerator {
} else if (type.type_parameter != null && current_type_symbol is Class) {
string func_name = "%s_dup_func".printf (type.type_parameter.name.down ());
return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
} else if (type is ArrayType) {
Report.error (type.source_reference, "internal error: duplicating %s instances not yet supported".printf (type.to_string ()));
return null;
} else {
return new CCodeConstant ("NULL");
}
......@@ -1146,6 +1149,8 @@ public class Vala.CCodeGenerator : CodeGenerator {
} else if (type.type_parameter != null && current_type_symbol is Class) {
string func_name = "%s_destroy_func".printf (type.type_parameter.name.down ());
return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
} else if (type is ArrayType) {
return new CCodeIdentifier ("g_free");
} else if (type is PointerType) {
return new CCodeIdentifier ("g_free");
} else {
......@@ -1162,7 +1167,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
*/
var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, cvar, new CCodeConstant ("NULL"));
if (type.data_type == null) {
if (type.type_parameter != null) {
if (!(current_type_symbol is Class) || !current_class.is_subtype_of (gobject_type)) {
return new CCodeConstant ("NULL");
}
......@@ -1231,7 +1236,9 @@ public class Vala.CCodeGenerator : CodeGenerator {
var cassign = new CCodeAssignment (cvar, ccomma);
// g_free (NULL) is allowed
if ((context.non_null && !type.requires_null_check) || (type.data_type != null && !type.data_type.is_reference_counting () && type.data_type.get_free_function () == "g_free")) {
bool uses_gfree = (type.data_type != null && !type.data_type.is_reference_counting () && type.data_type.get_free_function () == "g_free");
uses_gfree = uses_gfree || type is ArrayType;
if ((context.non_null && !type.requires_null_check) || uses_gfree) {
return new CCodeParenthesizedExpression (cassign);
}
......@@ -1294,7 +1301,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
var st = decl.type_reference.data_type as Struct;
if (decl.type_reference.data_type != null && decl.type_reference.data_type.is_reference_type ()) {
if (decl.type_reference.is_reference_type_or_type_parameter ()) {
vardecl.initializer = new CCodeConstant ("NULL");
} else if (st != null && !st.is_simple_type ()) {
// 0-initialize struct with struct initializer { 0 }
......@@ -1919,7 +1926,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
var local_vars = b.get_local_variables ();
foreach (VariableDeclarator decl in local_vars) {
if (decl.active && decl.type_reference.data_type != null && decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
if (decl.active && decl.type_reference.is_reference_type_or_type_parameter () && 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)));
......@@ -1967,7 +1974,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
var local_vars = b.get_local_variables ();
foreach (VariableDeclarator decl in local_vars) {
if (decl.active && decl.type_reference.data_type != null && decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
if (decl.active && decl.type_reference.is_reference_type_or_type_parameter () && decl.type_reference.takes_ownership) {
found = true;
var ma = new MemberAccess.simple (decl.name);
ma.symbol_reference = decl;
......
......@@ -57,8 +57,8 @@ public class Vala.CCodeGenerator {
var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
if (m is ArrayResizeMethod) {
var array = (Array) m.parent_symbol;
carg_map.set (get_param_pos (0), new CCodeIdentifier (array.get_cname ()));
var array_type = (ArrayType) ma.inner.static_type;
carg_map.set (get_param_pos (0), new CCodeIdentifier (array_type.element_type.get_cname ()));
} else if (m is ArrayMoveMethod) {
requires_array_move = true;
}
......@@ -96,9 +96,9 @@ public class Vala.CCodeGenerator {
}
if (m is ArrayMoveMethod) {
var array = (Array) m.parent_symbol;
var array_type = (ArrayType) ma.inner.static_type;
var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
csizeof.add_argument (new CCodeIdentifier (array.get_cname ()));
csizeof.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
carg_map.set (get_param_pos (0.1), csizeof);
} else if (m is DBusMethod) {
bool found_out = false;
......@@ -458,7 +458,8 @@ public class Vala.CCodeGenerator {
var clen = get_array_length_cexpression (ma.inner, 1);
var celems = (CCodeExpression) ma.inner.ccodenode;
var csizeof = new CCodeIdentifier ("sizeof (%s)".printf (ma.inner.static_type.data_type.get_cname ()));
var array_type = (ArrayType) ma.inner.static_type;
var csizeof = new CCodeIdentifier ("sizeof (%s)".printf (array_type.element_type.get_cname ()));
var cdelta = new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, temp_ref, clen));
var ccheck = new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN, temp_ref, clen);
......
......@@ -727,7 +727,7 @@ public class Vala.CCodeGenerator {
}
private CCodeExpression default_value_for_type (DataType! type) {
if ((type.data_type != null && type.data_type.is_reference_type ()) || type is PointerType) {
if ((type.data_type != null && type.data_type.is_reference_type ()) || type is PointerType || type is ArrayType) {
return new CCodeConstant ("NULL");
} else if (type.data_type != null && type.data_type.get_default_value () != null) {
return new CCodeConstant (type.data_type.get_default_value ());
......
......@@ -16,7 +16,6 @@ noinst_LTLIBRARIES = \
libvalacore_la_VALASOURCES = \
valaaddressofexpression.vala \
valaarray.vala \
valaarraycreationexpression.vala \
valaarraylengthfield.vala \
valaarraymovemethod.vala \
......
/* valaarray.vala
*
* 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
* License as published by the Free Software Foundation; either
* version 2.1 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:
* Raffaele Sandrini <raffaele@sandrini.ch>
* Jürg Billeter <j@bitron.ch>
*/
using GLib;
using Gee;
/**
* Represents an array type i.e. everything with direct accessable elements.
*/
public class Vala.Array : Typesymbol {
/**
* Typesymbol of which this is an array of.
*/
public weak Typesymbol element_type { get; set construct; }
/**
* TypeParameter of which this is an array of.
*/
public weak TypeParameter element_type_parameter { get; set construct; }
/**
* The rank of this array.
*/
public int rank { get; set construct; }
private string cname;
private ArrayLengthField length_field;
private ArrayResizeMethod resize_method;
private ArrayMoveMethod move_method;
public Array (Typesymbol! _element_type, int _rank, SourceReference _source_reference) {
rank = _rank;
element_type = _element_type;
source_reference = _source_reference;
}
public Array.with_type_parameter (TypeParameter! _element_type_parameter, int _rank, SourceReference _source_reference) {
rank = _rank;
element_type_parameter = _element_type_parameter;
source_reference = _source_reference;
}
construct {
assert (rank >= 1);
string commas = string.nfill (rank - 1, ',');
if (element_type != null) {
name = "%s[%s]".printf (element_type.name, commas);
} else {
name = "%s[%s]".printf (element_type_parameter.name, commas);
}
}
public override string get_cname (bool const_type = false) {
if (cname == null) {
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 = "gpointer";
}
}
return cname;
}
public override bool is_reference_type () {
return true;
}
public override string get_upper_case_cname (string infix) {
return null;
}
public override string get_lower_case_cname (string infix) {
return null;
}
public override string get_free_function () {
return "g_free";
}
public override Collection<string> get_cheader_filenames () {
if (element_type != null) {
return element_type.get_cheader_filenames ();
} else {
return base.get_cheader_filenames ();
}
}
public override string get_marshaller_type_name () {
return "POINTER";
}
public override string get_get_value_function () {
return "g_value_get_pointer";
}
public override string get_set_value_function () {
return "g_value_set_pointer";
}
public override string get_type_id () {
if (element_type == source_reference.file.context.root.scope.lookup ("string")) {
return "G_TYPE_STRV";
} else {
return null;
}
}
public ArrayLengthField get_length_field () {
if (length_field == null) {
length_field = new ArrayLengthField (source_reference);
length_field.access = SymbolAccessibility.PUBLIC;
var root_symbol = source_reference.file.context.root;
if (rank > 1) {
// length is an int[] containing the dimensions of the array, starting at 0
ValueType integer = new ValueType((Typesymbol) root_symbol.scope.lookup("int"));
length_field.type_reference = new ArrayType (integer, 1);
length_field.type_reference.add_type_argument (integer);
} else {
length_field.type_reference = new ValueType ((Typesymbol) root_symbol.scope.lookup ("int"));
}
}
return length_field;
}
public ArrayResizeMethod get_resize_method () {
if (resize_method == null) {
resize_method = new ArrayResizeMethod (source_reference);
resize_method.return_type = new VoidType ();
resize_method.access = SymbolAccessibility.PUBLIC;
resize_method.set_cname ("g_renew");
var root_symbol = source_reference.file.context.root;
var int_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("int"));
resize_method.add_parameter (new FormalParameter ("length", int_type));
resize_method.returns_modified_pointer = true;
}
return resize_method;
}
public ArrayMoveMethod get_move_method () {
if (move_method == null) {
move_method = new ArrayMoveMethod (source_reference);
move_method.return_type = new VoidType ();
move_method.access = SymbolAccessibility.PUBLIC;
move_method.set_cname ("_vala_array_move");
var root_symbol = source_reference.file.context.root;
var int_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("int"));
move_method.add_parameter (new FormalParameter ("src", int_type));
move_method.add_parameter (new FormalParameter ("dest", int_type));
move_method.add_parameter (new FormalParameter ("length", int_type));
}
return move_method;
}
}
......@@ -35,21 +35,88 @@ public class Vala.ArrayType : ReferenceType {
* The rank of this array.
*/
public int rank { get; construct set; }
private ArrayLengthField length_field;
private ArrayResizeMethod resize_method;
private ArrayMoveMethod move_method;
public ArrayType (construct DataType! element_type, construct int rank) {
public ArrayType (DataType! element_type, int rank, SourceReference source_reference) {
this.element_type = element_type;
this.rank = rank;
this.source_reference = source_reference;
}
construct {
if (element_type.data_type != null) {
data_type = element_type.data_type.get_array (rank);
} else {
data_type = element_type.type_parameter.get_array (rank);
public override Symbol? get_member (string member_name) {
if (member_name == "length") {
return get_length_field ();
} else if (member_name == "move") {
return get_move_method ();
} else if (member_name == "resize") {
return get_resize_method ();
}
return null;
}
private ArrayLengthField get_length_field () {
if (length_field == null) {
length_field = new ArrayLengthField (source_reference);
length_field.access = SymbolAccessibility.PUBLIC;
var root_symbol = source_reference.file.context.root;
if (rank > 1) {
// length is an int[] containing the dimensions of the array, starting at 0
ValueType integer = new ValueType((Typesymbol) root_symbol.scope.lookup("int"));
length_field.type_reference = new ArrayType (integer, 1, source_reference);
length_field.type_reference.add_type_argument (integer);
} else {
length_field.type_reference = new ValueType ((Typesymbol) root_symbol.scope.lookup ("int"));
}
}
return length_field;
}
private ArrayResizeMethod get_resize_method () {
if (resize_method == null) {
resize_method = new ArrayResizeMethod (source_reference);
resize_method.return_type = new VoidType ();
resize_method.access = SymbolAccessibility.PUBLIC;
resize_method.set_cname ("g_renew");
var root_symbol = source_reference.file.context.root;
var int_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("int"));
resize_method.add_parameter (new FormalParameter ("length", int_type));
resize_method.returns_modified_pointer = true;
}
return resize_method;
}
private ArrayMoveMethod get_move_method () {
if (move_method == null) {
move_method = new ArrayMoveMethod (source_reference);
move_method.return_type = new VoidType ();
move_method.access = SymbolAccessibility.PUBLIC;
move_method.set_cname ("_vala_array_move");
var root_symbol = source_reference.file.context.root;
var int_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("int"));
move_method.add_parameter (new FormalParameter ("src", int_type));
move_method.add_parameter (new FormalParameter ("dest", int_type));
move_method.add_parameter (new FormalParameter ("length", int_type));
}
return move_method;
}
public override DataType! copy () {
var result = new ArrayType (element_type, rank);
result.source_reference = source_reference;
var result = new ArrayType (element_type, rank, source_reference);
result.transfers_ownership = transfers_ownership;
result.takes_ownership = takes_ownership;
result.is_out = is_out;
......@@ -65,7 +132,47 @@ public class Vala.ArrayType : ReferenceType {
return result;
}
public override string get_cname (bool var_type, bool const_type) {
return element_type.get_cname () + "*";
}
public override bool is_array () {
return true;
}
public override string! to_string () {
return element_type.to_string () + "[]";
}
public override bool compatible (DataType! target_type, bool enable_non_null) {
if (target_type is PointerType || (target_type.data_type != null && target_type.data_type.get_attribute ("PointerType") != null)) {
/* any array type can be cast to a generic pointer */
return true;
}
/* temporarily ignore type parameters */
if (target_type.type_parameter != null) {
return true;
}
var target_array_type = target_type as ArrayType;
if (target_array_type == null) {
return false;
}
if (element_type.compatible (target_array_type.element_type)
&& target_array_type.element_type.compatible (element_type)) {
if (requires_null_check && !target_type.nullable) {
// incompatibility between null and non-null types
return !enable_non_null;
}
return true;
}
return false;
}
public override bool is_reference_type_or_type_parameter () {
return true;
}
}
......@@ -339,7 +339,6 @@ public abstract class Vala.DataType : CodeNode {
if (type_parameter != null ||
(data_type != null && (
data_type.is_reference_type () ||
this is ArrayType ||
this is DelegateType ||
data_type.get_attribute ("PointerType") != null))) {
return true;
......@@ -447,6 +446,13 @@ public abstract class Vala.DataType : CodeNode {
return symbols;
}
public virtual Symbol? get_member (string member_name) {
if (data_type != null) {
return SemanticAnalyzer.symbol_lookup_inherited (data_type, member_name);
}
return null;
}
public virtual Symbol get_pointer_member (string member_name) {
return null;
}
......
/* valamember.vala
*
* Copyright (C) 2006-2007 Raffaele Sandrini, Jürg Billeter
* Copyright (C) 2006-2008 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
......@@ -34,7 +34,7 @@ public class Vala.Member : Symbol {
}
public override Collection<string> get_cheader_filenames () {
if (cheader_filenames.size == 0) {
if (cheader_filenames.size == 0 && parent_symbol != null) {
/* default to header filenames of the namespace */
foreach (string filename in parent_symbol.get_cheader_filenames ()) {
add_cheader_filename (filename);
......
......@@ -1180,7 +1180,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
var calc_sizes = new ArrayList<LiteralExpression> ();
if (initlist != null) {
initlist.expected_type = new ArrayType (expr.element_type, expr.rank);
initlist.expected_type = new ArrayType (expr.element_type, expr.rank, expr.source_reference);
initlist.expected_type.add_type_argument (expr.element_type);
initlist.accept (this);
......@@ -1237,7 +1237,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
expr.element_type.takes_ownership = true;
}
expr.static_type = new ArrayType (expr.element_type, expr.rank);
expr.static_type = new ArrayType (expr.element_type, expr.rank, expr.source_reference);
expr.static_type.transfers_ownership = true;
expr.static_type.takes_ownership = true;
......@@ -1456,9 +1456,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
if (expr.symbol_reference == null && expr.inner.static_type != null) {
if (expr.pointer_member_access) {
expr.symbol_reference = expr.inner.static_type.get_pointer_member (expr.member_name);
} else if (expr.inner.static_type.data_type != null) {
base_symbol = expr.inner.static_type.data_type;
expr.symbol_reference = symbol_lookup_inherited (base_symbol, expr.member_name);
} else {
if (expr.inner.static_type.data_type != null) {
base_symbol = expr.inner.static_type.data_type;
}
expr.symbol_reference = expr.inner.static_type.get_member (expr.member_name);
}
if (expr.symbol_reference != null) {
// inner expression is variable, field, or parameter
......
......@@ -300,10 +300,9 @@ public class Vala.SymbolResolver : CodeVisitor {
element_type.is_ref = false;
element_type.is_out = false;
type = new ArrayType (element_type, unresolved_type.array_rank);
type = new ArrayType (element_type, unresolved_type.array_rank, unresolved_type.source_reference);
type.add_type_argument (element_type);
type.source_reference = unresolved_type.source_reference;
type.takes_ownership = unresolved_type.takes_ownership;
type.transfers_ownership = unresolved_type.transfers_ownership;
type.is_ref = unresolved_type.is_ref;
......
/* valatypeparameter.vala
*
* Copyright (C) 2006-2007 Jürg Billeter
* Copyright (C) 2006-2008 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
......@@ -50,45 +50,6 @@ public class Vala.TypeParameter : Symbol {
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 = null;
if (array_types != null) {
array_type = array_types[rank];
}
if (array_type == null) {
if (array_types == null) {
array_types = new HashMap<int,Array> ();
}
var new_array_type = new Array.with_type_parameter (this, rank, source_reference);
parent_symbol.scope.add (new_array_type.name, new_array_type);
/* add internal length field */
new_array_type.scope.add (new_array_type.get_length_field ().name, new_array_type.get_length_field ());
/* add internal resize method */
new_array_type.scope.add (new_array_type.get_resize_method ().name, new_array_type.get_resize_method ());
/* add internal move method */
new_array_type.scope.add (new_array_type.get_move_method ().name, new_array_type.get_move_method ());
/* link the array type to the same source as the container type */
new_array_type.source_reference = this.source_reference;
array_types[rank] = new_array_type;
array_type = new_array_type;
}
return array_type;
}
/**
* Checks two type parameters for equality.
......
......@@ -194,45 +194,6 @@ public abstract class Vala.Typesymbol : Symbol {
cheader_filenames.add (filename);
}
/**
* Returns the array type for elements of this data type.
*
* @param rank the rank the array should be of
* @return array type for this data type
*/
public Array! get_array (int rank) {
Array array_type = null;
if (array_types != null) {
array_type = array_types[rank];
}
if (array_type == null) {
if (array_types == null) {
array_types = new HashMap<int,Array> ();
}
var new_array_type = new Array (this, rank, source_reference);
parent_symbol.scope.add (new_array_type.name, new_array_type);
/* add internal length field */
new_array_type.scope.add (new_array_type.get_length_field ().name, new_array_type.get_length_field ());
/* add internal resize method */
new_array_type.scope.add (new_array_type.get_resize_method ().name, new_array_type.get_resize_method ());
/* add internal move method */
new_array_type.scope.add (new_array_type.get_move_method ().name, new_array_type.get_move_method ());
/* link the array type to the same source as the container type */
new_array_type.source_reference = this.source_reference;
array_types[rank] = new_array_type;
array_type = new_array_type;
}
return array_type;
}
/**
* Checks whether this data type is equal to or a subtype of the
* specified data type.
......
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