summaryrefslogtreecommitdiff
path: root/vala/valaparameter.vala
diff options
context:
space:
mode:
authorJürg Billeter <j@bitron.ch>2010-10-28 13:07:01 +0200
committerJürg Billeter <j@bitron.ch>2010-10-28 16:20:17 +0200
commite81776c024ab1e72b918612e49606f8500aaad06 (patch)
treee80e6e65ccc417359a8cf8531495d5157a68d232 /vala/valaparameter.vala
parent5f3ed0f460a06120900b082c49f9da8bcc1a0a84 (diff)
downloadvala-e81776c024ab1e72b918612e49606f8500aaad06.tar.gz
Rename FormalParameter to Parameter
Diffstat (limited to 'vala/valaparameter.vala')
-rw-r--r--vala/valaparameter.vala288
1 files changed, 288 insertions, 0 deletions
diff --git a/vala/valaparameter.vala b/vala/valaparameter.vala
new file mode 100644
index 000000000..9d17377f6
--- /dev/null
+++ b/vala/valaparameter.vala
@@ -0,0 +1,288 @@
+/* valaparameter.vala
+ *
+ * Copyright (C) 2006-2010 Jürg Billeter
+ * Copyright (C) 2006-2008 Raffaele Sandrini
+ *
+ * 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:
+ * Jürg Billeter <j@bitron.ch>
+ * Raffaele Sandrini <raffaele@sandrini.ch>
+ */
+
+using GLib;
+
+/**
+ * Represents a formal parameter in method and callback signatures.
+ */
+public class Vala.Parameter : Variable {
+ public ParameterDirection direction { get; set; default = ParameterDirection.IN; }
+
+ /**
+ * Specifies whether the methods accepts an indefinite number of
+ * parameters.
+ */
+ public bool ellipsis { get; set; }
+
+ /**
+ * Specifies whether the methods accepts an indefinite number of
+ * parameters.
+ */
+ public bool params_array { get; set; }
+
+ /**
+ * Specifies whether the array length should be passed implicitly
+ * if the parameter type is an array.
+ */
+ public bool no_array_length { get; set; }
+
+ /**
+ * Specifies whether the array is null terminated.
+ */
+ public bool array_null_terminated { get; set; }
+
+ /**
+ * Specifies whether the array length parameter uses a custom name in C.
+ */
+ public bool has_array_length_cname {
+ get { return (array_length_cname != null); }
+ }
+
+ /**
+ * Specifies a custom type for the array length.
+ */
+ public string? array_length_type { get; set; default = null; }
+
+ /**
+ * Specifies the position of the parameter in the C function.
+ */
+ public double cparameter_position { get; set; }
+
+ /**
+ * Specifies the position of the array length parameter in the C
+ * function.
+ */
+ public double carray_length_parameter_position { get; set; }
+
+ /**
+ * Specifies the position of the delegate target parameter in the C
+ * function.
+ */
+ public double cdelegate_target_parameter_position { get; set; }
+
+ public double cdestroy_notify_parameter_position { get; set; }
+
+ /**
+ * Specifies the type of the parameter in the C function.
+ */
+ public string? ctype { get; set; }
+
+ public bool captured { get; set; }
+
+ private string? array_length_cname;
+
+ /**
+ * Creates a new formal parameter.
+ *
+ * @param name parameter name
+ * @param type parameter type
+ * @param source reference to source code
+ * @return newly created formal parameter
+ */
+ public Parameter (string name, DataType variable_type, SourceReference? source_reference = null) {
+ base (variable_type, name, null, source_reference);
+
+ access = SymbolAccessibility.PUBLIC;
+ }
+
+ /**
+ * Creates a new ellipsis parameter representing an indefinite number of
+ * parameters.
+ */
+ public Parameter.with_ellipsis (SourceReference? source_reference = null) {
+ base (null, null, null, source_reference);
+ ellipsis = true;
+
+ access = SymbolAccessibility.PUBLIC;
+ }
+
+ public override void accept (CodeVisitor visitor) {
+ visitor.visit_formal_parameter (this);
+ }
+
+ public override void accept_children (CodeVisitor visitor) {
+ if (!ellipsis) {
+ variable_type.accept (visitor);
+
+ if (initializer != null) {
+ initializer.accept (visitor);
+ }
+ }
+ }
+
+ public override void replace_type (DataType old_type, DataType new_type) {
+ if (variable_type == old_type) {
+ variable_type = new_type;
+ }
+ }
+
+ public override void replace_expression (Expression old_node, Expression new_node) {
+ if (initializer == old_node) {
+ initializer = new_node;
+ }
+ }
+
+ /**
+ * Returns the name of the array length parameter as it is used in C code
+ *
+ * @return the name of the array length parameter to be used in C code
+ */
+ public string? get_array_length_cname () {
+ return this.array_length_cname;
+ }
+
+ /**
+ * Sets the name of the array length parameter as it is used in C code
+ *
+ * @param array_length_cname the name of the array length parameter to be
+ * used in C code
+ */
+ public void set_array_length_cname (string? array_length_cname) {
+ this.array_length_cname = array_length_cname;
+ }
+
+ private void process_ccode_attribute (Attribute a) {
+ if (a.has_argument ("type")) {
+ ctype = a.get_string ("type");
+ }
+ if (a.has_argument ("pos")) {
+ cparameter_position = a.get_double ("pos");
+ }
+ if (a.has_argument ("array_length")) {
+ no_array_length = !a.get_bool ("array_length");
+ }
+ if (a.has_argument ("array_length_type")) {
+ array_length_type = a.get_string ("array_length_type");
+ }
+ if (a.has_argument ("array_null_terminated")) {
+ array_null_terminated = a.get_bool ("array_null_terminated");
+ }
+ if (a.has_argument ("array_length_pos")) {
+ carray_length_parameter_position = a.get_double ("array_length_pos");
+ }
+ if (a.has_argument ("array_length_cname")) {
+ set_array_length_cname (a.get_string ("array_length_cname"));
+ }
+ if (a.has_argument ("delegate_target_pos")) {
+ cdelegate_target_parameter_position = a.get_double ("delegate_target_pos");
+ }
+ if (a.has_argument ("destroy_notify_pos")) {
+ cdestroy_notify_parameter_position = a.get_double ("destroy_notify_pos");
+ }
+ }
+
+ /**
+ * Process all associated attributes.
+ */
+ public void process_attributes () {
+ foreach (Attribute a in attributes) {
+ if (a.name == "CCode") {
+ process_ccode_attribute (a);
+ }
+ }
+ }
+
+ public Parameter copy () {
+ if (!ellipsis) {
+ var result = new Parameter (name, variable_type, source_reference);
+ result.params_array = params_array;
+ result.direction = this.direction;
+ result.initializer = this.initializer;
+ return result;
+ } else {
+ return new Parameter.with_ellipsis ();
+ }
+ }
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ process_attributes ();
+
+ var old_source_file = analyzer.current_source_file;
+ var old_symbol = analyzer.current_symbol;
+
+ if (source_reference != null) {
+ analyzer.current_source_file = source_reference.file;
+ }
+ analyzer.current_symbol = parent_symbol;
+
+ if (variable_type != null) {
+ if (variable_type is VoidType) {
+ error = true;
+ Report.error (source_reference, "'void' not supported as parameter type");
+ return false;
+ }
+ variable_type.check (analyzer);
+ }
+
+ if (!ellipsis) {
+ variable_type.check (analyzer);
+
+ if (params_array && !(variable_type is ArrayType)) {
+ error = true;
+ Report.error (source_reference, "parameter array expected");
+ return false;
+ }
+
+ if (initializer != null) {
+ initializer.target_type = variable_type.copy ();
+ initializer.check (analyzer);
+ }
+ }
+
+ if (initializer != null) {
+ if (initializer is NullLiteral
+ && !variable_type.nullable
+ && direction != ParameterDirection.OUT) {
+ Report.warning (source_reference, "`null' incompatible with parameter type `%s`".printf (variable_type.to_string ()));
+ }
+ }
+
+ if (!ellipsis) {
+ // check whether parameter type is at least as accessible as the method
+ if (!analyzer.is_type_accessible (this, variable_type)) {
+ error = true;
+ Report.error (source_reference, "parameter type `%s` is less accessible than method `%s`".printf (variable_type.to_string (), parent_symbol.get_full_name ()));
+ }
+ }
+
+ analyzer.current_source_file = old_source_file;
+ analyzer.current_symbol = old_symbol;
+
+ return !error;
+ }
+}
+
+public enum Vala.ParameterDirection {
+ IN,
+ OUT,
+ REF
+}
+