summaryrefslogtreecommitdiff
path: root/vala/valastruct.vala
diff options
context:
space:
mode:
Diffstat (limited to 'vala/valastruct.vala')
-rw-r--r--vala/valastruct.vala436
1 files changed, 436 insertions, 0 deletions
diff --git a/vala/valastruct.vala b/vala/valastruct.vala
new file mode 100644
index 000000000..3e57c6b93
--- /dev/null
+++ b/vala/valastruct.vala
@@ -0,0 +1,436 @@
+/* valastruct.vala
+ *
+ * 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
+ * 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 <j@bitron.ch>
+ */
+
+using GLib;
+
+/**
+ * Represents a struct declaration in the source code.
+ */
+public class Vala.Struct : DataType {
+ private List<TypeParameter> type_parameters;
+ private List<Constant> constants;
+ private List<Field> fields;
+ private List<Method> methods;
+
+ private List<TypeReference> base_types;
+
+ private string cname;
+ private string const_cname;
+ private string dup_function;
+ private string free_function;
+ private string type_id;
+ private string lower_case_cprefix;
+ private string lower_case_csuffix;
+ private bool reference_type;
+ private bool integer_type;
+ private bool floating_type;
+ private int rank;
+ private string marshaller_type_name;
+ private string get_value_function;
+ private string set_value_function;
+ private string default_value = null;
+
+ /**
+ * Specifies the default construction method.
+ */
+ public Method default_construction_method { get; set; }
+
+ /**
+ * Creates a new struct.
+ *
+ * @param name type name
+ * @param source reference to source code
+ * @return newly created struct
+ */
+ public Struct (string! _name, SourceReference source = null) {
+ name = _name;
+ source_reference = source;
+ }
+
+ /**
+ * Appends the specified parameter to the list of type parameters.
+ *
+ * @param p a type parameter
+ */
+ public void add_type_parameter (TypeParameter! p) {
+ type_parameters.append (p);
+ p.type = this;
+ }
+
+ /**
+ * Adds the specified constant as a member to this struct.
+ *
+ * @param c a constant
+ */
+ public void add_constant (Constant! c) {
+ constants.append (c);
+ }
+
+ /**
+ * Adds the specified field as a member to this struct.
+ *
+ * @param f a field
+ */
+ public void add_field (Field! f) {
+ fields.append (f);
+ }
+
+ /**
+ * Returns a copy of the list of fields.
+ *
+ * @return list of fields
+ */
+ public ref List<weak Field> get_fields () {
+ return fields.copy ();
+ }
+
+ /**
+ * Adds the specified method as a member to this struct.
+ *
+ * @param m a method
+ */
+ public void add_method (Method! m) {
+ return_if_fail (m != null);
+
+ methods.append (m);
+ }
+
+ /**
+ * Returns a copy of the list of methods.
+ *
+ * @return list of methods
+ */
+ public ref List<weak Method> get_methods () {
+ return methods.copy ();
+ }
+
+ public override void accept (CodeVisitor! visitor) {
+ visitor.visit_begin_struct (this);
+
+ foreach (TypeParameter p in type_parameters) {
+ p.accept (visitor);
+ }
+
+ foreach (Field f in fields) {
+ f.accept (visitor);
+ }
+
+ foreach (Constant c in constants) {
+ c.accept (visitor);
+ }
+
+ foreach (Method m in methods) {
+ m.accept (visitor);
+ }
+
+ visitor.visit_end_struct (this);
+ }
+
+ public override string get_cname (bool const_type = false) {
+ if (const_type && const_cname != null) {
+ return const_cname;
+ }
+
+ if (cname == null) {
+ cname = "%s%s".printf (@namespace.get_cprefix (), name);
+ }
+ return cname;
+ }
+
+ private void set_cname (string! cname) {
+ this.cname = cname;
+ }
+
+ private void set_const_cname (string! cname) {
+ this.const_cname = cname;
+ }
+
+ public override ref string get_lower_case_cprefix () {
+ if (lower_case_cprefix == null) {
+ lower_case_cprefix = "%s_".printf (get_lower_case_cname (null));
+ }
+ return lower_case_cprefix;
+ }
+
+ private string get_lower_case_csuffix () {
+ if (lower_case_csuffix == null) {
+ lower_case_csuffix = Namespace.camel_case_to_lower_case (name);
+ }
+ return lower_case_csuffix;
+ }
+
+ private void set_lower_case_csuffix (string! csuffix) {
+ this.lower_case_csuffix = csuffix;
+ }
+
+ public override ref string get_lower_case_cname (string infix) {
+ if (infix == null) {
+ infix = "";
+ }
+ return "%s%s%s".printf (@namespace.get_lower_case_cprefix (), infix, get_lower_case_csuffix ());
+ }
+
+ public override ref string get_upper_case_cname (string infix) {
+ return get_lower_case_cname (infix).up ();
+ }
+
+ public override bool is_reference_type () {
+ return reference_type;
+ }
+
+ /**
+ * Returns whether this is an integer type.
+ *
+ * @return true if this is an integer type, false otherwise
+ */
+ public bool is_integer_type () {
+ return integer_type;
+ }
+
+ /**
+ * Returns whether this is a floating point type.
+ *
+ * @return true if this is a floating point type, false otherwise
+ */
+ public bool is_floating_type () {
+ return floating_type;
+ }
+
+ /**
+ * Returns the rank of this integer or floating point type.
+ *
+ * @return the rank if this is an integer or floating point type
+ */
+ public int get_rank () {
+ return rank;
+ }
+
+ /**
+ * Sets whether this data type has value or reference type semantics.
+ *
+ * @param ref_type true if this data type has reference type semantics
+ */
+ public void set_is_reference_type (bool ref_type) {
+ reference_type = ref_type;
+ }
+
+ private void process_ccode_attribute (Attribute! a) {
+ if (a.has_argument ("cname")) {
+ set_cname (a.get_string ("cname"));
+ }
+ if (a.has_argument ("const_cname")) {
+ set_const_cname (a.get_string ("const_cname"));
+ }
+ if (a.has_argument ("cprefix")) {
+ lower_case_cprefix = a.get_string ("cprefix");
+ }
+ if (a.has_argument ("cheader_filename")) {
+ var val = a.get_string ("cheader_filename");
+ foreach (string filename in val.split (",")) {
+ add_cheader_filename (filename);
+ }
+ }
+ if (a.has_argument ("type_id")) {
+ set_type_id (a.get_string ("type_id"));
+ }
+ if (a.has_argument ("marshaller_type_name")) {
+ set_marshaller_type_name (a.get_string ("marshaller_type_name"));
+ }
+ if (a.has_argument ("get_value_function")) {
+ set_get_value_function (a.get_string ("get_value_function"));
+ }
+ if (a.has_argument ("set_value_function")) {
+ set_set_value_function (a.get_string ("set_value_function"));
+ }
+ if (a.has_argument ("default_value")) {
+ set_default_value (a.get_string ("default_value"));
+ }
+ }
+
+ private void process_ref_type_attribute (Attribute! a) {
+ reference_type = true;
+ if (a.has_argument ("dup_function")) {
+ set_dup_function (a.get_string ("dup_function"));
+ }
+ if (a.has_argument ("free_function")) {
+ set_free_function (a.get_string ("free_function"));
+ }
+ }
+
+ private void process_integer_type_attribute (Attribute! a) {
+ integer_type = true;
+ if (a.has_argument ("rank")) {
+ rank = a.get_integer ("rank");
+ }
+ }
+
+ private void process_floating_type_attribute (Attribute! a) {
+ floating_type = true;
+ if (a.has_argument ("rank")) {
+ rank = a.get_integer ("rank");
+ }
+ }
+
+ /**
+ * Process all associated attributes.
+ */
+ public void process_attributes () {
+ foreach (Attribute a in attributes) {
+ if (a.name == "CCode") {
+ process_ccode_attribute (a);
+ } else if (a.name == "ReferenceType") {
+ process_ref_type_attribute (a);
+ } else if (a.name == "IntegerType") {
+ process_integer_type_attribute (a);
+ } else if (a.name == "FloatingType") {
+ process_floating_type_attribute (a);
+ }
+ }
+ }
+
+ public override bool is_reference_counting () {
+ return false;
+ }
+
+ public override string get_dup_function () {
+ if (dup_function == null) {
+ Report.error (source_reference, "The type `%s` doesn't contain a copy function".printf (symbol.get_full_name ()));
+ }
+ return dup_function;
+ }
+
+ public void set_dup_function (string! name) {
+ this.dup_function = name;
+ }
+
+ public override string get_free_function () {
+ if (free_function == null) {
+ Report.error (source_reference, "The type `%s` doesn't contain a free function".printf (symbol.get_full_name ()));
+ }
+ return free_function;
+ }
+
+ private void set_free_function (string! name) {
+ this.free_function = name;
+ }
+
+ public override string get_type_id () {
+ if (type_id == null) {
+ if (is_reference_type ()) {
+ type_id = "G_TYPE_POINTER";
+ } else {
+ Report.error (source_reference, "The type `%s` doesn't declare a type id".printf (symbol.get_full_name ()));
+ }
+ }
+ return type_id;
+ }
+
+ public void set_type_id (string! name) {
+ this.type_id = name;
+ }
+
+ public override string get_marshaller_type_name () {
+ if (marshaller_type_name == null) {
+ if (is_reference_type ()) {
+ marshaller_type_name = "POINTER";
+ } else {
+ Report.error (source_reference, "The type `%s` doesn't declare a marshaller type name".printf (symbol.get_full_name ()));
+ }
+ }
+ return marshaller_type_name;
+ }
+
+ private void set_marshaller_type_name (string! name) {
+ this.marshaller_type_name = name;
+ }
+
+ public override string get_get_value_function () {
+ if (get_value_function == null) {
+ if (is_reference_type ()) {
+ return "g_value_get_pointer";
+ } else {
+ Report.error (source_reference, "The value type `%s` doesn't declare a GValue get function".printf (symbol.get_full_name ()));
+ }
+ } else {
+ return get_value_function;
+ }
+ }
+
+ public override string get_set_value_function () {
+ if (set_value_function == null) {
+ if (is_reference_type ()) {
+ return "g_value_set_pointer";
+ } else {
+ Report.error (source_reference, "The value type `%s` doesn't declare a GValue set function".printf (symbol.get_full_name ()));
+ }
+ } else {
+ return set_value_function;
+ }
+ }
+
+ private void set_get_value_function (string! function) {
+ get_value_function = function;
+ }
+
+ private void set_set_value_function (string! function) {
+ set_value_function = function;
+ }
+
+ public override string get_default_value () {
+ return default_value;
+ }
+
+ private void set_default_value (string! value) {
+ default_value = value;
+ }
+
+ /**
+ * Adds the specified struct to the list of base types of this struct.
+ *
+ * @param type a class or interface reference
+ */
+ public void add_base_type (TypeReference! type) {
+ base_types.append (type);
+ }
+
+ /**
+ * Returns a copy of the base type list.
+ *
+ * @return list of base types
+ */
+ public ref List<weak TypeReference> get_base_types () {
+ return base_types.copy ();
+ }
+
+ public override int get_type_parameter_index (string! name) {
+ int i = 0;
+
+ foreach (TypeParameter p in type_parameters) {
+ if (p.name == name) {
+ return (i);
+ }
+ i++;
+ }
+
+ return -1;
+ }
+}