+2007-03-03 Raffaele Sandrini <rasa@gmx.ch>
+
+ * vala/valaattributeprocessor.vala, vala/valamethod.vala,
+ vala/valacodegenerator.vala, vala/valacreationmethod.vala,
+ vala/valasymbolbuilder.vala, vala/valasemanticanalyzer.vala,
+ vala/parser.y, vala/valacodevisitor.vala,
+ vala/valainterfacewriter.vala, vala/valamemorymanager.vala:
+ add CreationMethod type; restrict creation methods bodys to contain
+ only property assignment statements
+ * vala/valacharacterliteral.vala, vala/valacodegenerator.vala,
+ vala/valaarray.vala: fix the compiler to obey the new creation
+ method rules
+ * vala/Makefile.am: update
+
2007-03-03 Jürg Billeter <j@bitron.ch>
* vapi/atk.vala, vapi/cairo.vala, vapi/gdk-2.0.vala, vapi/gtk+-2.0.vala,
valacontinuestatement.c \
valacontinuestatement.h \
valacontinuestatement.vala \
+ valacreationmethod.c \
+ valacreationmethod.h \
+ valacreationmethod.vala \
valadatatype.c \
valadatatype.h \
valadatatype.vala \
valaconstant.h \
valaconstructor.h \
valacontinuestatement.h \
+ valacreationmethod.h \
valadatatype.h \
valadeclarationstatement.h \
valadestructor.h \
GList *l;
ValaSourceReference *src = src_com(@5, $1);
- $$ = vala_method_new ($6, NULL, src);
+ $$ = VALA_METHOD (vala_creation_method_new ($6, src));
g_free ($5);
g_free ($6);
g_object_unref (src);
- vala_method_set_construction ($$, TRUE);
vala_method_set_instance ($$, FALSE);
if ($3 != 0) {
$$->access = $3;
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 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;
-
- if (_rank < 1) {
- Report.error (null, "internal: attempt to create an array with rank smaller than 1");
- }
}
construct {
name = "%s[%s]".printf (element_type.name, commas); */
+ if (rank < 1) {
+ Report.error (null, "internal: attempt to create an array with rank smaller than 1");
+ }
+
int i = rank - 1;
if (element_type != null) {
name = "%s[".printf (element_type.name);
public override void visit_begin_method (Method! m) {
m.process_attributes ();
}
+
+ public override void visit_begin_creation_method (CreationMethod! m) {
+ m.process_attributes ();
+ }
public override void visit_begin_property (Property! prop) {
prop.process_attributes ();
value = c;
source_reference = source;
+ }
+
+ construct {
if (error) {
Report.error (source_reference, "invalid character literal");
}
public CodeGenerator (bool manage_memory = true) {
memory_management = manage_memory;
-
+ }
+
+ construct {
predefined_marshal_list = new HashTable (str_hash, str_equal);
predefined_marshal_list.insert ("VOID:VOID", true);
predefined_marshal_list.insert ("VOID:BOOLEAN", true);
}
source_type_member_definition.append (function);
- if (m.construction && current_class != null) {
+ if (m is CreationMethod && current_class != null) {
// declare construction parameter array
var cparamsinit = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
cparamsinit.add_argument (new CCodeIdentifier ("GParameter"));
- cparamsinit.add_argument (new CCodeConstant (m.n_construction_params.to_string ()));
+ cparamsinit.add_argument (new CCodeConstant (((CreationMethod)m).n_construction_params.to_string ()));
var cdecl = new CCodeDeclaration ("GParameter *");
cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params", cparamsinit));
source_type_member_definition.append (vfunc);
}
- if (m.construction) {
+ if (m is CreationMethod) {
var creturn = new CCodeReturnStatement ();
creturn.return_expression = new CCodeIdentifier ("self");
function.block.add_statement (creturn);
}
}
+ public override void visit_begin_creation_method (CreationMethod! m) {
+ current_symbol = m.symbol;
+ current_return_type = m.return_type;
+ }
+
+ public override void visit_end_creation_method (CreationMethod! m) {
+ visit_end_method (m);
+ }
+
private bool is_possible_entry_point (Method! m, ref bool return_value, ref bool args_parameter) {
if (m.name == null || m.name != "main") {
// method must be called "main"
*/
public virtual void visit_end_method (Method! m) {
}
+
+ /**
+ * Visit operation called at beginning of creation methods.
+ *
+ * @param m a method
+ */
+ public virtual void visit_begin_creation_method (CreationMethod! m) {
+ }
+
+ /**
+ * Visit operation called at end of creation methods.
+ *
+ * @param m a method
+ */
+ public virtual void visit_end_creation_method (CreationMethod! m) {
+ }
/**
* Visit operation called for formal parameters.
--- /dev/null
+/* valacreationmethod.vala
+ *
+ * Copyright (C) 2007 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 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 <j@bitron.ch>
+ */
+
+using GLib;
+
+/**
+ * Represents a type creation method.
+ */
+public class Vala.CreationMethod : Method {
+ /**
+ * Specifies the number of parameters this creation method sets.
+ */
+ public int n_construction_params { get; set; }
+
+ private string cname;
+
+ /**
+ * Creates a new method.
+ *
+ * @param name method name
+ * @param source reference to source code
+ * @return newly created method
+ */
+ public CreationMethod (string _name, SourceReference source = null) {
+ name = _name;
+ source_reference = source;
+ }
+
+ public override void accept (CodeVisitor! visitor) {
+ visitor.visit_begin_creation_method (this);
+
+ foreach (FormalParameter param in get_parameters()) {
+ param.accept (visitor);
+ }
+
+ if (body != null) {
+ body.accept (visitor);
+ }
+
+ visitor.visit_end_creation_method (this);
+ }
+
+ /**
+ * Returns the interface name of this method as it is used in C code.
+ *
+ * @return the name to be used in C code
+ */
+ public override string! get_cname () {
+ if (cname == null) {
+ var parent = symbol.parent_symbol.node;
+ if (parent is DataType) {
+ if (name == null) {
+ cname = "%snew".printf (((DataType) parent).get_lower_case_cprefix ());
+ } else {
+ cname = "%snew_%s".printf (((DataType) parent).get_lower_case_cprefix (), name);
+ }
+ }
+ }
+ return cname;
+ }
+}
write_indent ();
write_string ("public");
- if (m.construction) {
+ if (m is CreationMethod) {
write_string (" ");
var datatype = (DataType) m.symbol.parent_symbol.node;
write_identifier (datatype.name);
write_string (" virtual");
}
- if (!m.construction) {
+ if (!(m is CreationMethod)) {
write_string (" ");
var type = m.return_type.data_type;
write_newline ();
}
+
+ public override void visit_begin_creation_method (CreationMethod! m) {
+ visit_begin_method (m);
+ }
public override void visit_begin_property (Property! prop) {
if (internal_scope) {
current_symbol = m.symbol;
}
+ public override void visit_begin_creation_method (CreationMethod! m) {
+ current_symbol = m.symbol;
+ }
+
public override void visit_begin_property (Property! prop) {
current_symbol = prop.symbol;
}
* of a base type.
*/
public bool overrides { get; set; }
-
- /**
- * Specifies whether this is a construction method.
- */
- public bool construction { get; set; }
-
- /**
- * Specifies the number of parameters this construction method sets.
- */
- public int n_construction_params { get; set; }
/**
* Specifies whether the C method returns a new instance pointer which
*
* @return the name to be used in C code
*/
- public string! get_cname () {
+ public virtual string! get_cname () {
if (cname == null) {
var parent = symbol.parent_symbol.node;
if (parent is DataType) {
- if (construction) {
- if (name == null) {
- cname = "%snew".printf (((DataType) parent).get_lower_case_cprefix ());
- } else {
- cname = "%snew_%s".printf (((DataType) parent).get_lower_case_cprefix (), name);
- }
- } else {
- cname = "%s%s".printf (((DataType) parent).get_lower_case_cprefix (), name);
- }
+ cname = "%s%s".printf (((DataType) parent).get_lower_case_cprefix (), name);
} else if (parent is Namespace) {
cname = "%s%s".printf (((Namespace) parent).get_lower_case_cprefix (), name);
} else {
}
}
- public override void visit_begin_method (Method! m) {
- if (m.construction) {
- m.return_type = new TypeReference ();
- m.return_type.data_type = (DataType) current_symbol.node;
- m.return_type.transfers_ownership = true;
-
- if (current_symbol.node is Class) {
- // check for floating reference
- var cl = (Class) current_symbol.node;
- while (cl != null) {
- if (cl == initially_unowned_type) {
- m.return_type.floating_reference = true;
- break;
- }
-
- cl = cl.base_class;
- }
- }
-
- if (m.body != null) {
- m.body.construction = true;
- }
- }
-
+ public override void visit_begin_method (Method! m) {
current_symbol = m.symbol;
current_return_type = m.return_type;
return;
}
}
+ }
+
+ public override void visit_begin_creation_method (CreationMethod! m) {
+ m.return_type = new TypeReference ();
+ m.return_type.data_type = (DataType) current_symbol.node;
+ m.return_type.transfers_ownership = true;
+
+ if (current_symbol.node is Class) {
+ // check for floating reference
+ var cl = (Class) current_symbol.node;
+ while (cl != null) {
+ if (cl == initially_unowned_type) {
+ m.return_type.floating_reference = true;
+ break;
+ }
+
+ cl = cl.base_class;
+ }
+ }
+
+ if (m.body != null) {
+ m.body.construction = true;
+ }
- if (m.construction && m.body != null) {
+ current_symbol = m.symbol;
+ current_return_type = m.return_type;
+ }
+
+ public override void visit_end_creation_method (CreationMethod! m) {
+ visit_end_method (m);
+
+ if (m.body != null) {
int n_params = 0;
foreach (Statement stmt in m.body.get_statements ()) {
int params = stmt.get_number_of_set_construction_parameters ();
if (params == -1) {
- break;
+ m.error = true;
+ Report.error (stmt.source_reference, "type creation methods only allow property assignment statements");
+ return;
}
n_params += params;
stmt.construction = true;
type_node = constructor_node.symbol.parent_symbol.node;
var constructor = (Method) constructor_node;
- if (!constructor.construction) {
+ if (!(constructor_node is CreationMethod)) {
expr.error = true;
Report.error (expr.source_reference, "`%s' is not a construction method".printf (constructor.symbol.get_full_name ()));
return;
return;
}
- if (m.construction) {
- var type_node = m.symbol.parent_symbol.node;
- if (!(type_node is Class || type_node is Struct)) {
- Report.error (m.source_reference, "construction methods may only be declared within classes and structs");
-
- m.error = true;
- return;
- }
-
- if (m.name == null) {
- if (type_node is Class) {
- ((Class) type_node).default_construction_method = m;
- } else if (type_node is Struct) {
- ((Struct) type_node).default_construction_method = m;
- }
- }
- } else if (m.instance) {
+ if (m.instance) {
if (!(m.symbol.parent_symbol.node is DataType)) {
Report.error (m.source_reference, "instance methods not allowed outside of data types");
current_symbol = current_symbol.parent_symbol;
}
+
+ public override void visit_begin_creation_method (CreationMethod! m) {
+ if (add_symbol (m.name, m) == null) {
+ return;
+ }
+
+ var type_node = m.symbol.parent_symbol.node;
+ if (!(type_node is Class || type_node is Struct)) {
+ Report.error (m.source_reference, "construction methods may only be declared within classes and structs");
+
+ m.error = true;
+ return;
+ }
+
+ if (m.name == null) {
+ if (type_node is Class) {
+ ((Class) type_node).default_construction_method = m;
+ } else if (type_node is Struct) {
+ ((Struct) type_node).default_construction_method = m;
+ }
+ }
+
+ current_symbol = m.symbol;
+ }
+
+ public override void visit_end_creation_method (CreationMethod! m) {
+ if (m.error) {
+ /* skip methods with errors */
+ return;
+ }
+
+ current_symbol = current_symbol.parent_symbol;
+ }
public override void visit_formal_parameter (FormalParameter! p) {
if (!p.ellipsis) {